aboutsummaryrefslogtreecommitdiff
path: root/examples/nrf
diff options
context:
space:
mode:
authorceekdee <[email protected]>2022-10-10 12:35:42 -0500
committerceekdee <[email protected]>2022-10-10 12:35:42 -0500
commit327d3cf0df7a1b116ea7ec44d36a569e6ba6ca16 (patch)
tree67c69a2d511ba9dee2def2f7858e859d8150559b /examples/nrf
parent79ba20d315f456ac525daf4c3d5dd0d2ce92ad2b (diff)
Change rak4631 feature to sx126x, removing use in board-specific processing; simplify the P2P examples; correct RSSI computation.
Diffstat (limited to 'examples/nrf')
-rw-r--r--examples/nrf/Cargo.toml2
-rw-r--r--examples/nrf/src/bin/lora_p2p_report.rs56
-rw-r--r--examples/nrf/src/bin/lora_p2p_sense.rs84
3 files changed, 44 insertions, 98 deletions
diff --git a/examples/nrf/Cargo.toml b/examples/nrf/Cargo.toml
index 91c418213..6949042e2 100644
--- a/examples/nrf/Cargo.toml
+++ b/examples/nrf/Cargo.toml
@@ -18,7 +18,7 @@ embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defm
18embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "pool-16"], optional = true } 18embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "pool-16"], optional = true }
19embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"], optional = true } 19embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"], optional = true }
20embedded-io = "0.3.0" 20embedded-io = "0.3.0"
21embassy-lora = { version = "0.1.0", path = "../../embassy-lora", features = ["rak4631", "time", "defmt"], optional = true } 21embassy-lora = { version = "0.1.0", path = "../../embassy-lora", features = ["sx126x", "time", "defmt"], optional = true }
22 22
23lorawan-device = { version = "0.8.0", default-features = false, features = ["async"], optional = true } 23lorawan-device = { version = "0.8.0", default-features = false, features = ["async"], optional = true }
24lorawan = { version = "0.7.1", default-features = false, features = ["default-crypto"], optional = true } 24lorawan = { version = "0.7.1", default-features = false, features = ["default-crypto"], optional = true }
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 @@
1//! This example runs on the RAK4631 WisBlock, which has an nRF52840 MCU and Semtech Sx126x radio. 1//! This example runs on the RAK4631 WisBlock, which has an nRF52840 MCU and Semtech Sx126x radio.
2//! Other nrf/sx126x combinations may work with appropriate pin modifications.
3//! It demonstates LORA P2P functionality in conjunction with example lora_p2p_sense.rs.
2#![no_std] 4#![no_std]
3#![no_main] 5#![no_main]
4#![macro_use] 6#![macro_use]
@@ -18,7 +20,7 @@ use {defmt_rtt as _, panic_probe as _};
18async fn main(_spawner: Spawner) { 20async fn main(_spawner: Spawner) {
19 let p = embassy_nrf::init(Default::default()); 21 let p = embassy_nrf::init(Default::default());
20 let mut spi_config = spim::Config::default(); 22 let mut spi_config = spim::Config::default();
21 spi_config.frequency = spim::Frequency::M1; // M16 ??? 23 spi_config.frequency = spim::Frequency::M16;
22 24
23 let mut radio = { 25 let mut radio = {
24 let irq = interrupt::take!(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1); 26 let irq = interrupt::take!(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1);
@@ -47,38 +49,30 @@ async fn main(_spawner: Spawner) {
47 Timer::after(Duration::from_secs(5)).await; 49 Timer::after(Duration::from_secs(5)).await;
48 start_indicator.set_low(); 50 start_indicator.set_low();
49 51
50 match radio.lora.sleep().await { 52 loop {
51 Ok(()) => info!("Sleep successful"), 53 let rf_config = RfConfig {
52 Err(err) => info!("Sleep unsuccessful = {}", err), 54 frequency: 903900000, // channel in Hz
53 } 55 bandwidth: Bandwidth::_250KHz,
54 56 spreading_factor: SpreadingFactor::_10,
55 let rf_config = RfConfig { 57 coding_rate: CodingRate::_4_8,
56 frequency: 903900000, // channel in Hz 58 };
57 bandwidth: Bandwidth::_250KHz,
58 spreading_factor: SpreadingFactor::_10,
59 coding_rate: CodingRate::_4_8,
60 };
61 59
62 let mut buffer = [00u8; 100]; 60 let mut buffer = [00u8; 100];
63 61
64 // P2P receive 62 // P2P receive
65 match radio.rx(rf_config, &mut buffer).await { 63 match radio.rx(rf_config, &mut buffer).await {
66 Ok((buffer_len, rx_quality)) => info!( 64 Ok((buffer_len, rx_quality)) => info!(
67 "RX received = {:?} with length = {} rssi = {} snr = {}", 65 "RX received = {:?} with length = {} rssi = {} snr = {}",
68 &buffer[0..buffer_len], 66 &buffer[0..buffer_len],
69 buffer_len, 67 buffer_len,
70 rx_quality.rssi(), 68 rx_quality.rssi(),
71 rx_quality.snr() 69 rx_quality.snr()
72 ), 70 ),
73 Err(err) => info!("RX error = {}", err), 71 Err(err) => info!("RX error = {}", err),
74 } 72 }
75 73
76 match radio.lora.sleep().await { 74 debug_indicator.set_high();
77 Ok(()) => info!("Sleep successful"), 75 Timer::after(Duration::from_secs(2)).await;
78 Err(err) => info!("Sleep unsuccessful = {}", err), 76 debug_indicator.set_low();
79 } 77 }
80
81 debug_indicator.set_high();
82 Timer::after(Duration::from_secs(5)).await;
83 debug_indicator.set_low();
84} 78}
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 @@
1//! This example runs on the RAK4631 WisBlock, which has an nRF52840 MCU and Semtech Sx126x radio. 1//! This example runs on the RAK4631 WisBlock, which has an nRF52840 MCU and Semtech Sx126x radio.
2//! Other nrf/sx126x combinations may work with appropriate pin modifications.
3//! It demonstates LORA P2P functionality in conjunction with example lora_p2p_report.rs.
2#![no_std] 4#![no_std]
3#![no_main] 5#![no_main]
4#![macro_use] 6#![macro_use]
@@ -9,8 +11,7 @@
9use defmt::*; 11use defmt::*;
10use embassy_executor::Spawner; 12use embassy_executor::Spawner;
11use embassy_lora::sx126x::*; 13use embassy_lora::sx126x::*;
12use embassy_nrf::gpio::{AnyPin, Input, Level, Output, OutputDrive, Pin as _, Pull}; 14use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pin as _, Pull};
13use embassy_nrf::temp::Temp;
14use embassy_nrf::{interrupt, spim}; 15use embassy_nrf::{interrupt, spim};
15use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; 16use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
16use embassy_sync::pubsub::{PubSubChannel, Publisher}; 17use embassy_sync::pubsub::{PubSubChannel, Publisher};
@@ -18,10 +19,6 @@ use embassy_time::{Duration, Timer};
18use lorawan_device::async_device::radio::{Bandwidth, CodingRate, PhyRxTx, RfConfig, SpreadingFactor, TxConfig}; 19use lorawan_device::async_device::radio::{Bandwidth, CodingRate, PhyRxTx, RfConfig, SpreadingFactor, TxConfig};
19use {defmt_rtt as _, panic_probe as _, panic_probe as _}; 20use {defmt_rtt as _, panic_probe as _, panic_probe as _};
20 21
21// Sensor packet constants
22const TEMPERATURE_UID: u8 = 0x01;
23const MOTION_UID: u8 = 0x02;
24
25// Message bus: queue of 2, 1 subscriber (Lora P2P), 2 publishers (temperature, motion detection) 22// Message bus: queue of 2, 1 subscriber (Lora P2P), 2 publishers (temperature, motion detection)
26static MESSAGE_BUS: PubSubChannel<CriticalSectionRawMutex, Message, 2, 1, 2> = PubSubChannel::new(); 23static MESSAGE_BUS: PubSubChannel<CriticalSectionRawMutex, Message, 2, 1, 2> = PubSubChannel::new();
27 24
@@ -32,53 +29,20 @@ enum Message {
32} 29}
33 30
34#[embassy_executor::task] 31#[embassy_executor::task]
35async fn temperature_task( 32async fn temperature_task(publisher: Publisher<'static, CriticalSectionRawMutex, Message, 2, 1, 2>) {
36 mut temperature: Temp<'static>, 33 // Publish a fake temperature every 43 seconds, minimizing LORA traffic.
37 publisher: Publisher<'static, CriticalSectionRawMutex, Message, 2, 1, 2>,
38) {
39 Timer::after(Duration::from_secs(45)).await; // stabilize for 45 seconds
40
41 let mut temperature_reporting_threshhold = 10;
42
43 loop { 34 loop {
44 let value = temperature.read().await; 35 Timer::after(Duration::from_secs(43)).await;
45 let mut temperature_val = value.to_num::<i32>(); 36 publisher.publish(Message::Temperature(9)).await;
46
47 info!("Temperature: {}", temperature_val);
48
49 // only report every 2 degree Celsius drops, from 9 through 5, but starting at 3 always report
50
51 if temperature_val == 8 || temperature_val == 6 || temperature_val == 4 {
52 temperature_val += 1;
53 }
54
55 if temperature_reporting_threshhold > temperature_val
56 && (temperature_val == 9 || temperature_val == 7 || temperature_val == 5)
57 {
58 temperature_reporting_threshhold = temperature_val;
59 publisher.publish(Message::Temperature(temperature_val)).await;
60 } else if temperature_val <= 3 {
61 publisher.publish(Message::Temperature(temperature_val)).await;
62 }
63
64 Timer::after(Duration::from_secs(20 * 60)).await;
65 } 37 }
66} 38}
67 39
68#[embassy_executor::task] 40#[embassy_executor::task]
69async fn motion_detection_task( 41async fn motion_detection_task(publisher: Publisher<'static, CriticalSectionRawMutex, Message, 2, 1, 2>) {
70 mut pir_pin: Input<'static, AnyPin>, 42 // Publish a fake motion detection every 79 seconds, minimizing LORA traffic.
71 publisher: Publisher<'static, CriticalSectionRawMutex, Message, 2, 1, 2>,
72) {
73 Timer::after(Duration::from_secs(30)).await; // stabilize for 30 seconds
74
75 loop { 43 loop {
76 // wait for motion detection 44 Timer::after(Duration::from_secs(79)).await;
77 pir_pin.wait_for_low().await;
78 publisher.publish(Message::MotionDetected).await; 45 publisher.publish(Message::MotionDetected).await;
79
80 // wait a minute before setting up for more motion detection
81 Timer::after(Duration::from_secs(60)).await;
82 } 46 }
83} 47}
84 48
@@ -91,7 +55,7 @@ async fn main(spawner: Spawner) {
91 let motion_detection_publisher = unwrap!(MESSAGE_BUS.publisher()); 55 let motion_detection_publisher = unwrap!(MESSAGE_BUS.publisher());
92 56
93 let mut spi_config = spim::Config::default(); 57 let mut spi_config = spim::Config::default();
94 spi_config.frequency = spim::Frequency::M1; // M16 ??? 58 spi_config.frequency = spim::Frequency::M16;
95 59
96 let mut radio = { 60 let mut radio = {
97 let irq = interrupt::take!(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1); 61 let irq = interrupt::take!(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1);
@@ -113,15 +77,7 @@ async fn main(spawner: Spawner) {
113 } 77 }
114 }; 78 };
115 79
116 // set up for the temperature task
117 let temperature_irq = interrupt::take!(TEMP);
118 let temperature = Temp::new(p.TEMP, temperature_irq);
119
120 // set the motion detection pin
121 let pir_pin = Input::new(p.P0_10.degrade(), Pull::Up);
122
123 let mut start_indicator = Output::new(p.P1_04, Level::Low, OutputDrive::Standard); 80 let mut start_indicator = Output::new(p.P1_04, Level::Low, OutputDrive::Standard);
124 let mut debug_indicator = Output::new(p.P1_03, Level::Low, OutputDrive::Standard);
125 81
126 start_indicator.set_high(); 82 start_indicator.set_high();
127 Timer::after(Duration::from_secs(5)).await; 83 Timer::after(Duration::from_secs(5)).await;
@@ -132,15 +88,15 @@ async fn main(spawner: Spawner) {
132 Err(err) => info!("Sleep unsuccessful = {}", err), 88 Err(err) => info!("Sleep unsuccessful = {}", err),
133 } 89 }
134 90
135 unwrap!(spawner.spawn(temperature_task(temperature, temperature_publisher))); 91 unwrap!(spawner.spawn(temperature_task(temperature_publisher)));
136 unwrap!(spawner.spawn(motion_detection_task(pir_pin, motion_detection_publisher))); 92 unwrap!(spawner.spawn(motion_detection_task(motion_detection_publisher)));
137 93
138 loop { 94 loop {
139 let message = lora_tx_subscriber.next_message_pure().await; 95 let message = lora_tx_subscriber.next_message_pure().await;
140 96
141 let tx_config = TxConfig { 97 let tx_config = TxConfig {
142 // 11 byte maximum payload for Bandwidth 125 and SF 10 98 // 11 byte maximum payload for Bandwidth 125 and SF 10
143 pw: 20, // up to 20 // 5 ??? 99 pw: 10, // up to 20
144 rf: RfConfig { 100 rf: RfConfig {
145 frequency: 903900000, // channel in Hz, not MHz 101 frequency: 903900000, // channel in Hz, not MHz
146 bandwidth: Bandwidth::_250KHz, 102 bandwidth: Bandwidth::_250KHz,
@@ -149,13 +105,13 @@ async fn main(spawner: Spawner) {
149 }, 105 },
150 }; 106 };
151 107
152 let mut buffer = [TEMPERATURE_UID, 0xffu8, MOTION_UID, 0x00u8]; 108 let mut buffer = [0x00u8];
153 match message { 109 match message {
154 Message::Temperature(temperature) => buffer[1] = temperature as u8, 110 Message::Temperature(temperature) => buffer[0] = temperature as u8,
155 Message::MotionDetected => buffer[3] = 0x01u8, 111 Message::MotionDetected => buffer[0] = 0x01u8,
156 }; 112 };
157 113
158 // crypto for text ??? 114 // unencrypted
159 match radio.tx(tx_config, &buffer).await { 115 match radio.tx(tx_config, &buffer).await {
160 Ok(ret_val) => info!("TX ret_val = {}", ret_val), 116 Ok(ret_val) => info!("TX ret_val = {}", ret_val),
161 Err(err) => info!("TX error = {}", err), 117 Err(err) => info!("TX error = {}", err),
@@ -165,9 +121,5 @@ async fn main(spawner: Spawner) {
165 Ok(()) => info!("Sleep successful"), 121 Ok(()) => info!("Sleep successful"),
166 Err(err) => info!("Sleep unsuccessful = {}", err), 122 Err(err) => info!("Sleep unsuccessful = {}", err),
167 } 123 }
168
169 debug_indicator.set_high();
170 Timer::after(Duration::from_secs(5)).await;
171 debug_indicator.set_low();
172 } 124 }
173} 125}