From a89a0c2f122759a7e743e75152f7af7f67b4387b Mon Sep 17 00:00:00 2001 From: ceekdee Date: Tue, 27 Sep 2022 21:55:41 -0500 Subject: Initial add for sx126x --- examples/nrf/src/bin/lora_p2p_report.rs | 84 ++++++++++++++++ examples/nrf/src/bin/lora_p2p_sense.rs | 173 ++++++++++++++++++++++++++++++++ 2 files changed, 257 insertions(+) create mode 100644 examples/nrf/src/bin/lora_p2p_report.rs create mode 100644 examples/nrf/src/bin/lora_p2p_sense.rs (limited to 'examples/nrf/src/bin') diff --git a/examples/nrf/src/bin/lora_p2p_report.rs b/examples/nrf/src/bin/lora_p2p_report.rs new file mode 100644 index 000000000..46cb848b1 --- /dev/null +++ b/examples/nrf/src/bin/lora_p2p_report.rs @@ -0,0 +1,84 @@ +//! This example runs on the RAK4631 WisBlock, which has an nRF52840 MCU and Semtech Sx126x radio. +#![no_std] +#![no_main] +#![macro_use] +#![allow(dead_code)] +#![feature(type_alias_impl_trait)] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_lora::sx126x::*; +use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pin as _, Pull}; +use embassy_nrf::{interrupt, spim}; +use embassy_time::{Duration, Timer}; +use lorawan_device::async_device::radio::{Bandwidth, CodingRate, PhyRxTx, RfConfig, SpreadingFactor}; +use {defmt_rtt as _, panic_probe as _}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let p = embassy_nrf::init(Default::default()); + let mut spi_config = spim::Config::default(); + spi_config.frequency = spim::Frequency::M1; // M16 ??? + + let mut radio = { + let irq = interrupt::take!(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1); + let spim = spim::Spim::new(p.TWISPI1, irq, p.P1_11, p.P1_13, p.P1_12, spi_config); + + let cs = Output::new(p.P1_10, Level::High, OutputDrive::Standard); + let reset = Output::new(p.P1_06, Level::High, OutputDrive::Standard); + let dio1 = Input::new(p.P1_15.degrade(), Pull::Down); + let busy = Input::new(p.P1_14.degrade(), Pull::Down); + let antenna_rx = Output::new(p.P1_05, Level::Low, OutputDrive::Standard); + let antenna_tx = Output::new(p.P1_07, Level::Low, OutputDrive::Standard); + + match Sx126xRadio::new(spim, cs, reset, antenna_rx, antenna_tx, dio1, busy, false).await { + Ok(r) => r, + Err(err) => { + info!("Sx126xRadio error = {}", err); + return; + } + } + }; + + let mut debug_indicator = Output::new(p.P1_03, Level::Low, OutputDrive::Standard); + let mut start_indicator = Output::new(p.P1_04, Level::Low, OutputDrive::Standard); + + start_indicator.set_high(); + Timer::after(Duration::from_secs(5)).await; + start_indicator.set_low(); + + match radio.lora.sleep().await { + Ok(()) => info!("Sleep successful"), + Err(err) => info!("Sleep unsuccessful = {}", err), + } + + let rf_config = RfConfig { + frequency: 903900000, // channel in Hz + bandwidth: Bandwidth::_250KHz, + spreading_factor: SpreadingFactor::_10, + coding_rate: CodingRate::_4_8, + }; + + let mut buffer = [00u8; 100]; + + // P2P receive + match radio.rx(rf_config, &mut buffer).await { + Ok((buffer_len, rx_quality)) => info!( + "RX received = {:?} with length = {} rssi = {} snr = {}", + &buffer[0..buffer_len], + buffer_len, + rx_quality.rssi(), + rx_quality.snr() + ), + Err(err) => info!("RX error = {}", err), + } + + match radio.lora.sleep().await { + Ok(()) => info!("Sleep successful"), + Err(err) => info!("Sleep unsuccessful = {}", err), + } + + debug_indicator.set_high(); + Timer::after(Duration::from_secs(5)).await; + debug_indicator.set_low(); +} diff --git a/examples/nrf/src/bin/lora_p2p_sense.rs b/examples/nrf/src/bin/lora_p2p_sense.rs new file mode 100644 index 000000000..57aaea665 --- /dev/null +++ b/examples/nrf/src/bin/lora_p2p_sense.rs @@ -0,0 +1,173 @@ +//! This example runs on the RAK4631 WisBlock, which has an nRF52840 MCU and Semtech Sx126x radio. +#![no_std] +#![no_main] +#![macro_use] +#![feature(type_alias_impl_trait)] +#![feature(alloc_error_handler)] +#![allow(incomplete_features)] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_lora::sx126x::*; +use embassy_nrf::gpio::{AnyPin, Input, Level, Output, OutputDrive, Pin as _, Pull}; +use embassy_nrf::temp::Temp; +use embassy_nrf::{interrupt, spim}; +use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; +use embassy_sync::pubsub::{PubSubChannel, Publisher}; +use embassy_time::{Duration, Timer}; +use lorawan_device::async_device::radio::{Bandwidth, CodingRate, PhyRxTx, RfConfig, SpreadingFactor, TxConfig}; +use {defmt_rtt as _, panic_probe as _, panic_probe as _}; + +// Sensor packet constants +const TEMPERATURE_UID: u8 = 0x01; +const MOTION_UID: u8 = 0x02; + +// Message bus: queue of 2, 1 subscriber (Lora P2P), 2 publishers (temperature, motion detection) +static MESSAGE_BUS: PubSubChannel = PubSubChannel::new(); + +#[derive(Clone, defmt::Format)] +enum Message { + Temperature(i32), + MotionDetected, +} + +#[embassy_executor::task] +async fn temperature_task( + mut temperature: Temp<'static>, + publisher: Publisher<'static, CriticalSectionRawMutex, Message, 2, 1, 2>, +) { + Timer::after(Duration::from_secs(45)).await; // stabilize for 45 seconds + + let mut temperature_reporting_threshhold = 10; + + loop { + let value = temperature.read().await; + let mut temperature_val = value.to_num::(); + + info!("Temperature: {}", temperature_val); // debug ??? + + // only report every 2 degree Celsius drops, from 9 through 5, but starting at 3 always report + + if temperature_val == 8 || temperature_val == 6 || temperature_val == 4 { + temperature_val += 1; + } + + if temperature_reporting_threshhold > temperature_val + && (temperature_val == 9 || temperature_val == 7 || temperature_val == 5) + { + temperature_reporting_threshhold = temperature_val; + publisher.publish(Message::Temperature(temperature_val)).await; + } else if temperature_val <= 3 { + publisher.publish(Message::Temperature(temperature_val)).await; + } + + Timer::after(Duration::from_secs(20 * 60)).await; + } +} + +#[embassy_executor::task] +async fn motion_detection_task( + mut pir_pin: Input<'static, AnyPin>, + publisher: Publisher<'static, CriticalSectionRawMutex, Message, 2, 1, 2>, +) { + Timer::after(Duration::from_secs(30)).await; // stabilize for 30 seconds + + loop { + // wait for motion detection + pir_pin.wait_for_low().await; + publisher.publish(Message::MotionDetected).await; + + // wait a minute before setting up for more motion detection + Timer::after(Duration::from_secs(60)).await; + } +} + +#[embassy_executor::main] +async fn main(spawner: Spawner) { + let p = embassy_nrf::init(Default::default()); + // set up to funnel temperature and motion detection events to the Lora Tx task + let mut lora_tx_subscriber = unwrap!(MESSAGE_BUS.subscriber()); + let temperature_publisher = unwrap!(MESSAGE_BUS.publisher()); + let motion_detection_publisher = unwrap!(MESSAGE_BUS.publisher()); + + let mut spi_config = spim::Config::default(); + spi_config.frequency = spim::Frequency::M1; // M16 ??? + + let mut radio = { + let irq = interrupt::take!(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1); + let spim = spim::Spim::new(p.TWISPI1, irq, p.P1_11, p.P1_13, p.P1_12, spi_config); + + let cs = Output::new(p.P1_10, Level::High, OutputDrive::Standard); + let reset = Output::new(p.P1_06, Level::High, OutputDrive::Standard); + let dio1 = Input::new(p.P1_15.degrade(), Pull::Down); + let busy = Input::new(p.P1_14.degrade(), Pull::Down); + let antenna_rx = Output::new(p.P1_05, Level::Low, OutputDrive::Standard); + let antenna_tx = Output::new(p.P1_07, Level::Low, OutputDrive::Standard); + + match Sx126xRadio::new(spim, cs, reset, antenna_rx, antenna_tx, dio1, busy, false).await { + Ok(r) => r, + Err(err) => { + info!("Sx126xRadio error = {}", err); + return; + } + } + }; + + // set up for the temperature task + let temperature_irq = interrupt::take!(TEMP); + let temperature = Temp::new(p.TEMP, temperature_irq); + + // set the motion detection pin + let pir_pin = Input::new(p.P0_10.degrade(), Pull::Up); + + let mut start_indicator = Output::new(p.P1_04, Level::Low, OutputDrive::Standard); + let mut debug_indicator = Output::new(p.P1_03, Level::Low, OutputDrive::Standard); + + start_indicator.set_high(); + Timer::after(Duration::from_secs(5)).await; + start_indicator.set_low(); + + match radio.lora.sleep().await { + Ok(()) => info!("Sleep successful"), + Err(err) => info!("Sleep unsuccessful = {}", err), + } + + unwrap!(spawner.spawn(temperature_task(temperature, temperature_publisher))); + unwrap!(spawner.spawn(motion_detection_task(pir_pin, motion_detection_publisher))); + + loop { + let message = lora_tx_subscriber.next_message_pure().await; + + let tx_config = TxConfig { + // 11 byte maximum payload for Bandwidth 125 and SF 10 + pw: 20, // up to 20 // 5 ??? + rf: RfConfig { + frequency: 903900000, // channel in Hz, not MHz + bandwidth: Bandwidth::_250KHz, + spreading_factor: SpreadingFactor::_10, + coding_rate: CodingRate::_4_8, + }, + }; + + let mut buffer = [TEMPERATURE_UID, 0xffu8, MOTION_UID, 0x00u8]; + match message { + Message::Temperature(temperature) => buffer[1] = temperature as u8, + Message::MotionDetected => buffer[3] = 0x01u8, + }; + + // crypto for text ??? + match radio.tx(tx_config, &buffer).await { + Ok(ret_val) => info!("TX ret_val = {}", ret_val), + Err(err) => info!("TX error = {}", err), + } + + match radio.lora.sleep().await { + Ok(()) => info!("Sleep successful"), + Err(err) => info!("Sleep unsuccessful = {}", err), + } + + debug_indicator.set_high(); + Timer::after(Duration::from_secs(5)).await; + debug_indicator.set_low(); + } +} -- cgit From 526e90d3f3b986fedc55ec421178b7b2ec954abf Mon Sep 17 00:00:00 2001 From: ceekdee Date: Wed, 28 Sep 2022 14:27:34 -0500 Subject: Update some outstanding questions --- examples/nrf/src/bin/lora_p2p_sense.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'examples/nrf/src/bin') diff --git a/examples/nrf/src/bin/lora_p2p_sense.rs b/examples/nrf/src/bin/lora_p2p_sense.rs index 57aaea665..3c6bb8767 100644 --- a/examples/nrf/src/bin/lora_p2p_sense.rs +++ b/examples/nrf/src/bin/lora_p2p_sense.rs @@ -44,7 +44,7 @@ async fn temperature_task( let value = temperature.read().await; let mut temperature_val = value.to_num::(); - info!("Temperature: {}", temperature_val); // debug ??? + info!("Temperature: {}", temperature_val); // only report every 2 degree Celsius drops, from 9 through 5, but starting at 3 always report -- cgit From f554962f54b9f9e8f85a0dd099635619bd1acd1d Mon Sep 17 00:00:00 2001 From: ceekdee Date: Sat, 8 Oct 2022 14:32:22 -0500 Subject: Improve generics and consolidate antenna handling --- examples/nrf/src/bin/lora_p2p_report.rs | 8 ++++---- examples/nrf/src/bin/lora_p2p_sense.rs | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'examples/nrf/src/bin') diff --git a/examples/nrf/src/bin/lora_p2p_report.rs b/examples/nrf/src/bin/lora_p2p_report.rs index 46cb848b1..4ba3d30ce 100644 --- a/examples/nrf/src/bin/lora_p2p_report.rs +++ b/examples/nrf/src/bin/lora_p2p_report.rs @@ -24,12 +24,12 @@ async fn main(_spawner: Spawner) { let irq = interrupt::take!(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1); let spim = spim::Spim::new(p.TWISPI1, irq, p.P1_11, p.P1_13, p.P1_12, spi_config); - let cs = Output::new(p.P1_10, Level::High, OutputDrive::Standard); - let reset = Output::new(p.P1_06, Level::High, OutputDrive::Standard); + let cs = Output::new(p.P1_10.degrade(), Level::High, OutputDrive::Standard); + let reset = Output::new(p.P1_06.degrade(), Level::High, OutputDrive::Standard); let dio1 = Input::new(p.P1_15.degrade(), Pull::Down); let busy = Input::new(p.P1_14.degrade(), Pull::Down); - let antenna_rx = Output::new(p.P1_05, Level::Low, OutputDrive::Standard); - let antenna_tx = Output::new(p.P1_07, Level::Low, OutputDrive::Standard); + let antenna_rx = Output::new(p.P1_05.degrade(), Level::Low, OutputDrive::Standard); + let antenna_tx = Output::new(p.P1_07.degrade(), Level::Low, OutputDrive::Standard); match Sx126xRadio::new(spim, cs, reset, antenna_rx, antenna_tx, dio1, busy, false).await { Ok(r) => r, diff --git a/examples/nrf/src/bin/lora_p2p_sense.rs b/examples/nrf/src/bin/lora_p2p_sense.rs index 3c6bb8767..405a8403f 100644 --- a/examples/nrf/src/bin/lora_p2p_sense.rs +++ b/examples/nrf/src/bin/lora_p2p_sense.rs @@ -97,12 +97,12 @@ async fn main(spawner: Spawner) { let irq = interrupt::take!(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1); let spim = spim::Spim::new(p.TWISPI1, irq, p.P1_11, p.P1_13, p.P1_12, spi_config); - let cs = Output::new(p.P1_10, Level::High, OutputDrive::Standard); - let reset = Output::new(p.P1_06, Level::High, OutputDrive::Standard); + let cs = Output::new(p.P1_10.degrade(), Level::High, OutputDrive::Standard); + let reset = Output::new(p.P1_06.degrade(), Level::High, OutputDrive::Standard); let dio1 = Input::new(p.P1_15.degrade(), Pull::Down); let busy = Input::new(p.P1_14.degrade(), Pull::Down); - let antenna_rx = Output::new(p.P1_05, Level::Low, OutputDrive::Standard); - let antenna_tx = Output::new(p.P1_07, Level::Low, OutputDrive::Standard); + let antenna_rx = Output::new(p.P1_05.degrade(), Level::Low, OutputDrive::Standard); + let antenna_tx = Output::new(p.P1_07.degrade(), Level::Low, OutputDrive::Standard); match Sx126xRadio::new(spim, cs, reset, antenna_rx, antenna_tx, dio1, busy, false).await { Ok(r) => r, -- cgit From e1faf8860776f6ad2bac2f3b06e7160fe00da7df Mon Sep 17 00:00:00 2001 From: huntc Date: Sun, 9 Oct 2022 13:07:25 +1100 Subject: Removes some of the code duplication for UarteWithIdle This commit removes some of the code duplication for UarteWithIdle at the expense of requiring a split. As the example illustrates though, this expense seems worth the benefit in terms of maintenance, and the avoidance of copying over methods. My main motivation for this commit was actually due to the `event_endtx` method not having been copied across. --- examples/nrf/src/bin/uart_idle.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'examples/nrf/src/bin') diff --git a/examples/nrf/src/bin/uart_idle.rs b/examples/nrf/src/bin/uart_idle.rs index 09ec624c0..6af4f7097 100644 --- a/examples/nrf/src/bin/uart_idle.rs +++ b/examples/nrf/src/bin/uart_idle.rs @@ -15,7 +15,8 @@ async fn main(_spawner: Spawner) { config.baudrate = uarte::Baudrate::BAUD115200; let irq = interrupt::take!(UARTE0_UART0); - let mut uart = uarte::UarteWithIdle::new(p.UARTE0, p.TIMER0, p.PPI_CH0, p.PPI_CH1, irq, p.P0_08, p.P0_06, config); + let uart = uarte::Uarte::new(p.UARTE0, irq, p.P0_08, p.P0_06, config); + let (mut tx, mut rx) = uart.split_with_idle(p.TIMER0, p.PPI_CH0, p.PPI_CH1); info!("uarte initialized!"); @@ -23,12 +24,12 @@ async fn main(_spawner: Spawner) { let mut buf = [0; 8]; buf.copy_from_slice(b"Hello!\r\n"); - unwrap!(uart.write(&buf).await); + unwrap!(tx.write(&buf).await); info!("wrote hello in uart!"); loop { info!("reading..."); - let n = unwrap!(uart.read_until_idle(&mut buf).await); + let n = unwrap!(rx.read_until_idle(&mut buf).await); info!("got {} bytes", n); } } -- cgit From 327d3cf0df7a1b116ea7ec44d36a569e6ba6ca16 Mon Sep 17 00:00:00 2001 From: ceekdee Date: Mon, 10 Oct 2022 12:35:42 -0500 Subject: Change rak4631 feature to sx126x, removing use in board-specific processing; simplify the P2P examples; correct RSSI computation. --- examples/nrf/src/bin/lora_p2p_report.rs | 56 ++++++++++------------ examples/nrf/src/bin/lora_p2p_sense.rs | 84 +++++++-------------------------- 2 files changed, 43 insertions(+), 97 deletions(-) (limited to 'examples/nrf/src/bin') diff --git a/examples/nrf/src/bin/lora_p2p_report.rs b/examples/nrf/src/bin/lora_p2p_report.rs index 4ba3d30ce..d512b83f6 100644 --- a/examples/nrf/src/bin/lora_p2p_report.rs +++ b/examples/nrf/src/bin/lora_p2p_report.rs @@ -1,4 +1,6 @@ //! This example runs on the RAK4631 WisBlock, which has an nRF52840 MCU and Semtech Sx126x radio. +//! Other nrf/sx126x combinations may work with appropriate pin modifications. +//! It demonstates LORA P2P functionality in conjunction with example lora_p2p_sense.rs. #![no_std] #![no_main] #![macro_use] @@ -18,7 +20,7 @@ use {defmt_rtt as _, panic_probe as _}; async fn main(_spawner: Spawner) { let p = embassy_nrf::init(Default::default()); let mut spi_config = spim::Config::default(); - spi_config.frequency = spim::Frequency::M1; // M16 ??? + spi_config.frequency = spim::Frequency::M16; let mut radio = { let irq = interrupt::take!(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1); @@ -47,38 +49,30 @@ async fn main(_spawner: Spawner) { Timer::after(Duration::from_secs(5)).await; start_indicator.set_low(); - match radio.lora.sleep().await { - Ok(()) => info!("Sleep successful"), - Err(err) => info!("Sleep unsuccessful = {}", err), - } - - let rf_config = RfConfig { - frequency: 903900000, // channel in Hz - bandwidth: Bandwidth::_250KHz, - spreading_factor: SpreadingFactor::_10, - coding_rate: CodingRate::_4_8, - }; + loop { + let rf_config = RfConfig { + frequency: 903900000, // channel in Hz + bandwidth: Bandwidth::_250KHz, + spreading_factor: SpreadingFactor::_10, + coding_rate: CodingRate::_4_8, + }; - let mut buffer = [00u8; 100]; + let mut buffer = [00u8; 100]; - // P2P receive - match radio.rx(rf_config, &mut buffer).await { - Ok((buffer_len, rx_quality)) => info!( - "RX received = {:?} with length = {} rssi = {} snr = {}", - &buffer[0..buffer_len], - buffer_len, - rx_quality.rssi(), - rx_quality.snr() - ), - Err(err) => info!("RX error = {}", err), - } + // P2P receive + match radio.rx(rf_config, &mut buffer).await { + Ok((buffer_len, rx_quality)) => info!( + "RX received = {:?} with length = {} rssi = {} snr = {}", + &buffer[0..buffer_len], + buffer_len, + rx_quality.rssi(), + rx_quality.snr() + ), + Err(err) => info!("RX error = {}", err), + } - match radio.lora.sleep().await { - Ok(()) => info!("Sleep successful"), - Err(err) => info!("Sleep unsuccessful = {}", err), + debug_indicator.set_high(); + Timer::after(Duration::from_secs(2)).await; + debug_indicator.set_low(); } - - debug_indicator.set_high(); - Timer::after(Duration::from_secs(5)).await; - debug_indicator.set_low(); } diff --git a/examples/nrf/src/bin/lora_p2p_sense.rs b/examples/nrf/src/bin/lora_p2p_sense.rs index 405a8403f..b9768874b 100644 --- a/examples/nrf/src/bin/lora_p2p_sense.rs +++ b/examples/nrf/src/bin/lora_p2p_sense.rs @@ -1,4 +1,6 @@ //! This example runs on the RAK4631 WisBlock, which has an nRF52840 MCU and Semtech Sx126x radio. +//! Other nrf/sx126x combinations may work with appropriate pin modifications. +//! It demonstates LORA P2P functionality in conjunction with example lora_p2p_report.rs. #![no_std] #![no_main] #![macro_use] @@ -9,8 +11,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_lora::sx126x::*; -use embassy_nrf::gpio::{AnyPin, Input, Level, Output, OutputDrive, Pin as _, Pull}; -use embassy_nrf::temp::Temp; +use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pin as _, Pull}; use embassy_nrf::{interrupt, spim}; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::pubsub::{PubSubChannel, Publisher}; @@ -18,10 +19,6 @@ use embassy_time::{Duration, Timer}; use lorawan_device::async_device::radio::{Bandwidth, CodingRate, PhyRxTx, RfConfig, SpreadingFactor, TxConfig}; use {defmt_rtt as _, panic_probe as _, panic_probe as _}; -// Sensor packet constants -const TEMPERATURE_UID: u8 = 0x01; -const MOTION_UID: u8 = 0x02; - // Message bus: queue of 2, 1 subscriber (Lora P2P), 2 publishers (temperature, motion detection) static MESSAGE_BUS: PubSubChannel = PubSubChannel::new(); @@ -32,53 +29,20 @@ enum Message { } #[embassy_executor::task] -async fn temperature_task( - mut temperature: Temp<'static>, - publisher: Publisher<'static, CriticalSectionRawMutex, Message, 2, 1, 2>, -) { - Timer::after(Duration::from_secs(45)).await; // stabilize for 45 seconds - - let mut temperature_reporting_threshhold = 10; - +async fn temperature_task(publisher: Publisher<'static, CriticalSectionRawMutex, Message, 2, 1, 2>) { + // Publish a fake temperature every 43 seconds, minimizing LORA traffic. loop { - let value = temperature.read().await; - let mut temperature_val = value.to_num::(); - - info!("Temperature: {}", temperature_val); - - // only report every 2 degree Celsius drops, from 9 through 5, but starting at 3 always report - - if temperature_val == 8 || temperature_val == 6 || temperature_val == 4 { - temperature_val += 1; - } - - if temperature_reporting_threshhold > temperature_val - && (temperature_val == 9 || temperature_val == 7 || temperature_val == 5) - { - temperature_reporting_threshhold = temperature_val; - publisher.publish(Message::Temperature(temperature_val)).await; - } else if temperature_val <= 3 { - publisher.publish(Message::Temperature(temperature_val)).await; - } - - Timer::after(Duration::from_secs(20 * 60)).await; + Timer::after(Duration::from_secs(43)).await; + publisher.publish(Message::Temperature(9)).await; } } #[embassy_executor::task] -async fn motion_detection_task( - mut pir_pin: Input<'static, AnyPin>, - publisher: Publisher<'static, CriticalSectionRawMutex, Message, 2, 1, 2>, -) { - Timer::after(Duration::from_secs(30)).await; // stabilize for 30 seconds - +async fn motion_detection_task(publisher: Publisher<'static, CriticalSectionRawMutex, Message, 2, 1, 2>) { + // Publish a fake motion detection every 79 seconds, minimizing LORA traffic. loop { - // wait for motion detection - pir_pin.wait_for_low().await; + Timer::after(Duration::from_secs(79)).await; publisher.publish(Message::MotionDetected).await; - - // wait a minute before setting up for more motion detection - Timer::after(Duration::from_secs(60)).await; } } @@ -91,7 +55,7 @@ async fn main(spawner: Spawner) { let motion_detection_publisher = unwrap!(MESSAGE_BUS.publisher()); let mut spi_config = spim::Config::default(); - spi_config.frequency = spim::Frequency::M1; // M16 ??? + spi_config.frequency = spim::Frequency::M16; let mut radio = { let irq = interrupt::take!(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1); @@ -113,15 +77,7 @@ async fn main(spawner: Spawner) { } }; - // set up for the temperature task - let temperature_irq = interrupt::take!(TEMP); - let temperature = Temp::new(p.TEMP, temperature_irq); - - // set the motion detection pin - let pir_pin = Input::new(p.P0_10.degrade(), Pull::Up); - let mut start_indicator = Output::new(p.P1_04, Level::Low, OutputDrive::Standard); - let mut debug_indicator = Output::new(p.P1_03, Level::Low, OutputDrive::Standard); start_indicator.set_high(); Timer::after(Duration::from_secs(5)).await; @@ -132,15 +88,15 @@ async fn main(spawner: Spawner) { Err(err) => info!("Sleep unsuccessful = {}", err), } - unwrap!(spawner.spawn(temperature_task(temperature, temperature_publisher))); - unwrap!(spawner.spawn(motion_detection_task(pir_pin, motion_detection_publisher))); + unwrap!(spawner.spawn(temperature_task(temperature_publisher))); + unwrap!(spawner.spawn(motion_detection_task(motion_detection_publisher))); loop { let message = lora_tx_subscriber.next_message_pure().await; let tx_config = TxConfig { // 11 byte maximum payload for Bandwidth 125 and SF 10 - pw: 20, // up to 20 // 5 ??? + pw: 10, // up to 20 rf: RfConfig { frequency: 903900000, // channel in Hz, not MHz bandwidth: Bandwidth::_250KHz, @@ -149,13 +105,13 @@ async fn main(spawner: Spawner) { }, }; - let mut buffer = [TEMPERATURE_UID, 0xffu8, MOTION_UID, 0x00u8]; + let mut buffer = [0x00u8]; match message { - Message::Temperature(temperature) => buffer[1] = temperature as u8, - Message::MotionDetected => buffer[3] = 0x01u8, + Message::Temperature(temperature) => buffer[0] = temperature as u8, + Message::MotionDetected => buffer[0] = 0x01u8, }; - // crypto for text ??? + // unencrypted match radio.tx(tx_config, &buffer).await { Ok(ret_val) => info!("TX ret_val = {}", ret_val), Err(err) => info!("TX error = {}", err), @@ -165,9 +121,5 @@ async fn main(spawner: Spawner) { Ok(()) => info!("Sleep successful"), Err(err) => info!("Sleep unsuccessful = {}", err), } - - debug_indicator.set_high(); - Timer::after(Duration::from_secs(5)).await; - debug_indicator.set_low(); } } -- cgit From a4afab46403aacd7bb555cadaefad7f216fb9931 Mon Sep 17 00:00:00 2001 From: pbert Date: Sun, 10 Jul 2022 20:12:25 +0200 Subject: add support for pdm microphones in nrf driver --- examples/nrf/src/bin/pdm.rs | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 examples/nrf/src/bin/pdm.rs (limited to 'examples/nrf/src/bin') diff --git a/examples/nrf/src/bin/pdm.rs b/examples/nrf/src/bin/pdm.rs new file mode 100644 index 000000000..7388580fb --- /dev/null +++ b/examples/nrf/src/bin/pdm.rs @@ -0,0 +1,33 @@ +#![no_std] +#![no_main] +#![feature(type_alias_impl_trait)] + +use defmt::info; +use embassy_executor::Spawner; +use embassy_nrf::interrupt; +use embassy_nrf::pdm::{Config, Pdm}; +use embassy_time::{Duration, Timer}; +use {defmt_rtt as _, panic_probe as _}; + +#[embassy_executor::main] +async fn main(_p: Spawner) { + let p = embassy_nrf::init(Default::default()); + let config = Config::default(); + let mut pdm = Pdm::new(p.PDM, interrupt::take!(PDM), p.P0_01, p.P0_00, config); + + loop { + pdm.start().await; + + // wait some time till the microphon settled + Timer::after(Duration::from_millis(1000)).await; + + const SAMPLES: usize = 2048; + let mut buf = [0i16; SAMPLES]; + pdm.sample(&mut buf).await.unwrap(); + + info!("samples: {:?}", &buf); + + pdm.stop().await; + Timer::after(Duration::from_millis(100)).await; + } +} -- cgit