Events und eigene zyklische Aufgaben

Hier möchten wir euch eine Lösung vorstellen, mit der ihr auf Events reagieren, aber gleichzeitig auch eigene zyklische Aufgaben erledigen könnt.

Es muss mindestens Version 2.2.2 von RevPiModIO verwendet werden!

Programmbeschreibung

Das Programm soll den Ausgang O_1 auf True setzen, wenn I_1 auf True wechselt und diesen aktiv lassen. Wenn I_1 erneut auf True wechselt, soll O_1 wieder auf False gesetzt werden (FlipFlop Schaltung).

Parallel soll während das Programm läuft, die LED A1 vom Core im Takt von 500 Millisekunden grün blinken!

piCtory Konfiguration

Wichtig sind hier auch die Namen der IOs. Für dieses Beispiel brauchen wir einen Eingang mit dem Namen I_1 und einen Ausgang mit dem Namen O_1 (dies ist meistens der Standard).

Quellcode

Und hier ist der dokumentierte Quellcode, der unsere Aufgabe erledigt.
Das neue .exitsignal.wait(0.5) wird für unseren While-Loop verwendet, um diesen alle 0.5 Sekunden (500 Millisekunden) auszuführen und bei Programmende zu verlassen. Es handelt sich dabei um ein Python threading.Event() Objekt – Doku. Dieses wird automatisch von RevPiModIO gesetzt (Bei .exit() oder Verwendung von .handlesignalend())

#!/usr/bin/python3
# -*- coding: utf-8 -*-
#
# (c) Sven Sager, License: GPLv3
#
"""Combined events with mainloop() and own cyclic functions.

Let the LED A1 blink green during program is running. Switch on output O_1
if I_1 goes to True and switch off output O_1 if I_1 goes to True again.

piCtory Setup: RevPICore | DIO

"""
import revpimodio2


class MyRevPiApp():

    """Mainapp for RevPi."""

    def __init__(self):
        """Init MyRevPiApp class."""

        # Instantiate RevPiModIO
        self.rpi = revpimodio2.RevPiModIO(autorefresh=True)

        # Handle SIGINT / SIGTERM to exit program cleanly
        self.rpi.handlesignalend(self.cleanup_revpi)

        # Register event to toggle output O_1 with input I_1
        self.rpi.io.I_1.reg_event(self.event_flipflop_o1, edge=revpimodio2.RISING)

    def cleanup_revpi(self):
        """Cleanup function to leave the RevPi in a defined state."""

        # Switch of LED and outputs before exit program
        self.rpi.core.a1green.value = False
        self.rpi.io.O_1.value = False

    def event_flipflop_o1(self, ioname, iovalue):
        """Called if I_1 goes to True."""

        # Switch on/off output O_1
        self.rpi.io.O_1.value = not self.rpi.io.O_1.value

    def start(self):
        """Start event system and own cyclic loop."""

        # Start event system without blocking here
        self.rpi.mainloop(blocking=False)

        # My own loop to do some work next to the event system. We will stay
        # here till self.rpi.exitsignal.wait returns True after SIGINT/SIGTERM
        while not self.rpi.exitsignal.wait(0.5):

            # Switch on / off green part of LED A1 | or do other things
            self.rpi.core.a1green.value = not self.rpi.core.a1green.value


if __name__ == "__main__":
    # Start RevPiApp app
    root = MyRevPiApp()
    root.start()

PS: Um dieses Programm auf den RevPi zu übertragen und zu überwachen, verwenden wir RevPiPyLoad – Es läuft aber natürlich auch direkt auf dem RevPI.