Basics
Core concepts and fundamental usage of RevPiModIO.
Programming Paradigms
RevPiModIO supports two complementary programming approaches:
Cyclic Programming - Execute a function at regular intervals, similar to PLC programming.
Best for deterministic timing, state machines, and time-critical control
Runs your function every cycle (typically 20-50ms)
See Cyclic Programming for details
Event-Driven Programming - Register callbacks triggered by hardware state changes.
Best for user interactions, sporadic events, and system integration
Consumes CPU only when events occur
See Event Programming for details
Both approaches can be combined in a single application. See Advanced for examples.
Getting Started
Basic Instantiation
Create a RevPiModIO instance to access your hardware:
import revpimodio2
rpi = revpimodio2.RevPiModIO(autorefresh=True)
# Your code here
rpi.exit()
Configuration Parameters
rpi = revpimodio2.RevPiModIO(
autorefresh=True, # Auto-sync process image (recommended)
monitoring=False, # Read-only mode
syncoutputs=True, # Load output values on init
debug=False # Enable debug messages
)
autorefresh - Automatically reads inputs and writes outputs. Set to True for most applications.
monitoring - Read-only mode. Use when monitoring without controlling hardware.
syncoutputs - Load current output values on startup. Prevents outputs from resetting.
debug - Enable debug logging for troubleshooting.
Cycle Timing
Default update rates depend on your hardware:
Core 1: 40ms (25Hz)
Core3/Connect: 20ms (50Hz)
NetIO: 50ms (20Hz)
Adjust cycle time to match your needs:
rpi = revpimodio2.RevPiModIO()
rpi.cycletime = 100 # Set to 100ms
rpi.autorefresh_all()
Important: Faster cycle times consume more CPU. Choose the slowest cycle time that meets your requirements. Default values will fit most needs.
Error Handling
Configure I/O error threshold:
maxioerrors = 10 # Raise exception after 10 errors
# Check error count
if rpi.core.ioerrorcount > maxioerrors:
print("Warning: I/O errors detected")
Core Objects
rpi.io - Input/Output Access
Access all configured IOs from piCtory:
# Direct attribute access
value = rpi.io.button.value
rpi.io.led.value = True
# String-based access
rpi.io["button"].value
# Check existence
if "sensor" in rpi.io:
print(rpi.io.sensor.value)
# Iterate all IOs
for io in rpi.io:
print(f"{io.name}: {io.value}")
IO Properties
Each IO object has these properties:
.name- IO name from piCtory.value- Current value (read/write).address- Byte address in process image.type- IO type (INPUT=300, OUTPUT=301, MEMORY=302).defaultvalue- Default value from piCtory
rpi.core - System Control
Access Revolution Pi system features:
LED Control
# Using constants
rpi.core.A1 = revpimodio2.GREEN
rpi.core.A2 = revpimodio2.RED
rpi.core.A3 = revpimodio2.OFF
# Individual colors
rpi.core.a1green.value = True
rpi.core.a1red.value = False
System Status
# CPU information
temp = rpi.core.temperature.value
freq = rpi.core.frequency.value
# piBridge status
cycle_time = rpi.core.iocycle.value
errors = rpi.core.ioerrorcount.value
Watchdog
# Toggle watchdog
rpi.core.wd_toggle()
# Watchdog IO object
rpi.core.wd.value = True
See Advanced for complete watchdog management examples.
rpi.device - Device Access
Access specific hardware devices:
# By name
dio = rpi.device.DIO_Module_1
# By position
first = rpi.device[0]
# Iterate
for device in rpi.device:
print(device.name)
Signal Handling
Graceful Shutdown
Handle SIGINT and SIGTERM for clean program termination:
rpi = revpimodio2.RevPiModIO(autorefresh=True)
# Enable signal handling
rpi.handlesignalend()
# Run main loop
rpi.mainloop()
Custom Signal Handler
Implement custom cleanup logic:
def cleanup(signum, frame):
print("Shutting down...")
rpi.setdefaultvalues()
rpi.exit()
rpi.handlesignalend(cleanup)
rpi.mainloop()
Simple Examples
Read Input, Control Output
import revpimodio2
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
rpi.exit()
LED Control
import revpimodio2
rpi = revpimodio2.RevPiModIO(autorefresh=True)
# Control status LEDs
rpi.core.A1 = revpimodio2.GREEN
rpi.core.A2 = revpimodio2.RED
rpi.exit()
Iterate All IOs
import revpimodio2
rpi = revpimodio2.RevPiModIO(autorefresh=True)
# Print all IOs and their values
for io in rpi.io:
print(f"{io.name}: {io.value}")
rpi.exit()
Best Practices
Use Descriptive IO Names
Configure descriptive names in piCtory:
# Good - Clear intent
if rpi.io.emergency_stop.value:
rpi.io.motor.value = False
# Poor - Generic names
if rpi.io.I_15.value:
rpi.io.O_3.value = False
Always Clean Up
Always call rpi.exit() to clean up resources:
rpi = revpimodio2.RevPiModIO(autorefresh=True)
try:
# Your code here
pass
finally:
rpi.exit()
Check IO Existence
Verify IOs exist before accessing:
if "optional_sensor" in rpi.io:
value = rpi.io.optional_sensor.value
else:
print("Sensor not configured")
See Also
Cyclic Programming - Cyclic programming patterns
Event Programming - Event-driven programming patterns
Advanced - Advanced topics and best practices
API Reference - API reference