This folder contains the lowest-level adapters that talk to Rio hardware: SPI/GPIO selection, packet framing, and per-module protocol drivers. Controllers in ../controllers/ build “application behaviors” on top of these primitives.
- Belongs here: device protocol constants, packet framing, and “one module ↔ one firmware protocol” drivers.
- Does not belong here: UI semantics and long-running orchestration loops (those belong in
../controllers/), and HTTP/WebSocket handling (belongs in../rio-webapp/).
This folder is the hardware abstraction layer for the system. For most modules there is a single concrete driver (flow/heater/strobe/pump). Cameras are the exception: drivers/camera/ defines a BaseCamera abstraction plus multiple backends (Pi legacy, Mako, Daheng). Controllers consume these drivers and provide the higher-level behavior.
spi_handler.py is the shared substrate used by SPI-speaking drivers:
- Simulation switch:
RIO_SIMULATION=trueswaps in simulated GPIO/SPI from../simulation/spi_simulated.py. - SPI lifecycle:
spi_init(bus, mode, speed_hz)initializes the globalspi_handler.spi- drivers expect
spi_handler.spito be initialized before calling into them
- Chip select: the board uses GPIO “ports” (see
PORT_*constants) andspi_select_device(port)to select a module. - Concurrency:
spi_lock()/spi_release()serialize access across modules.
Multiple drivers follow the same PIC packet framing:
STX = 2- message:
[STX][size][packet_type][data...][checksum] - checksum is chosen so that the sum of all bytes modulo 256 equals 0
See: drivers/flow.py, drivers/heater.py, drivers/strobe.py (and the corresponding firmware folders under hardware-modules/*/*_pic/).
-
Flow/pressure:
flow.py→class PiFlow- packet types align with
hardware-modules/pressure-flow-control/pressure_and_flow_pic/ - typical calls:
get_id(),set_pressure(...),get_pressure_actual(),set_flow(...),get_control_modes(),set_control_mode(...), PID constant get/set - simulation: may delegate to
simulation.flow_simulated.SimulatedFlowwhen enabled
- packet types align with
-
Heater/stirrer:
heater.py→class PiHolder- packet types align with
hardware-modules/heating-stirring/sample_holder_pic/ - typical calls:
get_id(),set_pid_temp(...),get_temp_actual(), PID get/set, autotune, stir get/set, power-limit get/set
- packet types align with
-
Strobe:
strobe.py→class PiStrobe- packet types align with
hardware-modules/strobe-imaging/strobe_pic/ - typical calls:
set_enable(...),set_timing(wait_ns, period_ns),set_hold(...),get_cam_read_time() - Note:
set_trigger_mode()exists in the driver but is not used (PIC-paced mode only)
- packet types align with
-
Camera:
camera/subpackage (seecamera/README.md)- abstraction layer and backends (Pi camera + Mako)
-
Syringe pump (USB serial):
syringe_pump_serial.py- USB serial protocol for the ESP32 pump controller
Prefer running tests in simulation mode:
cd software
export RIO_SIMULATION=true
pytest -vThis file was AI-generated and may contain errors. Please verify against the source code and runtime behavior.
- Date: 2025-12-30
- Model: GPT-5.2
- Maintenance: If you change protocols, packet framing, or driver public methods, update this document.