Skip to main content

multireader/
multireader.rs

1// Read two channels at once with a multi reader, which aligns the signals on
2// a common clock so each row of values shares one timestamp.
3
4use opendaq::{Channel, Instance, MultiReader, TickConverter};
5
6/// Render nanoseconds since the Unix epoch as a readable UTC time of day,
7/// e.g. "21:05:28.401836".
8fn time_of_day(unix_nanos: i128) -> String {
9    let micros = unix_nanos.div_euclid(1_000);
10    let micro = micros.rem_euclid(1_000_000);
11    let s = micros.div_euclid(1_000_000).rem_euclid(86_400);
12    format!(
13        "{:02}:{:02}:{:02}.{micro:06}",
14        s / 3600,
15        s / 60 % 60,
16        s % 60
17    )
18}
19
20fn find_channel(instance: &Instance, path: &str) -> opendaq::Result<Channel> {
21    instance
22        .find_component(path)?
23        .unwrap_or_else(|| panic!("channel {path} not found"))
24        .cast::<Channel>()
25}
26
27fn main() -> opendaq::Result<()> {
28    let instance = Instance::new()?;
29    instance.add_device("daqref://device0")?;
30
31    let channels = [
32        find_channel(&instance, "Dev/RefDev0/IO/AI/RefCh0")?,
33        find_channel(&instance, "Dev/RefDev0/IO/AI/RefCh1")?,
34    ];
35    channels[0].set_property_value("Frequency", 0.5)?;
36    channels[1].set_property_value("Frequency", 2.0)?;
37
38    let signals = [
39        channels[0].signals()?[0].clone(),
40        channels[1].signals()?[0].clone(),
41    ];
42    let reader = MultiReader::<f64>::new(&signals)?;
43
44    // The first reads can return nothing while the reader synchronises the
45    // signals onto the common domain; retry until rows arrive.
46    for _ in 0..10 {
47        let (values, domain) = reader.read_with_domain(8, 1000)?;
48        if domain[0].is_empty() {
49            continue;
50        }
51        let converter = TickConverter::from_multi_reader(&reader)?;
52        print!("{:<16}", "timestamp");
53        for index in 0..values.len() {
54            print!("{:>14}", format!("signal {index}"));
55        }
56        println!();
57        for (row, tick) in domain[0].iter().enumerate() {
58            print!("{:<16}", time_of_day(converter.tick_to_unix_nanos(*tick)));
59            for signal_values in &values {
60                print!("{:>14.6}", signal_values[row]);
61            }
62            println!();
63        }
64        return Ok(());
65    }
66    println!("Multi reader did not synchronise in time.");
67    Ok(())
68}