Quick Start

This guide will help you write your first RevPiModIO program.

Basic Concepts

RevPiModIO provides two main programming paradigms:

  • Cyclic Programming - Execute a function at regular intervals (PLC-style)

  • Event-Driven Programming - Register callbacks triggered by hardware changes

Both approaches use the same core objects:

  • rpi.io - Access inputs and outputs by name

  • rpi.core - Control LEDs, watchdog, and system status

  • rpi.device - Access specific hardware devices

Hardware Configuration

Before programming, configure your hardware using piCtory:

  1. Access piCtory web interface on your RevPi Core module

  2. Add and configure your I/O modules

  3. Assign symbolic names to inputs and outputs

    • Example: button, led, temperature

    • Good names make your code readable

  4. Save configuration and activate

Your First Program

Simple Input to Output

The simplest program reads an input and controls an output:

import revpimodio2

# Initialize with auto-refresh
rpi = revpimodio2.RevPiModIO(autorefresh=True)

# Read input and control output
if rpi.io.button.value:
    rpi.io.led.value = True
else:
    rpi.io.led.value = False

# Clean up
rpi.exit()

Cyclic Program

For continuous operation, use a cyclic loop:

import revpimodio2

def main_cycle(ct: revpimodio2.Cycletools):
    """Called every cycle (default: 20-50ms)."""

    if ct.first:
        # Initialize on first cycle
        ct.var.counter = 0
        print("Program started")

    # Main logic
    if ct.io.button.value:
        ct.io.led.value = True
    else:
        ct.io.led.value = False

    # Count button presses
    if ct.changed(ct.io.button, edge=revpimodio2.RISING):
        ct.var.counter += 1
        print(f"Button pressed {ct.var.counter} times")

    if ct.last:
        # Cleanup on exit
        print("Program stopped")

# Run cyclic loop
revpimodio2.run_plc(main_cycle)

Event-Driven Program

For event-based operation, use callbacks:

import revpimodio2

rpi = revpimodio2.RevPiModIO(autorefresh=True)

def on_button_press(ioname, iovalue):
    """Called when button changes."""
    print(f"Button is now: {iovalue}")
    rpi.io.led.value = iovalue

# Register event callback
rpi.io.button.reg_event(on_button_press)

# Handle shutdown signals
rpi.handlesignalend()

# Start event loop
rpi.mainloop()

LED Control

Control the RevPi status LEDs:

import revpimodio2

rpi = revpimodio2.RevPiModIO(autorefresh=True)

# Set LED colors using constants
rpi.core.A1 = revpimodio2.GREEN  # Success
rpi.core.A2 = revpimodio2.RED    # Error
rpi.core.A3 = revpimodio2.OFF    # Off

# Or control individual colors
rpi.core.a1green.value = True
rpi.core.a1red.value = False

rpi.exit()

Common Patterns

Initialize and Cleanup

Always initialize variables and clean up resources:

def main_cycle(ct):
    if ct.first:
        # Initialize
        ct.var.state = "IDLE"
        ct.var.error_count = 0

    # Main logic here...

    if ct.last:
        # Cleanup
        ct.io.motor.value = False
        print(f"Errors: {ct.var.error_count}")

Edge Detection

Detect rising or falling edges:

def main_cycle(ct):
    # Detect button press (rising edge)
    if ct.changed(ct.io.button, edge=revpimodio2.RISING):
        print("Button pressed!")

    # Detect button release (falling edge)
    if ct.changed(ct.io.button, edge=revpimodio2.FALLING):
        print("Button released!")

Timers

Use built-in cycle-based timers:

def main_cycle(ct):
    # On-delay: Input must be True for 10 cycles
    ct.set_tonc("startup", 10)
    if ct.get_tonc("startup"):
        ct.io.motor.value = True

    # Pulse: Generate 5-cycle pulse
    if ct.io.trigger.value:
        ct.set_tpc("pulse", 5)
    ct.io.pulse_output.value = ct.get_tpc("pulse")

Next Steps