Erweiterung für gpiozero

  • Hallo Zusammen,

    bin gerade positiv überrascht wie einfach es doch ist in Python sich zu einem bestehenden Modul eigene Funktionen zu erweitern.

    Seit dem Umstieg von RPi.GPIO auf gpiozero hatte ich immer die Funktion event_detected() in gpiozero vermisst.

    Dies habe ich mir nun selbst erweitert.

    Zuzüglich noch die Funktion, dass man ermitteln kann wie lange ein Taster gedrückt worden ist. Dies funktioniert ja aktuell leider Modulseitig nicht ohne Fehler: siehe hier ab #10

    Vielleicht kann es ja der ein oder andere von euch gebrauchen :)

    example.py

    buttonxtendgpiozero.py:

  • Moin

    [...]Seit dem Umstieg von RPi.GPIO auf gpiozero hatte ich immer die Funktion event_detected() in gpiozero vermisst.[...]

    Die Funktion gibt es doch. Je nach Klasse hat sie einen anderen Namen zB wait_for_press oder when_motion etc...

    Intern werden die obigen Namen an die Methode when_activated() bzw. wait_for_active()gebunden:

    Python
    from gpiozero import DigitalInputDevice
    import signal
    
    def say_hello():
        print "hallo welt"
    
    taster = DigitalInputDevice(21)
    
    taster.when_activated = say_hello
    signal.pause()

    Quelle: https://github.com/RPi-Distro/pyt…/mixins.py#L149

  • Um das Thema nochmal "scharf" zu machen,

    nein, der Unterschied darin ist, bei when_activated gehts sofort bei Tastendruck in die definierte Funktion.

    Bei meiner Erweiterung wird der Tastendruck im Hintergrund gespeichert und man kann im Skriptablauf gezielt danach abfragen, ob bis dahin der entsprechende Taster gedrückt wurde und erst zu diesem Zeitpunkt betritt man die gewünschte Funktion.

  • Also du hast natürlich recht, dass die Funktion das Programm solange blockiert wie der Taster gedrückt wird.

    Aber dem ist wohl auch in jeder anderen "einfachen" umsetzen der Fall wenn man wissen will wie lange der Taster gedrückt wird.

    So wie ich das bisher bei asyncio verstanden habe, muss dafür das ganze Programm dafür ausgelegt sein, womit es nicht reichen würde nur in der Funktion set_event das einzubauen...sondern es müsste überall angepasst werden, womit die Integration der Erweiterung deutlich erschwert werden würde.

    Bis auf threading würd mir sonst keine andere Möglichkeit einfallen das Programm damit nicht zu blockieren?!

    Bisher hatte ich jedoch noch keine Probleme damit, dass mir die Funktion den Ablauf blockierte, vll auch deswegen im Unterbewusstsein mit einkalkuliert :conf:

  • asyncio

    Wo kommt denn jetzt auf einmal asyncio her? gpiozero arbeitet m.E. mit Threads. Trotzdem ist mein Verständnis, daß callback-Funktionen nicht blockieren sollten:

    If you're using event-driven, don't put blocking while loops in your callbacks!

    Bis auf threading würd mir sonst keine andere Möglichkeit einfallen das Programm damit nicht zu blockieren?!

    Ich würde das vermutlich ungefähr so machen:

    (alles ungetestet, könnte also beliebig viele Syntax-Fehler enthalten).

    Wobei mir nicht ganz klar ist, wie Du damit umgehen willst, wenn check_status aufgerufen wird, währen der Button noch gedrückt ist – insofern stellt dieser Code einen Rateversuch dar.

    Einmal editiert, zuletzt von Manul (14. August 2018 um 12:39) aus folgendem Grund: Link zum Github-Zitat ergänzt.

  • Wo kommt denn jetzt auf einmal asyncio her?

    Nur aus meinem Kopf heraus wie man das ganze lösen könnte


    Wobei mir nicht ganz klar ist, wie Du damit umgehen willst, wenn check_status aufgerufen wird, währen der Button noch gedrückt ist

    Hierbei ist check_status noch auf False, dies wird erst nach loslassen des Tasters gesetzt

    gpiozero arbeitet m.E. mit Threads. Trotzdem ist mein Verständnis, daß callback-Funktionen nicht blockieren sollten:

    da ich gpiozero nur Erweitert habe, dann müsste das ganze sowieso in einem seperaten Thread ablaufen, wodurch evtl das Programm nicht blockiert wird. Werd ich bei zeiten mal prüfen.

  • So gerade getestet, das Programm läuft während des Drücken des Tasters weiter:

  • Hallo,

    so, besser spät als nie :) Es geht auch ohne die Klasse zu erweitern, in dem man eine Generator-Funktion für die Zeitmessung benutzt:

    Während ist das `print('Foo') getippt habe war der Button gedrückt.

    Gruß, noisefloor

  • Ich würde das vermutlich ungefähr so machen:

    Auf Basis dessen, habe ich eine Überarbeitete Version erstellt ( siehe #1)


    so, besser spät als nie :)

    ich hoffe, das zählt für mich jetzt auch :)

    Also vorwiegend gehts mir nicht um die Erfassung der Zeit, sondern um den Status zwischenzuspeichern, dass ein Taster gedrückt wurde.

    Erst wenn der Status abgefragt wird, wird der Status zurückgesetzt. Das mit der Zeiterfassung hab ich dann nur zusätzlich mit rein genommen.

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!