Probleme mit Pulsein

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • Ich glaube es ist Arduino-Hardware.

      Aber so sollte es funktionieren:

      Source Code

      1. $Regfile = "m328pdef.dat"
      2. $Crystal = 16000000
      3. Config SubMode = New
      4. ' ----------------------------------------------
      5. ' Dauer Low-Puls messen, Auflösung 5µs
      6. ' Rückgabe in 5µs Schritten
      7. ' Beispiel: Rückgabe 4 bedeutet Dauer war 4 x 5µs
      8. ' ----------------------------------------------
      9. Function myPulseIn() as Word
      10. Local tmpTimeout as Word
      11. Local tmpDauer as Word : tmpDauer = 0
      12. tmpDauer = 0 ' Pulsdauer auf 0
      13. tmpTimeout = 80 ' Timeout 400µs = 80x5µs
      14. BitWait PinB.1 , Set ' Warten auf High
      15. ' Schleifendurchlauf 5µs
      16. While PinB.1 = 0 ' Messen Low-Puls
      17. Incr tmpDauer
      18. Decr tmpTimeout
      19. If tmpTimeout = 0 then
      20. Exit While
      21. End If
      22. NOP
      23. NOP
      24. NOP
      25. NOP
      26. NOP
      27. NOP
      28. NOP
      29. NOP
      30. NOP
      31. NOP
      32. NOP
      33. NOP
      34. NOP
      35. NOP
      36. NOP
      37. NOP
      38. NOP
      39. NOP
      40. Wend
      41. myPulseIn = tmpDauer
      42. End Function
      43. Dim Value as Word
      44. Do
      45. Value = myPulseIn()
      46. Loop
      Display All
    • six1 wrote:

      Timer Overflow
      Der bringt aber nicht die gewünschte Zeit, ein Preload wäre ungenau und das Timeout müsste immer noch "zu Fuß " gebaut werden. (Nur Timer2 ist noch verfügbar)
      Der normale Aufruf "verbraucht" schon fast die gesammten 10µS. Aber das ist kein Problem wenn er beim Pulsmessen nichts anderes zu tun braucht (keine anderen Ints z.B.Zeitgeber/Usart)
      Wobei die auch das normale Pulsein verfälschen würden. So gesehen die präziesere Lösung.

      The post was edited 1 time, last by Pluto25 ().

    • Ok, zugegeben, man braucht einen Timer mit Interrupt Eingang.
      Aber deine weiteren Ausführungen verstehe ich nicht.
      Wenn man den Timer Overflow auf eine DWord Variable aufaddiert und im Int Fall den Timer plus Overflow Variable zur Berechnung hernimmt, bekommt man die Zykluszeit des Eingangssignals in Genauigkeit eines Timer-Steps.
      Ich kenne keine genauere Methode, ein Eingangssignal zu bestimmen.
      Code first, think later - Natural programmer :D
    • six1 wrote:

      keine genauere Methode
      Ja, (deswegen ungenau). Man muß nur noch die Prioritäten festlegen- Präziese Pulslänge oder normal funktionierende Interrupts zu lasten der Genauigkeit. Die Timer2-Isr hätte nur ca 7 Takte bis sie wieder aufgerufen wird. Würde da ein anderer Int anliegen wird ein Aufruf übersprungen bzw das Preload zu spät gesetzt.
    • Pluto25 wrote:

      Nicht wirklich. Das Bitwait ist falschrum. Er würde blockiert wenn es keinen Puls gibt. Er mißt zu schnell (4,xx µS)
      Und ein Timeout von 400 ms wären immer noch nicht möglich.
      Bit falschrum?
      Steht ja ganz FETT drüber, "Länge Low-Puls" messen.
      Klar muss man an 2 Stellen drehen, dass das mit positivem Puls geht.

      Und das Timeout stimmt auch.
      Ein Schleifendurchlauf sind genau 5µs (im Simulator überprüft!).

      Das Timeout ist auf 80 Schleifendurchläufe ausgelegt. mal 5µs sind 400µs.
      Das Timeout kann in der Routine gesetzt werden.

      Vom Timing passt die Routine.
      Zugegeben, das mit dem Bitwait ist nicht schön. Das kann man auch mit While Wend machen.
      Aber die Routine sollte ja nur das Prinzip klar machen.
      Schließlich kochen die Entwickler ja auch nur mit Wasser.
    • Habs's kapiert mit dem verdrehten Bit.
      Bei dem Timeout habe ich mich verguckt.

      Hier also Version 2.

      BASCOM Source Code

      1. $Regfile = "m328pdef.dat"
      2. $Crystal = 16000000
      3. Config SubMode = New
      4. ' ----------------------------------------------
      5. ' Dauer High-Pegel messen, Auflösung 10µs
      6. ' Rückgabe in 10µs Schritten
      7. ' Beispiel: Rückgabe 4 bedeutet Dauer war 4 x 10µs = 40µs
      8. ' ----------------------------------------------
      9. Function myPulseIn() as Long
      10. Local tmpTimeout as Long
      11. Local tmpDauer as Long : tmpDauer = 0
      12. tmpDauer = 0 ' Pulsdauer auf 0
      13. tmpTimeout = 40000 ' Timeout 400µs = 40000x10µs
      14. BitWait PinB.1 , Reset ' Warten auf Low-Flanke
      15. ' Schleifendurchlauf 10µs
      16. While PinB.1 = 0 ' Messen Low-Dauer
      17. !Push r16
      18. !LDI r16,14
      19. !NOP
      20. !DEC r16
      21. !BRNE -2
      22. !POP r16
      23. !NOP
      24. !NOP
      25. Incr tmpDauer
      26. If tmpTimeout = 0 then
      27. Exit While
      28. End If
      29. Decr tmpTimeout
      30. Wend
      31. myPulseIn = tmpDauer
      32. End Function
      33. Dim Value as Word
      34. Do
      35. Value = myPulseIn()
      36. Loop
      Display All
      Die Schleifendauer habe ich jetzt auf 10µs gesetzt.

      Und gleich vorweg.
      Die Messung funktioniert nur genau, wenn während der Messung keine Interrupts laufen. Aber das sollte ich nicht extra erwähnen müssen, weil das ja logisch ist.
    • Pluto25 wrote:

      Bleibt nur noch das Problem das er ewig wartet wenn kein Puls kommt.
      Das hatte ich bereits erklärt in Post 27. Wer will kann das ja auch in eine While-Wend-Schleife packen.
      Und es soll ja auch kein Code sein, den mal jetzt 1:1 übernehmen muss, sondern nur aufzeigen, wie man einen Pulsein coden kann.

      Anstatt nur Kritik an Code von anderen zu üben, wäre es doch mal eine schöne Ergänzung, selbst einen funktionierenden Code aufzuzeigen.
      Und mit funktionieren meine ich funktionieren. Dein Code aus Post 15 hat auch einige Fehler.

      Mal abgesehen davon, dass man Interrupt-Flags durch Setzen dieser löscht und nicht durch Beschreiben von 0, kann ich auch mit deinem OR2A-Wert mit 95 nix abfangen.
      Für mich ergibt das keinen Sinn. Zumal nirgends steht, ob der Timer durchläuft oder ob du da einen CTC-Timer betreibst.

      Unsere Diskutiererei bringt uns aber nicht weiter.
      Marcopolo wird wohl eher an einer Lösung interessiert sein bezüglich seines Problems.
      Also entweder einen Lösungsansatz aufzeigen oder eben eine Lösung vorschlagen (nachvollziehbar).
    • Hallo Programmierer
      Der Prozessor war es nicht, habe einen anderen genommen, mit genau dem gleichen Ergebniss. Es scheint wohl so wie R2D2 Bastler es damals festgestellt hast.
      Ich komme einfach nicht über 40 mS.
      Aber ich gebe noch nicht auf
    • Hallo allerseits,
      heute habe ich den ganzen Tag mit Pulsein rumgespielt, leider überhaupt keine brauchbaren Erkenntnisse gewonnen.
      Das einzig stabile ist die Timeout Zeit von ca: 70mS (12Mhz Quarz). Mit der Variablen @genus(x) rumgespielt, zwar teilweise starke Unterschiede in dem Zählwert bis Timeout erhalten, aber nichts nachrechenbares. Auch der Eintrag "waitus Bpulsein_delay" war kein Erfolg.
      Also ich muß feststellen das der Befehl Pulsein zwar arbeitet aber in keinster Weise wie von MCS mit 3 Zeilen mal eben beschreiben wurde. Man findet auch nur diese 3 Zeilen in jeder Hilfe.
      Ich finde von MCS keine E-Mail, sonst würde ich diese gern mal damit konfrontieren, vielleicht hat ja jemand die Adresse oder ich schreibe denen mal einen Brief, ich kann es nicht glauchen das der Befehl nicht arbeitet.
      Also vielen Dank an alle die sich diesem Problem angenommen haben
      Viele Grüße Dieter
    • Na ja er arbeitet schon. Nur nicht so umfangreich wie Du es gern hättest. Das ist immer ein "Problem" mit vorbereiteten Routinen. Sie sollen möglichst kurz sein aber alles können, was nun leider ein Widerspruch ist.
      Sie sind entweder zu umfangreich (Flashverbrauchend) oder nicht umfangreich genung (Timeout). Wäre sie mit Dword ausgestattet sagt irgendwann jemand "Die dreiviertelstunde reicht nicht"
      Das schöne an Bascom ist ja neben der Sprache die Vielzahl an vorbereiteten Routinen. Da ist es aber nicht zu vermeiden das die manchmal nicht genau den Wunsch des Nutzers treffen.

      Ich hab ihn mir nochmal angeschaut . Irgendwas stimmt wirklich nicht. Es sieht aus als würde die Lib nicht aufgerufen.
      Kopiere ich sie ins Programm arbeitet sie wie in der Hilfe. Ca 10µs Step und ein Timeout von bis zu 0.6 Sekunden.

      The post was edited 1 time, last by Pluto25 ().

    • Das war auch nur um das Problem zu finden. Die Lib ist unkompiliert im Bascom Unterordner "LIB" und läßt sich mit jedem Editor öffnen. Ich habe die untere Routine (alles von _pulse_in5: bis zum ret) in die Main loop gepackt um zu sehen was falsch leuft - lief richtig. Das war nur ein Bruchteil der so für sich alleine wenig nützlich ist.
      Soll es nun richtig arbeiten ist da etwas mehr Arbeit nötig jedoch in den wenigsten Fällen sinnvoll. Macht es was es soll kann es auch in der Lib bleiben (Der Compiler holt sich was er braucht) Macht es nicht was man sucht ist ein eigener angepasster Code eher sinnvoll.