Events and own cyclical tasks

We would like to introduce you a solution to use events and also do your own cyclical tasks at the same time.

You must use at least version 2.2.2 of RevPiModIO!

Program description

The program sets output O_1 to True, if input I_1 is set to True and leave it set. If I_1 goes to True again, O_1 should be reset to False (FlipFlop circuit).

While the program is running and waits for events, the LED A1 of the Core flashes green at a rate of 500 milliseconds!

piCtory configuration

Also important are the names of the IOs. For this example we need an input named I_1 and an output named O_1 (this is usually the default).

Source code

And here is the documented source code that does our job.
The new .exitsignal.wait(0.5) is used for our while loop to execute it every 0.5 seconds (500 milliseconds) and exit at program exit SIGINT/SIGTERM. This is a Python threading.Event() object – Doc. It is automatically set by RevPiModIO (When call .exit() or used .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: To transfer and monitor this program to the RevPi, we use RevPiPyLoad – but of course it also runs directly on the RevPi.