A RPi Pico powered Lightning Detector
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: Abstract UpdateConnection state

+47 -35
+9 -22
src/detector.rs
··· 19 19 constants::BLOCK_SIZE, 20 20 pwm::PwmDriver, 21 21 rtc::GlobalRtc, 22 - state::{DEVICE_STATE, DeviceState}, 23 - updates::{NET_CHANNEL, NetDataSender}, 22 + updates::UpdateConnection, 24 23 utils::{static_alloc, try_buffer, try_static_timestamped_block_vecs}, 25 24 }; 26 25 ··· 34 33 while !rtc.is_running().await { 35 34 Timer::after_secs(2).await; 36 35 } 37 - let net_data = NET_CHANNEL.sender(); 36 + 38 37 info!("Allocating detector resources"); 39 38 40 39 let blocks = unwrap!( ··· 47 46 48 47 let (mut sender, mut receiver) = buf_channel.split(); 49 48 50 - let mut detector = Detector::new(adc, pwm, net_data); 49 + let mut detector = Detector::new(adc, pwm); 51 50 let mut samples = unwrap!(try_buffer(64), "Failed to allocate sample buffer"); 52 51 let mut peaks = Vec::new(); 53 52 ··· 72 71 adc: AdcDriver<'device, NoopRawMutex, DMA_CH1>, 73 72 pwm: PwmDriver<'device>, 74 73 state: DetectorState, 75 - net_data: NetDataSender, 76 74 } 77 75 78 76 #[derive(Debug)] ··· 91 89 } 92 90 93 91 impl<'device> Detector<'device> { 94 - fn new( 95 - adc: AdcDriver<'device, NoopRawMutex, DMA_CH1>, 96 - mut pwm: PwmDriver<'device>, 97 - net_data: NetDataSender, 98 - ) -> Self { 92 + fn new(adc: AdcDriver<'device, NoopRawMutex, DMA_CH1>, mut pwm: PwmDriver<'device>) -> Self { 99 93 pwm.enable(); 100 94 101 95 Self { 102 96 adc, 103 97 pwm, 104 - net_data, 105 98 state: DetectorState::default(), 106 99 } 107 100 } ··· 175 168 if blips > 0 { 176 169 self.state 177 170 .strikes 178 - .set(self.state.strikes.get().saturating_add(32)); 171 + .update(|strike| strike.saturating_add(32)); 179 172 180 - if let Some(net_data) = self.get_data_channel() { 173 + if let Some(net_data) = UpdateConnection::can_update() { 181 174 data::transmit_strike( 182 175 *timestamp, 183 176 buf.as_slice(), 184 177 peaks.as_slice(), 185 178 average, 186 - net_data, 179 + &net_data, 187 180 ); 188 181 } 189 182 ··· 230 223 inactive = Some(Instant::now()); 231 224 } 232 225 None => { 233 - if let Some(net_data) = self.get_data_channel() { 226 + if let Some(net_data) = UpdateConnection::can_update() { 234 227 let now = rtc.get_timestamp().await; 235 - data::transmit_level_update(now.timestamp(), decay, net_data); 228 + data::transmit_level_update(now.timestamp(), decay, &net_data); 236 229 } 237 230 } 238 231 _ => continue, 239 232 } 240 233 } 241 - } 242 - 243 - fn get_data_channel(&self) -> Option<&NetDataSender> { 244 - DEVICE_STATE 245 - .lock(|x| x.get() == DeviceState::Connected) 246 - .then_some(&self.net_data) 247 234 } 248 235 }
-1
src/errors.rs
··· 2 2 use embassy_rp::rtc::RtcError; 3 3 use sachy_sntp::SntpError; 4 4 5 - 6 5 #[derive(Debug)] 7 6 #[cfg_attr(feature = "defmt", derive(defmt::Format))] 8 7 pub enum PicoError {
+9 -10
src/net.rs
··· 13 13 use crate::{ 14 14 constants::{HOST_NAME, HOST_PORT}, 15 15 rtc::GlobalRtc, 16 - state::DEVICE_STATE, 17 - updates::{NET_CHANNEL, NetDataReceiver}, 16 + updates::UpdateConnection, 18 17 }; 19 18 20 19 #[embassy_executor::task] ··· 102 101 103 102 select(stack.wait_link_down(), data_loop(&mut tcp)).await; 104 103 105 - DEVICE_STATE.lock(|state| state.set(crate::state::DeviceState::Disconnected)); 104 + UpdateConnection::disconnect(); 106 105 } 107 106 108 107 async fn data_loop<'connection>(tcp: &mut TcpSocket<'connection>) { 109 108 let mut buffer: Vec<u8> = vec![0u8; 2048]; 110 - let net_data: NetDataReceiver = NET_CHANNEL.receiver(); 109 + let net_data = UpdateConnection::get_receiver(); 111 110 112 - 'outer: loop { 113 - DEVICE_STATE.lock(|state| state.set(crate::state::DeviceState::Disconnected)); 111 + loop { 112 + UpdateConnection::disconnect(); 114 113 115 114 if tcp.accept(HOST_PORT).await.is_err() { 116 115 continue; 117 116 } 118 117 119 - DEVICE_STATE.lock(|state| state.set(crate::state::DeviceState::Connected)); 118 + UpdateConnection::connect(); 120 119 121 - loop { 120 + 'inner: loop { 122 121 let data = net_data.receive().await; 123 122 124 123 if let Ok(written) = postcard::to_slice(&data, &mut buffer) 125 124 && let Err(_) = tcp.write(written).await 126 125 { 127 - continue 'outer; 126 + break 'inner; 128 127 } 129 128 130 129 if tcp.flush().await.is_err() { 131 - continue 'outer; 130 + break 'inner; 132 131 } 133 132 } 134 133 }
+29 -2
src/updates.rs
··· 2 2 3 3 use embassy_sync::channel::{Channel, Receiver, Sender}; 4 4 5 - use crate::locks::NetDataLock; 5 + use crate::{ 6 + locks::NetDataLock, 7 + state::{DEVICE_STATE, DeviceState}, 8 + }; 6 9 7 10 pub type NetDataChannel = Channel<NetDataLock, Update, 8>; 8 11 pub type NetDataSender = Sender<'static, NetDataLock, Update, 8>; ··· 22 25 }, 23 26 } 24 27 25 - pub static NET_CHANNEL: NetDataChannel = Channel::new(); 28 + static NET_CHANNEL: NetDataChannel = Channel::new(); 29 + 30 + pub struct UpdateConnection; 31 + 32 + impl UpdateConnection { 33 + pub fn disconnect() { 34 + DEVICE_STATE.lock(|state| state.set(DeviceState::Disconnected)); 35 + } 36 + 37 + pub fn connect() { 38 + DEVICE_STATE.lock(|state| state.set(DeviceState::Connected)); 39 + } 40 + 41 + pub fn is_connected() -> bool { 42 + DEVICE_STATE.lock(|state| state.get() == DeviceState::Connected) 43 + } 44 + 45 + pub fn get_receiver() -> NetDataReceiver { 46 + NET_CHANNEL.receiver() 47 + } 48 + 49 + pub fn can_update() -> Option<NetDataSender> { 50 + Self::is_connected().then(|| NET_CHANNEL.sender()) 51 + } 52 + }