rsiot/drivers_i2c/ads1115/
device.rs1use std::{io::Cursor, sync::Arc, time::Duration};
2
3use byteorder::{BigEndian, ReadBytesExt};
4use tokio::{sync::Mutex, task::JoinSet, time::sleep};
5use tracing::warn;
6
7use crate::{executor::CmpInOut, message::MsgDataBound};
8
9use super::{
10 super::{I2cSlaveAddress, RsiotI2cDriverBase},
11 config,
12};
13
14pub struct ADS1115<TMsg, Driver>
16where
17 TMsg: MsgDataBound,
18 Driver: RsiotI2cDriverBase,
19{
20 pub address: I2cSlaveAddress,
22
23 pub inputs: Vec<config::InputConfig<TMsg>>,
25
26 pub driver: Arc<Mutex<Driver>>,
28
29 pub cmp_in_out: CmpInOut<TMsg>,
30}
31
32impl<TMsg, Driver> ADS1115<TMsg, Driver>
33where
34 TMsg: MsgDataBound + 'static,
35 Driver: RsiotI2cDriverBase + 'static,
36{
37 pub async fn spawn(&self) {
38 loop {
39 let mut task_set: JoinSet<Result<(), String>> = JoinSet::new();
40
41 for input in &self.inputs {
42 let driver = self.driver.clone();
43 let input = input.clone();
44 let cmp_in_out = self.cmp_in_out.clone();
45 let task = TaskInput {
46 address: self.address,
47 input,
48 driver,
49 cmp_in_out,
50 };
51 task_set.spawn(async move { task.spawn().await });
52 }
53
54 while let Some(res) = task_set.join_next().await {
55 warn!("ADS1150 stop execution: {:?}", res);
56 task_set.abort_all();
57 }
58
59 sleep(Duration::from_secs(2)).await;
60 }
61 }
62}
63
64fn convert_response_to_voltage(
65 response: &[u8],
66 amplfier: &config::Amplifier,
67) -> Result<f64, String> {
68 let mut rdr = Cursor::new(response);
69 let response = rdr.read_i16::<BigEndian>().unwrap();
70 let max_scale = amplfier.max_value();
71 let volt = response as f64 * max_scale / 32768.0;
72
73 Ok(volt)
74}
75
76struct TaskInput<TMsg, Driver>
77where
78 TMsg: MsgDataBound,
79 Driver: RsiotI2cDriverBase,
80{
81 pub address: I2cSlaveAddress,
82 pub input: config::InputConfig<TMsg>,
83 pub driver: Arc<Mutex<Driver>>,
84 pub cmp_in_out: CmpInOut<TMsg>,
85}
86
87impl<TMsg, Driver> TaskInput<TMsg, Driver>
88where
89 TMsg: MsgDataBound,
90 Driver: RsiotI2cDriverBase,
91{
92 pub async fn spawn(&self) -> Result<(), String> {
93 loop {
94 {
95 let mut driver = self.driver.lock().await;
96
97 let mut request = vec![0x01];
99 request.extend(config::config_to_bytes(
100 &self.input.mux_config,
101 &self.input.amplifier,
102 ));
103
104 let _ = driver
105 .write(self.address, &request, Duration::from_secs(2))
106 .await;
107
108 sleep(Duration::from_millis(10)).await;
109
110 let request = [0x00];
112 let response = driver
113 .write_read(self.address, &request, 2, Duration::from_secs(2))
114 .await
115 .map_err(String::from)?;
116 let volt = convert_response_to_voltage(&response, &self.input.amplifier).unwrap();
117
118 let msg = (self.input.fn_output)(volt);
120 let Some(msg) = msg else { continue };
121 self.cmp_in_out
122 .send_output(msg)
123 .await
124 .map_err(|e| e.to_string())?;
125 }
126
127 sleep(self.input.period).await
128 }
129 }
130}