diff --git a/examples/STM32WLx/STM32WLx_Channel_Activity_Detection/STM32WLx_Channel_Activity_Detection.ino b/examples/STM32WLx/STM32WLx_Channel_Activity_Detection/STM32WLx_Channel_Activity_Detection.ino new file mode 100644 index 00000000..ef511dc8 --- /dev/null +++ b/examples/STM32WLx/STM32WLx_Channel_Activity_Detection/STM32WLx_Channel_Activity_Detection.ino @@ -0,0 +1,61 @@ +/* + RadioLib STM32WLx Channel Activity Detection Example + + This example uses STM32WLx to scan the current LoRa + channel and detect ongoing LoRa transmissions. + Unlike SX127x CAD, SX126x/STM32WLx can detect any part + of LoRa transmission, not just the preamble. + + For default module settings, see the wiki page + https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lora-modem + + For full API reference, see the GitHub Pages + https://jgromes.github.io/RadioLib/ +*/ + +// include the library +#include + +// no need to configure pins, signals are routed to the radio internally +STM32WLx radio = new STM32WLx_Module(); + + +void setup() { + Serial.begin(9600); + + // initialize STM32WLx with default settings + Serial.print(F("[STM32WLx] Initializing ... ")); + int state = radio.begin(868.0); + if (state == RADIOLIB_ERR_NONE) { + Serial.println(F("success!")); + } else { + Serial.print(F("failed, code ")); + Serial.println(state); + while (true); + } +} + +void loop() { + Serial.print(F("[STM32WLx] Scanning channel for LoRa transmission ... ")); + + // start scanning current channel + int state = radio.scanChannel(); + + if (state == RADIOLIB_LORA_DETECTED) { + // LoRa preamble was detected + Serial.println(F("detected!")); + + } else if (state == RADIOLIB_CHANNEL_FREE) { + // no preamble was detected, channel is free + Serial.println(F("channel is free!")); + + } else { + // some other error occurred + Serial.print(F("failed, code ")); + Serial.println(state); + + } + + // wait 100 ms before new scan + delay(100); +} diff --git a/examples/STM32WLx/STM32WLx_Channel_Activity_Detection_Interrupt/STM32WLx_Channel_Activity_Detection_Interrupt.ino b/examples/STM32WLx/STM32WLx_Channel_Activity_Detection_Interrupt/STM32WLx_Channel_Activity_Detection_Interrupt.ino new file mode 100644 index 00000000..374a41f1 --- /dev/null +++ b/examples/STM32WLx/STM32WLx_Channel_Activity_Detection_Interrupt/STM32WLx_Channel_Activity_Detection_Interrupt.ino @@ -0,0 +1,98 @@ +/* + RadioLib STM32WLx Channel Activity Detection Example + + This example uses STM32WLx to scan the current LoRa + channel and detect ongoing LoRa transmissions. + Unlike SX127x CAD, SX126x/STM32WLx can detect any part + of LoRa transmission, not just the preamble. + + For default module settings, see the wiki page + https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lora-modem + + For full API reference, see the GitHub Pages + https://jgromes.github.io/RadioLib/ +*/ + +// include the library +#include + +// no need to configure pins, signals are routed to the radio internally +STM32WLx radio = new STM32WLx_Module(); + + +void setup() { + Serial.begin(9600); + + // initialize STM32WLx with default settings + Serial.print(F("[STM32WLx] Initializing ... ")); + int state = radio.begin(868.0); + if (state == RADIOLIB_ERR_NONE) { + Serial.println(F("success!")); + } else { + Serial.print(F("failed, code ")); + Serial.println(state); + while (true); + } + + // set the function that will be called + // when LoRa packet or timeout is detected + radio.setDio1Action(setFlag); + + // start scanning the channel + Serial.print(F("[STM32WLx] Starting scan for LoRa preamble ... ")); + state = radio.startChannelScan(); + if (state == RADIOLIB_ERR_NONE) { + Serial.println(F("success!")); + } else { + Serial.print(F("failed, code ")); + Serial.println(state); + } +} + +// flag to indicate that a packet was detected or CAD timed out +volatile bool scanFlag = false; + +// this function is called when a complete packet +// is received by the module +// IMPORTANT: this function MUST be 'void' type +// and MUST NOT have any arguments! +void setFlag(void) { + // something happened, set the flag + scanFlag = true; +} + +void loop() { + // check if the flag is set + if(scanFlag) { + // reset flag + scanFlag = false; + + // check CAD result + int state = radio.getChannelScanResult(); + + if (state == RADIOLIB_LORA_DETECTED) { + // LoRa packet was detected + Serial.println(F("[STM32WLx] Packet detected!")); + + } else if (state == RADIOLIB_CHANNEL_FREE) { + // channel is free + Serial.println(F("[STM32WLx] Channel is free!")); + + } else { + // some other error occurred + Serial.print(F("[STM32WLx] Failed, code ")); + Serial.println(state); + + } + + // start scanning the channel again + Serial.print(F("[STM32WLx] Starting scan for LoRa preamble ... ")); + state = radio.startChannelScan(); + if (state == RADIOLIB_ERR_NONE) { + Serial.println(F("success!")); + } else { + Serial.print(F("failed, code ")); + Serial.println(state); + } + } +} diff --git a/examples/STM32WLx/STM32WLx_Receive/STM32WLx_Receive.ino b/examples/STM32WLx/STM32WLx_Receive/STM32WLx_Receive.ino new file mode 100644 index 00000000..b645affe --- /dev/null +++ b/examples/STM32WLx/STM32WLx_Receive/STM32WLx_Receive.ino @@ -0,0 +1,124 @@ +/* + RadioLib STM32WLx Receive Example + + This example listens for LoRa transmissions using STM32WL MCU with + integrated (SX126x) LoRa radio. + + To successfully receive data, the following settings have to be the same + on both transmitter and receiver: + - carrier frequency + - bandwidth + - spreading factor + - coding rate + - sync word + - preamble length + + This example assumes Nucleo WL55JC1 is used. For other Nucleo boards + or standalone STM32WL, some configuration such as TCXO voltage and + RF switch control may have to be adjusted. + + For default module settings, see the wiki page + https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lora-modem + + For full API reference, see the GitHub Pages + https://jgromes.github.io/RadioLib/ +*/ + +// include the library +#include + +// no need to configure pins, signals are routed to the radio internally +STM32WLx radio = new STM32WLx_Module(); + +// set RF switch configuration for Nucleo WL55JC1 +// NOTE: other boards may be different! +static const RADIOLIB_PIN_TYPE rfswitch_pins[] = + {PC3, PC4, PC5}; +static const Module::RfSwitchMode_t rfswitch_table[] = { + {STM32WLx::MODE_IDLE, {LOW, LOW, LOW}}, + {STM32WLx::MODE_RX, {HIGH, HIGH, LOW}}, + {STM32WLx::MODE_TX_LP, {HIGH, HIGH, HIGH}}, + {STM32WLx::MODE_TX_HP, {HIGH, LOW, HIGH}}, + STM32WLx::END_OF_MODE_TABLE, +}; + +void setup() { + Serial.begin(9600); + + // set RF switch control configuration + // this has to be done prior to calling begin() + radio.setRfSwitchTable(rfswitch_pins, rfswitch_table); + + // initialize STM32WL with default settings, except frequency + Serial.print(F("[STM32WL] Initializing ... ")); + int state = radio.begin(868.0); + if (state == RADIOLIB_ERR_NONE) { + Serial.println(F("success!")); + } else { + Serial.print(F("failed, code ")); + Serial.println(state); + while (true); + } + + // set appropriate TCXO voltage for Nucleo WL55JC1 + state = radio.setTCXO(1.7); + if (state == RADIOLIB_ERR_NONE) { + Serial.println(F("success!")); + } else { + Serial.print(F("failed, code ")); + Serial.println(state); + while (true); + } +} + +void loop() { + Serial.print(F("[STM32WL] Waiting for incoming transmission ... ")); + + // you can receive data as an Arduino String + // NOTE: receive() is a blocking method! + // See example ReceiveInterrupt for details + // on non-blocking reception method. + String str; + int state = radio.receive(str); + + // you can also receive data as byte array + /* + byte byteArr[8]; + int state = radio.receive(byteArr, 8); + */ + + if (state == RADIOLIB_ERR_NONE) { + // packet was successfully received + Serial.println(F("success!")); + + // print the data of the packet + Serial.print(F("[STM32WL] Data:\t\t")); + Serial.println(str); + + // print the RSSI (Received Signal Strength Indicator) + // of the last received packet + Serial.print(F("[STM32WL] RSSI:\t\t")); + Serial.print(radio.getRSSI()); + Serial.println(F(" dBm")); + + // print the SNR (Signal-to-Noise Ratio) + // of the last received packet + Serial.print(F("[STM32WL] SNR:\t\t")); + Serial.print(radio.getSNR()); + Serial.println(F(" dB")); + + } else if (state == RADIOLIB_ERR_RX_TIMEOUT) { + // timeout occurred while waiting for a packet + Serial.println(F("timeout!")); + + } else if (state == RADIOLIB_ERR_CRC_MISMATCH) { + // packet was received, but is malformed + Serial.println(F("CRC error!")); + + } else { + // some other error occurred + Serial.print(F("failed, code ")); + Serial.println(state); + + } +} diff --git a/examples/STM32WLx/STM32WLx_Receive_Interrupt/STM32WLx_Receive_Interrupt.ino b/examples/STM32WLx/STM32WLx_Receive_Interrupt/STM32WLx_Receive_Interrupt.ino new file mode 100644 index 00000000..57563001 --- /dev/null +++ b/examples/STM32WLx/STM32WLx_Receive_Interrupt/STM32WLx_Receive_Interrupt.ino @@ -0,0 +1,158 @@ +/* + RadioLib STM32WLx Receive with Interrupts Example + + This example listens for LoRa transmissions and tries to + receive them. Once a packet is received, an interrupt is + triggered. To successfully receive data, the following + settings have to be the same on both transmitter + and receiver: + - carrier frequency + - bandwidth + - spreading factor + - coding rate + - sync word + + This example assumes Nucleo WL55JC1 is used. For other Nucleo boards + or standalone STM32WL, some configuration such as TCXO voltage and + RF switch control may have to be adjusted. + + For default module settings, see the wiki page + https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lora-modem + + For full API reference, see the GitHub Pages + https://jgromes.github.io/RadioLib/ +*/ + +// include the library +#include + +// no need to configure pins, signals are routed to the radio internally +STM32WLx radio = new STM32WLx_Module(); + +// set RF switch configuration for Nucleo WL55JC1 +// NOTE: other boards may be different! +static const RADIOLIB_PIN_TYPE rfswitch_pins[] = + {PC3, PC4, PC5}; +static const Module::RfSwitchMode_t rfswitch_table[] = { + {STM32WLx::MODE_IDLE, {LOW, LOW, LOW}}, + {STM32WLx::MODE_RX, {HIGH, HIGH, LOW}}, + {STM32WLx::MODE_TX_LP, {HIGH, HIGH, HIGH}}, + {STM32WLx::MODE_TX_HP, {HIGH, LOW, HIGH}}, + STM32WLx::END_OF_MODE_TABLE, +}; + +void setup() { + Serial.begin(9600); + + // set RF switch control configuration + // this has to be done prior to calling begin() + radio.setRfSwitchTable(rfswitch_pins, rfswitch_table); + + // initialize STM32WL with default settings, except frequency + Serial.print(F("[STM32WL] Initializing ... ")); + int state = radio.begin(868.0); + if (state == RADIOLIB_ERR_NONE) { + Serial.println(F("success!")); + } else { + Serial.print(F("failed, code ")); + Serial.println(state); + while (true); + } + + // set appropriate TCXO voltage for Nucleo WL55JC1 + state = radio.setTCXO(1.7); + if (state == RADIOLIB_ERR_NONE) { + Serial.println(F("success!")); + } else { + Serial.print(F("failed, code ")); + Serial.println(state); + while (true); + } + + // set the function that will be called + // when new packet is received + radio.setDio1Action(setFlag); + + // start listening for LoRa packets + Serial.print(F("[STM32WL] Starting to listen ... ")); + state = radio.startReceive(); + if (state == RADIOLIB_ERR_NONE) { + Serial.println(F("success!")); + } else { + Serial.print(F("failed, code ")); + Serial.println(state); + while (true); + } + + // if needed, 'listen' mode can be disabled by calling + // any of the following methods: + // + // radio.standby() + // radio.sleep() + // radio.transmit(); + // radio.receive(); + // radio.readData(); + // radio.scanChannel(); +} + +// flag to indicate that a packet was received +volatile bool receivedFlag = false; + +// this function is called when a complete packet +// is received by the module +// IMPORTANT: this function MUST be 'void' type +// and MUST NOT have any arguments! +void setFlag(void) { + // we got a packet, set the flag + receivedFlag = true; +} + +void loop() { + // check if the flag is set + if(receivedFlag) { + // reset flag + receivedFlag = false; + + // you can read received data as an Arduino String + String str; + int state = radio.readData(str); + + // you can also read received data as byte array + /* + byte byteArr[8]; + int state = radio.readData(byteArr, 8); + */ + + if (state == RADIOLIB_ERR_NONE) { + // packet was successfully received + Serial.println(F("[STM32WL] Received packet!")); + + // print data of the packet + Serial.print(F("[STM32WL] Data:\t\t")); + Serial.println(str); + + // print RSSI (Received Signal Strength Indicator) + Serial.print(F("[STM32WL] RSSI:\t\t")); + Serial.print(radio.getRSSI()); + Serial.println(F(" dBm")); + + // print SNR (Signal-to-Noise Ratio) + Serial.print(F("[STM32WL] SNR:\t\t")); + Serial.print(radio.getSNR()); + Serial.println(F(" dB")); + + } else if (state == RADIOLIB_ERR_CRC_MISMATCH) { + // packet was received, but is malformed + Serial.println(F("CRC error!")); + + } else { + // some other error occurred + Serial.print(F("failed, code ")); + Serial.println(state); + + } + + // put module back to listen mode + radio.startReceive(); + } +} diff --git a/examples/STM32WLx/STM32WLx_Transmit/STM32WLx_Transmit.ino b/examples/STM32WLx/STM32WLx_Transmit/STM32WLx_Transmit.ino new file mode 100644 index 00000000..fb6dab58 --- /dev/null +++ b/examples/STM32WLx/STM32WLx_Transmit/STM32WLx_Transmit.ino @@ -0,0 +1,112 @@ +/* + RadioLib STM32WLx Transmit Example + + This example transmits packets using STM32WL MCU with integrated + (SX126x) LoRa radio. + + Each packet contains up to 256 bytes of data, in the form of: + - Arduino String + - null-terminated char array (C-string) + - arbitrary binary data (byte array) + + This example assumes Nucleo WL55JC1 is used. For other Nucleo boards + or standalone STM32WL, some configuration such as TCXO voltage and + RF switch control may have to be adjusted. + + For default module settings, see the wiki page + https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lora-modem + + For full API reference, see the GitHub Pages + https://jgromes.github.io/RadioLib/ +*/ + +// include the library +#include + +// no need to configure pins, signals are routed to the radio internally +STM32WLx radio = new STM32WLx_Module(); + +// set RF switch configuration for Nucleo WL55JC1 +// NOTE: other boards may be different! +static const RADIOLIB_PIN_TYPE rfswitch_pins[] = + {PC3, PC4, PC5}; +static const Module::RfSwitchMode_t rfswitch_table[] = { + {STM32WLx::MODE_IDLE, {LOW, LOW, LOW}}, + {STM32WLx::MODE_RX, {HIGH, HIGH, LOW}}, + {STM32WLx::MODE_TX_LP, {HIGH, HIGH, HIGH}}, + {STM32WLx::MODE_TX_HP, {HIGH, LOW, HIGH}}, + STM32WLx::END_OF_MODE_TABLE, +}; + +void setup() { + Serial.begin(9600); + + // set RF switch control configuration + // this has to be done prior to calling begin() + radio.setRfSwitchTable(rfswitch_pins, rfswitch_table); + + // initialize STM32WL with default settings, except frequency + Serial.print(F("[STM32WL] Initializing ... ")); + int state = radio.begin(868.0); + if (state == RADIOLIB_ERR_NONE) { + Serial.println(F("success!")); + } else { + Serial.print(F("failed, code ")); + Serial.println(state); + while (true); + } + + // set appropriate TCXO voltage for Nucleo WL55JC1 + state = radio.setTCXO(1.7); + if (state == RADIOLIB_ERR_NONE) { + Serial.println(F("success!")); + } else { + Serial.print(F("failed, code ")); + Serial.println(state); + while (true); + } +} + +void loop() { + Serial.print(F("[STM32WL] Transmitting packet ... ")); + + // you can transmit C-string or Arduino string up to + // 256 characters long + // NOTE: transmit() is a blocking method! + // See example STM32WLx_Transmit_Interrupt for details + // on non-blocking transmission method. + int state = radio.transmit("Hello World!"); + + // you can also transmit byte array up to 256 bytes long + /* + byte byteArr[] = {0x01, 0x23, 0x45, 0x56, 0x78, 0xAB, 0xCD, 0xEF}; + int state = radio.transmit(byteArr, 8); + */ + + if (state == RADIOLIB_ERR_NONE) { + // the packet was successfully transmitted + Serial.println(F("success!")); + + // print measured data rate + Serial.print(F("[STM32WL] Datarate:\t")); + Serial.print(radio.getDataRate()); + Serial.println(F(" bps")); + + } else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) { + // the supplied packet was longer than 256 bytes + Serial.println(F("too long!")); + + } else if (state == RADIOLIB_ERR_TX_TIMEOUT) { + // timeout occured while transmitting packet + Serial.println(F("timeout!")); + + } else { + // some other error occurred + Serial.print(F("failed, code ")); + Serial.println(state); + + } + + // wait for a second before transmitting again + delay(1000); +} diff --git a/examples/STM32WLx/STM32WLx_Transmit_Interrupt/STM32WLx_Transmit_Interrupt.ino b/examples/STM32WLx/STM32WLx_Transmit_Interrupt/STM32WLx_Transmit_Interrupt.ino new file mode 100644 index 00000000..ea17838a --- /dev/null +++ b/examples/STM32WLx/STM32WLx_Transmit_Interrupt/STM32WLx_Transmit_Interrupt.ino @@ -0,0 +1,140 @@ +/* + RadioLib STM32WLx Transmit with Interrupts Example + + This example transmits LoRa packets with one second delays + between them. Each packet contains up to 256 bytes + of data, in the form of: + - Arduino String + - null-terminated char array (C-string) + - arbitrary binary data (byte array) + + For default module settings, see the wiki page + https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lora-modem + + For full API reference, see the GitHub Pages + https://jgromes.github.io/RadioLib/ +*/ + +// include the library +#include + +// no need to configure pins, signals are routed to the radio internally +STM32WLx radio = new STM32WLx_Module(); + +// set RF switch configuration for Nucleo WL55JC1 +// NOTE: other boards may be different! +static const RADIOLIB_PIN_TYPE rfswitch_pins[] = + {PC3, PC4, PC5}; +static const Module::RfSwitchMode_t rfswitch_table[] = { + {STM32WLx::MODE_IDLE, {LOW, LOW, LOW}}, + {STM32WLx::MODE_RX, {HIGH, HIGH, LOW}}, + {STM32WLx::MODE_TX_LP, {HIGH, HIGH, HIGH}}, + {STM32WLx::MODE_TX_HP, {HIGH, LOW, HIGH}}, + STM32WLx::END_OF_MODE_TABLE, +}; + +// save transmission state between loops +int transmissionState = RADIOLIB_ERR_NONE; + +void setup() { + Serial.begin(9600); + + // set RF switch control configuration + // this has to be done prior to calling begin() + radio.setRfSwitchTable(rfswitch_pins, rfswitch_table); + + // initialize STM32WL with default settings, except frequency + Serial.print(F("[STM32WL] Initializing ... ")); + int state = radio.begin(868.0); + if (state == RADIOLIB_ERR_NONE) { + Serial.println(F("success!")); + } else { + Serial.print(F("failed, code ")); + Serial.println(state); + while (true); + } + + // set appropriate TCXO voltage for Nucleo WL55JC1 + state = radio.setTCXO(1.7); + if (state == RADIOLIB_ERR_NONE) { + Serial.println(F("success!")); + } else { + Serial.print(F("failed, code ")); + Serial.println(state); + while (true); + } + + // set the function that will be called + // when packet transmission is finished + radio.setDio1Action(setFlag); + + // start transmitting the first packet + Serial.print(F("[STM32WL] Sending first packet ... ")); + + // you can transmit C-string or Arduino string up to + // 256 characters long + transmissionState = radio.startTransmit("Hello World!"); + + // you can also transmit byte array up to 256 bytes long + /* + byte byteArr[] = {0x01, 0x23, 0x45, 0x67, + 0x89, 0xAB, 0xCD, 0xEF}; + state = radio.startTransmit(byteArr, 8); + */ +} + +// flag to indicate that a packet was sent +volatile bool transmittedFlag = false; + +// this function is called when a complete packet +// is transmitted by the module +// IMPORTANT: this function MUST be 'void' type +// and MUST NOT have any arguments! +void setFlag(void) { + // we sent a packet, set the flag + transmittedFlag = true; +} + +void loop() { + // check if the previous transmission finished + if(transmittedFlag) { + // reset flag + transmittedFlag = false; + + if (transmissionState == RADIOLIB_ERR_NONE) { + // packet was successfully sent + Serial.println(F("transmission finished!")); + + // NOTE: when using interrupt-driven transmit method, + // it is not possible to automatically measure + // transmission data rate using getDataRate() + + } else { + Serial.print(F("failed, code ")); + Serial.println(transmissionState); + + } + + // clean up after transmission is finished + // this will ensure transmitter is disabled, + // RF switch is powered down etc. + radio.finishTransmit(); + + // wait a second before transmitting again + delay(1000); + + // send another one + Serial.print(F("[STM32WL] Sending another packet ... ")); + + // you can transmit C-string or Arduino string up to + // 256 characters long + transmissionState = radio.startTransmit("Hello World!"); + + // you can also transmit byte array up to 256 bytes long + /* + byte byteArr[] = {0x01, 0x23, 0x45, 0x67, + 0x89, 0xAB, 0xCD, 0xEF}; + int state = radio.startTransmit(byteArr, 8); + */ + } +}