Register Pipeline
Simulates hardware register access: reads a sensor register, processes the value against thresholds, and sets GPIO pins accordingly. Demonstrates RegisterDataset, GpioDataset, and Param with a programmatically constructed catalog.
Usage
cargo run --example register_example -- run
cargo run --example register_example -- viz
Types
// ---------------------------------------------------------------------------
// Simulated hardware: heap-allocated "registers"
// ---------------------------------------------------------------------------
struct SimulatedHardware {
sensor_reg: Box<u16>,
status_reg: Box<u32>,
}
impl SimulatedHardware {
fn new() -> Self {
Self {
sensor_reg: Box::new(0),
status_reg: Box::new(0),
}
}
fn sensor_address(&self) -> usize {
&*self.sensor_reg as *const u16 as usize
}
fn status_address(&self) -> usize {
&*self.status_reg as *const u32 as usize
}
}
// ---------------------------------------------------------------------------
// Catalog and params
// ---------------------------------------------------------------------------
#[derive(Serialize)]
struct Catalog {
sensor: RegisterDataset<u16>,
status: RegisterDataset<u32>,
led_ok: GpioDataset,
led_warn: GpioDataset,
led_crit: GpioDataset,
}
#[derive(Serialize, Deserialize)]
struct Params {
warn_threshold: Param<u16>,
crit_threshold: Param<u16>,
}
Pipeline definition
// ---------------------------------------------------------------------------
// Pipeline
// ---------------------------------------------------------------------------
fn register_pipeline<'a>(cat: &'a Catalog, params: &'a Params) -> impl Steps<PondError> + 'a {
(
Node {
name: "read_sensor",
func: |raw: u16| -> (u32,) {
println!(" Sensor reading: 0x{raw:04x} ({raw})");
(raw as u32,)
},
input: (&cat.sensor,),
output: (&cat.status,),
},
Node {
name: "set_ok_led",
func: |reading: u16, warn: u16| {
let ok = reading < warn;
println!(" OK LED: {ok} (reading {reading} < warn {warn})");
(ok,)
},
input: (&cat.sensor, ¶ms.warn_threshold),
output: (&cat.led_ok,),
},
Node {
name: "set_warn_led",
func: |reading: u16, warn: u16, crit: u16| {
let warning = reading >= warn && reading < crit;
println!(" WARN LED: {warning}");
(warning,)
},
input: (&cat.sensor, ¶ms.warn_threshold, ¶ms.crit_threshold),
output: (&cat.led_warn,),
},
Node {
name: "set_crit_led",
func: |reading: u16, crit: u16| {
let critical = reading >= crit;
println!(" CRIT LED: {critical}");
(critical,)
},
input: (&cat.sensor, ¶ms.crit_threshold),
output: (&cat.led_crit,),
},
)
}