Basics¶
Core concepts and fundamental usage of RevPiModIO.
Contents
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
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