RPM PIGPIO falsche Werte "entprellen"

  • Wer nicht alles durch lesen möchte * Kann hier direkt einsteigen:
    http://www.forum-raspberrypi.d…llen?pid=281615#pid281615


    Da beginnt das Nötige. Wenn es fertig ist, arbeite ich das nochmal auf.



    Hallo,


    ich versuche meine RPM ein wenig zu entprellen und nutze die pigpio Bibliothek


    Ich bekomme leider immer wieder zu hohe Werte zurück :(


    Meine Umdrehungen ( Fahrrad ) liegen zwischen 1 und 120. Ich weiß nicht wo ich was nachstellen muss damit keine falschen Werte mehr ausgespuckt werden.


    Bei dem Beispiel:





    Kommen immer wieder Werte weit über 1000 ( So schnell bin ich wirklich nicht)
    Kondensator und Widerstand zum Hardware entprellen habe ich schon versucht, klappt leider nicht.


    die level im script habe ich auch schon in alle Variationen durch, allerdings wenn ich nicht weiß wo ich drehen soll bringt das ja auch nix.
    Kann mir da Jemand helfen?


    die RPM zähle ich mit eine reed Kontakt

    Einmal editiert, zuletzt von Landixus ()


  • die RPM zähle ich mit eine reed Kontakt


    Servus Landixus,


    bezüglich der Problematik "Entprellung" sind im Thread >> [C, C++] Taster prellen und Interrupt << gute Hinweise gegeben, wie man das Ganze am besten anpackt. Das Stichwort lautet dabei "Interrupt".


    Auch wenn dieser Thread von 2015 ist, so hat er fast nichts an Aktualität verloren: Dein Reedkontakt ist mit einem Taster direkt vergleichbar.


    schlizbäda

  • Er verwendet glaub ich bereits Interrupts.
    Er bedient sich hier des "RPM Monitor" Scripts von http://abyz.co.uk/rpi/pigpio/examples.html
    Ich weiß aber nicht ob das Script hierfür tatsächlich optimal funktioniert - dafür habe ich mich noch nicht ausführlich genug mit "pigpio" beschäftigt. Daher würde ich zunächst dazu tendieren das ganze mit eigenem Code umzusetzen der nicht so komplex aussieht bzw sehen sollte:


    [code=php]
    #!/usr/bin/python3
    from functools import partial
    from queue import Queue
    from datetime import datetime
    import pigpio



    # ISR
    def _callback(q, gpio, level, tick):
    # gpio: the gpio number of event
    # level: 0 or 1
    # tick: the number of microseconds since system boot
    q.put( (gpio, level, datetime.now()) ) # tuple



    def main():
    GPIO_pin = 4
    queue = Queue()
    gpio = pigpio.pi()

    gpio.set_mode(GPIO_pin, pigpio.INPUT)
    gpio.set_pull_up_down(GPIO_pin, pigpio.PUD_UP)
    gpio.callback(GPIO_pin, pigpio.EITHER_EDGE, partial(_callback, queue))

    try:
    # Queue abarbeiten
    while True:
    pin, state, dt = queue.get() # blockiert bis Eintrag im queue vorhanden
    if state == pigpio.LOW:
    print("{} Falling edge detected on {}".format(dt.strftime("%d.%m.%Y %H:%M:%S.%f"), pin))
    elif state == pigpio.HIGH:
    print("{} Rising edge detected on {}".format(dt.strftime("%d.%m.%Y %H:%M:%S.%f"), pin))

    except (KeyboardInterrupt, SystemExit):
    gpio.stop()
    print('\nQuit\n')



    if __name__ == '__main__':
    main()


    #EOF
    [/php]


    Das sollte als Basis herhalten können.


    Durch die Queue Geschichte wird sichergestellt das die Callback nicht blockiert wird und kein Interrupt verpasst werden kann.

  • Ich habs mal so eingebaut:


    Code
    1. pi.set_mode(gpio, pigpio.INPUT)
    2.       pi.set_glitch_filter(4, 200000)
    3.       self._cb = pi.callback(gpio, pigpio.RISING_EDGE, self._cbf)
    4.       pi.set_watchdog(gpio, self._watchdog)


    funktioniert noch nicht wirklich. Noch zu viele Fehler:




    Morgen mal bei Reichelt nen bisschen Hardware nachkaufen :)

    Einmal editiert, zuletzt von Landixus ()

  • Wo hast du das eingebaut? Du hast doch ein Klassen Konstrukt der der GPIO übergeben wird und als "gpio" abgreifbar ist. Es ist also unnötig " 4 " hardcoded einzufügen. Richte dich einfach an die anderen Zeilen


    Änder also:

    Code
    1. #
    2. pi.set_mode(gpio, pigpio.INPUT)
    3. pi.set_glitch_filter(4, 200000)
    4. self._cb = pi.callback(gpio, pigpio.RISING_EDGE, self._cbf)
    5. pi.set_watchdog(gpio, self._watchdog)


    in:

    Code
    1. #
    2. pi.set_mode(gpio, pigpio.INPUT)
    3. pi.set_glitch_filter(gpio, 200000)
    4. self._cb = pi.callback(gpio, pigpio.RISING_EDGE, self._cbf)
    5. pi.set_watchdog(gpio, self._watchdog)


    Siehe dazu auch: http://abyz.co.uk/rpi/pigpio/python.html#set_glitch_filter


    Und was meinst du mit "funktioniert noch nicht wirklich" ? Kannst du das bitte genauer spezifizieren? ;)


  • das meine ich mit funktioniert nicht richtig :)



    so ist der code jetzt

    Einmal editiert, zuletzt von Landixus ()

  • Wieso importierst du denn sowohl pigpio als auch RPi.GPIO ? :-/ Du brauchst nur eins von beidem



    Was mir aber auch gerade eben erst aufgefallen ist:

    Code
    1. import read_RPM
    2. p = read_RPM.reader(pi, RPM_GPIO)


    Wenn die Datei read_RPM.py heißt dann muss man innerhalb des selben Scripts nicht read_RPM.reader() aufrufen... :-/ :s
    Man hat eine Datei read_RPM.py und dort steht ganz oben " class reader: " usw. Dann importiert man nicht noch mal das file selbst sondern bindet das Klassen-Objekt an eine Variable, so wie es auch mit pigpio gemacht wird.. Oder hab ich da grad selbst nen Knoten im Kopf :huh:


    Daher an dieser Stelle die Frage: Hast du zuvor schon mal was mit Python gemacht? Irgendein Script geschrieben und ausprobiert?


    Code Beitrag#1 müsste IMHO also wenn dann so aussehen => http://codepad.org/KQTaY9qi



    Habe mich jetzt ein bisschen mehr mit dem Script auseinander gesetzt und glaube nicht das "set_glitch_filter" irgendwas ändern wird. Allgemein finde ich das Script etwas fragwürdig für dein Vorhaben, da es zB auch "minimum RPM" behandelt und set_watchdog nutzt dh tritt innerhalb 200ms kein Interrupt auf wird _cbf() mit level=2 ausgeführt.


    Aber wie gesagt, ich kenne mich mit pigpio noch nicht allzu gut aus., würde aber trotzdem versuchen das ganze mit eigenen Codezeilen nachzubauen.... Also selber ein Konzept überlegen, die Anforderungen festlegen oder generell darüber nachdenken was man eigentlich erreichen möchte. Angefangen damit, wie viele Impulse/Interrupts für eine Umrundung des Rads zählen - oder ob innerhalb von zum Beispiel einer Sekunde die Umrundungen angezeigt werden sollen? Aktuell werden alle 2 Sekunden die RPM ausgelesen und dem Ergebnis 0.5 addiert... Die Zeiterfassung für jeden Interrupt wird durch 'tick' und 'pigpio.tickDiff' erfasst.



    Kann aber wie gesagt gut sein das ich völlig am Ziel vorbei schieße :blush:


    //EDIT: Probier mal das die Zeile "pi.set_watchdog(gpio, self._watchdog)" auf das zu ändern: pi.set_watchdog(gpio, 0)
    damit wird der abgeschaltet ohne am Code groß was ändern zu müssen...



    //EDIT2: Vielleicht hilft dir aber auch das: https://github.com/meigrafd/Sa…master/geschwindigkeit.py

  • Zitat


    Probier mal das die Zeile "pi.set_watchdog(gpio, self._watchdog)" auf das zu ändern: pi.set_watchdog(gpio, 0)


    leider immer noch falsche Werte:

    Zitat


    EDIT2: Vielleicht hilft dir aber auch das: https://github.com/meigrafd/Sample-Code/...digkeit.py


    habs versucht, bekomme aber damit keine Ausgabe hin.

    Code
    1. pi@carcam:~/ant-cycling-power $ ./rpm.py
    2. Traceback (most recent call last):
    3.  File "./rpm.py", line 8, in <module>
    4.    from RPi import GPIO
    5. ImportError: No module named 'RPi'
    6. pi@carcam:~/ant-cycling-power $


    So genau weiß ich nicht was ich da mache, allerdings habe ich mir das seit 2 Wochen zusammen geschustert das ich schon eine Ausgabe habe. Am Ende muss das doch nicht am entprellen scheitern :(
    Ich hab jetzt nochmal den kompletten code inklusive "meiner" power Berechnung gepostet. Bin echt am verzweifeln und für jede Hilfe dankbar.



    Ich spende nen Fuffi für das Forum wenn es läuft Und nen Fuffi für den Ersteller des laufenden Scripts. Und wenn das Forum kein Geld braucht, dann 100 für den Ersteller :) :wallbash:

    Einmal editiert, zuletzt von Landixus ()

  • Zunächst würde ich versuchen hardwareseitig so gut wie möglich das prellen zu unterbinden, erst dann würde ich am Code den Rest machen. Mehr Infos zu deiner verbauten Hardware wäre da schon nützlich.
    Ein min_RPM = 1.0 hast du ja schon, warum nicht auch ein max_RPM, der alle Werte über 120 verwirft...
    Zu dem:

    Code
    1. ImportError: No module named 'RPi'


    Probier mal statt ./rpm.py ein

    Code
    1. /usr/bin/python /pfad/zum/script/rpm.py


    Wenn es nicht vorhanden ist, dann musst du es halt installieren:

    Code
    1. sudo apt-get install rpi.gpio
  • Hardware entprellen hab ich, das auch kein Problem für mich *zum Glück kann ich auch was :).
    Ich geh einfach mit den Werten hoch wenn die Zeit zu kurz ist (100nf -> 470nf ->1µf)


    Aber ich weiß das der code schrottig ist(Das kann ich mal gar nicht), deswegen mein Taler Angebot.


    das rpm.py würde ich gerne nicht benutzen, da ich nicht von vorne anfangen wollte.

    Einmal editiert, zuletzt von Landixus ()


  • Mit einem Oszi lässt sich doch gut messen, wie sauber das Signal ist, vllt. hast du eines oder kannst dir eines leihen.


    OSZI habe ich nicht, aber ich glaube auch nicht, das dort das Problem liegt. (Das Problem guckt immer auf den Monitor) :)
    Beim Arduino war das soooooo leicht...

  • Wie gesagt, du brauchst nicht beide Module: RPi.GPIO und pigpio
    Sondern nur eins von beidem. Deine selbst zusammengeschusterte read_rpm.py verwendet beides, was, wenn ich das so sagen darf, Quatsch ist.


    RPi.GPIO ist ein Python Module für den Pi zur Handhabung der GPIOs - das erste was raus kam aber mittlerweile leider veraltet.
    pigpio ist auch ein Python Module für den Pi zur Handhabung der GPIOs - ein recht junges und weitaus umfangreicheres wie dem Urgestein.


    Beides in einem Script zu verwenden schürt Verwirrung.


    geschwindkeit.py ist für Python3. Es muss also das RPi.GPIO Module explizit für Python3 installiert sein, da Python2 und 3 von einander getrennte Umgebungen sind - und nicht wirklich vollständig kompatibel zueinander.


    Aber auch das read_rpm.py Script ist für Python3 geschrieben - das erkennt man an den print's da das in Python3 eine Funktion ist, in Python2 aber ein Statement.


    Code
    1. sudo apt-get install python3-rpi.gpio


    Allerdings finde ichs generell besser Python Module über 'pip' zu installieren, den Python eigenen Paketmanager, denn über apt-get sind die Pakete teilweise älter.


    Code
    1. sudo apt-get install python3-pip
    2. sudo pip3 install RPi.GPIO


    Auch wenn du geschwindkeit.py (bzw rpm.py ?) nicht verwenden willst, würde es zumindest dabei helfen um herauszufinden ob dein Problem Hardwareseitig liegt oder doch Softwareseitig.
    Einrückungen sind für Python auch extrem wichtig, in deinem zuletzt gezeigten Code sind diesbezüglich aber einige Fehlerhafte Zeilen drin.


    Auch wenn wir nicht das gesamte Konstrukt kennen lehne ich mich mal aus dem Fenster und behaupte dass es nicht viel Aufwand wäre dein bisheriges Script umzuschreiben.

  • Kann ich das dann so machen mit max_RPM?



    Allerdings ist das ja auch nicht richtig, wenn alle 8 RPM Werte ein falscher Wert kommt.
    Automatisch zusammengefügt:
    [hr]


    Das ist ja alles ganz nett, aber ich probiere nur rum, das bringt mich leider nicht so richtig weiter. Ich kanns einfach nicht *zensierten Ausruf mach*. das mit pip und so kenn ich, benutze ich auch für die Module, aber ich möchte ja mein script weiter verwenden, ich kann einfach nicht mehr von vorne anfangen.
    RPi.GPIO hab ich mit drinne, da ich noch 2 Taster extra bediene um in der Tabelle die richtigen Level zu wählen.
    Ich brauch die Tabelle um später du Powerwerte auszulesen (Das klappt schon).

    Einmal editiert, zuletzt von Landixus ()

  • Wie schon in Beitrag#15 erwähnt: Für Python sind Einrückungen extrem wichtig. Du hast hier leider auch wieder eine falsche Einrückung verwendet.


    Dazu kommt, wenn du alle Werte über 120 auf 50 ändern lässt wird das doch genau so verfälscht wie zuvor!? Sowas löst kein Problem sondern ignoriert es nur... Finde ich einen ziemlich miesen weg


    //EDIT:


    RPi.GPIO hab ich mit drinne, da ich noch 2 Taster extra bediene um in der Tabelle die richtigen Level zu wählen.
    Ich brauch die Tabelle um später du Powerwerte auszulesen (Das klappt schon).


    Was hat die Tabelle mit den Python Modulen zu tun? :-/


    pigpio kann genau so mit 2 Tastern umgehen!
    Tu dir selbst ein Gefallen und setze dich mit dem Code den du verwendest auseinander


    Wenn du pip kennst wieso installierst du für ein python3 Script dann nicht das benötigte Module? Also sorry aber das passt doch nicht zusammen? In Beitrag#9 kriegste das Script nicht ausgeführt und nun sagste das sei dir alles längst bekannt?



    ich kann einfach nicht mehr von vorne anfangen.


    Dein Konstrukt funktioniert nicht, also musst du zwangsläufig etwas umschreiben. Wenn dein Script aber nur aus dem bisher gezeigten besteht ist es doch nicht wirklich viel? Die "reader" Klasse stammt nicht von dir und der Rest sind nur 20 Zeilen oder so...




    PS: Bitte nicht Beiträge vollständig quoten/zitieren, vor allem wenn diese genau da drüber stehen.

  • Demnach wäre noch wichtig zu erwähnen, das Script so zu starten:

    Code
    1. /usr/bin/python3 /pfad/zum/script/rpm.py


    Denn aus dem Script selbst geht das nicht hervor, welche Python-Version benutzt werden soll.

  • Servus,
    nur mal eine kleine Bewerkung am Rande ...


    ... die RPM zähle ich mit eine reed Kontakt


    ich würde den Reed-Kontakt mal durch einen Hall-Sensor ersetzen. Ich kann mir gut vorstellen dass der Kontakt durch die Vibrationen beim Fahren Fehlimpulse liefert ...


    cu,
    -ds-

  • fred0815 : Im geschwindigkeit.py ist der Shebang auf python3 gesetzt und das hatte er zuvor versucht direkt auszuführen:



    habs versucht, bekomme aber damit keine Ausgabe hin.

    Code
    1. pi@carcam:~/ant-cycling-power $ ./rpm.py
    2. Traceback (most recent call last):
    3.  File "./rpm.py", line 8, in <module>
    4.    from RPi import GPIO
    5. ImportError: No module named 'RPi'
    6. pi@carcam:~/ant-cycling-power $


    Es fehlte also nur das Module für Python3. Und da das fehlt führt er die ganze Zeit read_rpm.py mit der falschen Python Version aus....