From aa4dbdaec927e3e6e083bffb0c37e132e3b8c029 Mon Sep 17 00:00:00 2001 From: Sylvain Montagny Date: Tue, 23 Apr 2024 21:38:04 +0200 Subject: [PATCH] Update board --- CHANGELOG.md | 20 +- README.md | 15 +- examples/LoRaWAN_Class_A/LoRaWAN_Class_A.ino | 6 +- examples/LoRaWAN_Class_A/config_board.h | 42 +++ examples/LoRaWAN_Class_C/LoRaWAN_Class_C.ino | 8 +- examples/LoRaWAN_Class_C/config_board.h | 42 +++ .../LoRaWAN_State-Machine.ino | 6 +- examples/LoRaWAN_State-Machine/config_board.h | 42 +++ .../MLR003-simulation/MLR003-simulation.ino | 6 +- examples/MLR003-simulation/config_board.h | 42 +++ library.properties | 2 +- src/lorae5.cpp | 314 ++++++++++-------- src/lorae5.h | 34 +- 13 files changed, 419 insertions(+), 160 deletions(-) create mode 100644 examples/LoRaWAN_Class_A/config_board.h create mode 100644 examples/LoRaWAN_Class_C/config_board.h create mode 100644 examples/LoRaWAN_State-Machine/config_board.h create mode 100644 examples/MLR003-simulation/config_board.h diff --git a/CHANGELOG.md b/CHANGELOG.md index 602b343..af7c154 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,9 +4,23 @@ ## Knows limitation -- Tested on "EU868" & "US915". -- Tested compatibility only with "Leonardo" and "Zero" Arduino boards. -- "LoRaWAN modem is busy" message may occurs for Class C/ABP. +* Tested on "EU868" & "US915". +* Tested compatibility only with: +1. "Leonardo", "Zero" and "Due" Arduino boards, +2. "ESP32_DevKitc_V4" Espressif board, +3. "F446RE" and "L073RZ" Nucleo boards, +4. "Wio Terminal" Seeed board, +* "LoRaWAN modem is busy" message may occurs for Class C/ABP. + +## Version: V3.0.0 | 2024-05-14 + +### Added +- A “config_board.h” header to manage several defined boards and allow you to choose the serial configuration for the others. +- Implement a setup_hardware() method. + +### Modified +- "USB_Serial" has been replaced by "Debug_Serial". +- Renamed setup() method to setup_lorawan(). ## Version: V2.0.0 | 2024-04-22 diff --git a/README.md b/README.md index d66c569..563fff2 100644 --- a/README.md +++ b/README.md @@ -42,16 +42,22 @@ This library has only been tested with an **Arduino Leonardo** and an **Arduino ## 2.2. Arduino Hardware -This library works with any Arduino boards with two serial ports (or one USB + one Serial). It has been tested on an Arduino **Leonardo & Zero** boards with: -- USB_Serial: Connection to computer: 115200 baud. +This library works with any Arduino boards with two serial ports (or one USB + one Serial). It has been tested on an Arduino **Leonardo, Zero & Due** boards with: +- Debug_Serial: Connection to computer: 115200 baud. - LoRa_Serial: Serial link for the communication between the Arduino MCU and the LoRa-E5 LoRaWAN module. Your LoRa-E5 module need to be connected to the RX-TX arduino header pin. +It also works with : +- Espressif "ESP32_DevKitc_V4" board, +- Nucleo "F446RE" and "L073RZ" boards, +- Seeed "Wio Terminal" board, + ## 2.3. How to use this library -- Set up the parameters in **config_application.h** file. If you use ABP, you need to configure devAdddr, nwkSKey and appSKey. If you use OTAA you need to configure devEUI, appEUI and appKey. +- Set up the LoRaWAN parameters in **config_application.h** file. If you use ABP, you need to configure devAdddr, nwkSKey and appSKey. If you use OTAA you need to configure devEUI, appEUI and appKey. +- Set up the hardware parameters in **config_board.h** file. Choose the right setting for your board (Serial or Pins). - Set up your Gateway or use a public coverage. - Register your Device on a Network Server (TTN, Actility, LORIOT, ...) - Open the Serial Monitor in the arduino IDE to see the logs. :warning: 115200 baud. @@ -64,5 +70,4 @@ Your LoRa-E5 module need to be connected to the RX-TX arduino header pin. ## 2.5. Best practices -- It is recommended to opt for OTAA over ABP for the Activation Mode. - \ No newline at end of file +- It is recommended to opt for OTAA over ABP for the Activation Mode. \ No newline at end of file diff --git a/examples/LoRaWAN_Class_A/LoRaWAN_Class_A.ino b/examples/LoRaWAN_Class_A/LoRaWAN_Class_A.ino index 708c0a0..9601fb9 100644 --- a/examples/LoRaWAN_Class_A/LoRaWAN_Class_A.ino +++ b/examples/LoRaWAN_Class_A/LoRaWAN_Class_A.ino @@ -1,6 +1,7 @@ #include #include "lorae5.h" #include "config_application.h" +#include "config_board.h" uint8_t sizePayloadUp = 4; uint8_t sizePayloadDown = 0; @@ -15,11 +16,12 @@ LORAE5 lorae5(devEUI, appEUI, appKey, devAddr, nwkSKey, appSKey); /***********************************************************************/ void setup() { - lorae5.setup(REGION, ACTIVATION_MODE, CLASS, SPREADING_FACTOR, ADAPTIVE_DR, CONFIRMED, PORT_UP, SEND_BY_PUSH_BUTTON, FRAME_DELAY); + lorae5.setup_hardware(&Debug_Serial, &LoRa_Serial); + lorae5.setup_lorawan(REGION, ACTIVATION_MODE, CLASS, SPREADING_FACTOR, ADAPTIVE_DR, CONFIRMED, PORT_UP, SEND_BY_PUSH_BUTTON, FRAME_DELAY); lorae5.printInfo(); if(ACTIVATION_MODE == OTAA){ - USB_Serial.println("Join Procedure in progress..."); + Debug_Serial.println("Join Procedure in progress..."); while(lorae5.join() == false); delay(2000); } diff --git a/examples/LoRaWAN_Class_A/config_board.h b/examples/LoRaWAN_Class_A/config_board.h new file mode 100644 index 0000000..32f68f0 --- /dev/null +++ b/examples/LoRaWAN_Class_A/config_board.h @@ -0,0 +1,42 @@ +#ifndef CONFIG_BOARD_H +#define CONFIG_BOARD_H + +////////////////////////////////////////////// +// If you use an ARDUINO or ESP32 board +////////////////////////////////////////////// + #if defined(ARDUINO_ARCH_AVR) || defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_WIO_TERMINAL) + #define Debug_Serial Serial // Select the right SerialX for Debug + + // Arduino's Serial Documentation : https://www.arduino.cc/reference/en/language/functions/communication/serial/ + // ESP32 Documentation + #define LoRa_Serial Serial1 // Select the right SerialX for the LoRaE5 connection + +////////////////////////////////////////////// +// If you use a STM32 NUCLEO board +////////////////////////////////////////////// + #elif defined(ARDUINO_ARCH_STM32) + #define RX_PIN_DEBUG PA3 // Select UART RX Pin for Debug + #define TX_PIN_DEBUG PA2 // Select UART TX Pin for Debug + HardwareSerial Debug_Serial(RX_PIN_DEBUG, TX_PIN_DEBUG); + + #define RX_PIN_LORA PA1 // Select UART RX Pin for the LoRaE5 connection + #define TX_PIN_LORA PA0 // Select UART TX Pin for the LoRaE5 connection + HardwareSerial LoRa_Serial(RX_PIN_LORA, TX_PIN_LORA); + + +////////////////////////////////////////////// +// /!\ Your card has never been tested yet ! +// Please let us know if you find the PIN configuration of your board +// So we can add it to the next version of this code +////////////////////////////////////////////// + + #else + #warning "Your board has never been tested with this lib" + #warning "Select the right Serial for Debug and LoRaE5 connection in config_board.h" + + #define Debug_Serial Serial + #define LoRa_Serial Serial1 + + #endif + +#endif //CONFIG_BOARD_H \ No newline at end of file diff --git a/examples/LoRaWAN_Class_C/LoRaWAN_Class_C.ino b/examples/LoRaWAN_Class_C/LoRaWAN_Class_C.ino index 22a6f47..1e6794f 100644 --- a/examples/LoRaWAN_Class_C/LoRaWAN_Class_C.ino +++ b/examples/LoRaWAN_Class_C/LoRaWAN_Class_C.ino @@ -1,6 +1,7 @@ #include #include "lorae5.h" #include "config_application.h" +#include "config_board.h" uint8_t sizePayloadUp = 4; uint8_t sizePayloadDown = 0; @@ -15,11 +16,12 @@ LORAE5 lorae5(devEUI, appEUI, appKey, devAddr, nwkSKey, appSKey); /***********************************************************************/ void setup() { - lorae5.setup(REGION, ACTIVATION_MODE, CLASS, SPREADING_FACTOR, ADAPTIVE_DR, CONFIRMED, PORT_UP, SEND_BY_PUSH_BUTTON, FRAME_DELAY); + lorae5.setup_hardware(&Debug_Serial, &LoRa_Serial); + lorae5.setup_lorawan(REGION, ACTIVATION_MODE, CLASS, SPREADING_FACTOR, ADAPTIVE_DR, CONFIRMED, PORT_UP, SEND_BY_PUSH_BUTTON, FRAME_DELAY); lorae5.printInfo(); if(ACTIVATION_MODE == OTAA){ - USB_Serial.println("Join Procedure in progress..."); + Debug_Serial.println("Join Procedure in progress..."); while(lorae5.join() == false); delay(2000); } @@ -42,4 +44,4 @@ void loop() { void processDownlink() { // You have received "sizePayloadDown" bytes stored in the table "payloadDown" -} \ No newline at end of file +} \ No newline at end of file diff --git a/examples/LoRaWAN_Class_C/config_board.h b/examples/LoRaWAN_Class_C/config_board.h new file mode 100644 index 0000000..32f68f0 --- /dev/null +++ b/examples/LoRaWAN_Class_C/config_board.h @@ -0,0 +1,42 @@ +#ifndef CONFIG_BOARD_H +#define CONFIG_BOARD_H + +////////////////////////////////////////////// +// If you use an ARDUINO or ESP32 board +////////////////////////////////////////////// + #if defined(ARDUINO_ARCH_AVR) || defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_WIO_TERMINAL) + #define Debug_Serial Serial // Select the right SerialX for Debug + + // Arduino's Serial Documentation : https://www.arduino.cc/reference/en/language/functions/communication/serial/ + // ESP32 Documentation + #define LoRa_Serial Serial1 // Select the right SerialX for the LoRaE5 connection + +////////////////////////////////////////////// +// If you use a STM32 NUCLEO board +////////////////////////////////////////////// + #elif defined(ARDUINO_ARCH_STM32) + #define RX_PIN_DEBUG PA3 // Select UART RX Pin for Debug + #define TX_PIN_DEBUG PA2 // Select UART TX Pin for Debug + HardwareSerial Debug_Serial(RX_PIN_DEBUG, TX_PIN_DEBUG); + + #define RX_PIN_LORA PA1 // Select UART RX Pin for the LoRaE5 connection + #define TX_PIN_LORA PA0 // Select UART TX Pin for the LoRaE5 connection + HardwareSerial LoRa_Serial(RX_PIN_LORA, TX_PIN_LORA); + + +////////////////////////////////////////////// +// /!\ Your card has never been tested yet ! +// Please let us know if you find the PIN configuration of your board +// So we can add it to the next version of this code +////////////////////////////////////////////// + + #else + #warning "Your board has never been tested with this lib" + #warning "Select the right Serial for Debug and LoRaE5 connection in config_board.h" + + #define Debug_Serial Serial + #define LoRa_Serial Serial1 + + #endif + +#endif //CONFIG_BOARD_H \ No newline at end of file diff --git a/examples/LoRaWAN_State-Machine/LoRaWAN_State-Machine.ino b/examples/LoRaWAN_State-Machine/LoRaWAN_State-Machine.ino index e98ba4f..4c742d3 100644 --- a/examples/LoRaWAN_State-Machine/LoRaWAN_State-Machine.ino +++ b/examples/LoRaWAN_State-Machine/LoRaWAN_State-Machine.ino @@ -1,6 +1,7 @@ #include #include "lorae5.h" #include "config_application.h" +#include "config_board.h" uint8_t sizePayloadUp = 4; uint8_t sizePayloadDown = 0; @@ -21,11 +22,12 @@ State currentState = State::SEND_DATA; /***********************************************************************/ void setup() { - lorae5.setup(REGION, ACTIVATION_MODE, CLASS, SPREADING_FACTOR, ADAPTIVE_DR, CONFIRMED, PORT_UP, SEND_BY_PUSH_BUTTON, FRAME_DELAY); + lorae5.setup_hardware(&Debug_Serial, &LoRa_Serial); + lorae5.setup_lorawan(REGION, ACTIVATION_MODE, CLASS, SPREADING_FACTOR, ADAPTIVE_DR, CONFIRMED, PORT_UP, SEND_BY_PUSH_BUTTON, FRAME_DELAY); lorae5.printInfo(); if(ACTIVATION_MODE == OTAA){ - USB_Serial.println("Join Procedure in progress..."); + Debug_Serial.println("Join Procedure in progress..."); while(lorae5.join() == false); delay(2000); } diff --git a/examples/LoRaWAN_State-Machine/config_board.h b/examples/LoRaWAN_State-Machine/config_board.h new file mode 100644 index 0000000..32f68f0 --- /dev/null +++ b/examples/LoRaWAN_State-Machine/config_board.h @@ -0,0 +1,42 @@ +#ifndef CONFIG_BOARD_H +#define CONFIG_BOARD_H + +////////////////////////////////////////////// +// If you use an ARDUINO or ESP32 board +////////////////////////////////////////////// + #if defined(ARDUINO_ARCH_AVR) || defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_WIO_TERMINAL) + #define Debug_Serial Serial // Select the right SerialX for Debug + + // Arduino's Serial Documentation : https://www.arduino.cc/reference/en/language/functions/communication/serial/ + // ESP32 Documentation + #define LoRa_Serial Serial1 // Select the right SerialX for the LoRaE5 connection + +////////////////////////////////////////////// +// If you use a STM32 NUCLEO board +////////////////////////////////////////////// + #elif defined(ARDUINO_ARCH_STM32) + #define RX_PIN_DEBUG PA3 // Select UART RX Pin for Debug + #define TX_PIN_DEBUG PA2 // Select UART TX Pin for Debug + HardwareSerial Debug_Serial(RX_PIN_DEBUG, TX_PIN_DEBUG); + + #define RX_PIN_LORA PA1 // Select UART RX Pin for the LoRaE5 connection + #define TX_PIN_LORA PA0 // Select UART TX Pin for the LoRaE5 connection + HardwareSerial LoRa_Serial(RX_PIN_LORA, TX_PIN_LORA); + + +////////////////////////////////////////////// +// /!\ Your card has never been tested yet ! +// Please let us know if you find the PIN configuration of your board +// So we can add it to the next version of this code +////////////////////////////////////////////// + + #else + #warning "Your board has never been tested with this lib" + #warning "Select the right Serial for Debug and LoRaE5 connection in config_board.h" + + #define Debug_Serial Serial + #define LoRa_Serial Serial1 + + #endif + +#endif //CONFIG_BOARD_H \ No newline at end of file diff --git a/examples/MLR003-simulation/MLR003-simulation.ino b/examples/MLR003-simulation/MLR003-simulation.ino index 66caf09..07574d9 100644 --- a/examples/MLR003-simulation/MLR003-simulation.ino +++ b/examples/MLR003-simulation/MLR003-simulation.ino @@ -1,6 +1,7 @@ #include #include "lorae5.h" #include "config_application.h" +#include "config_board.h" uint8_t sizePayloadUp = 2; uint8_t sizePayloadDown = 0; @@ -18,11 +19,12 @@ LORAE5 lorae5(devEUI, appEUI, appKey, devAddr, nwkSKey, appSKey); /***********************************************************************/ void setup() { - lorae5.setup(REGION, ACTIVATION_MODE, CLASS, SPREADING_FACTOR, ADAPTIVE_DR, CONFIRMED, PORT_UP, SEND_BY_PUSH_BUTTON, FRAME_DELAY); + lorae5.setup_hardware(&Debug_Serial, &LoRa_Serial); + lorae5.setup_lorawan(REGION, ACTIVATION_MODE, CLASS, SPREADING_FACTOR, ADAPTIVE_DR, CONFIRMED, PORT_UP, SEND_BY_PUSH_BUTTON, FRAME_DELAY); lorae5.printInfo(); if(ACTIVATION_MODE == OTAA){ - USB_Serial.println("Join Procedure in progress..."); + Debug_Serial.println("Join Procedure in progress..."); while(lorae5.join() == false); delay(2000); } diff --git a/examples/MLR003-simulation/config_board.h b/examples/MLR003-simulation/config_board.h new file mode 100644 index 0000000..32f68f0 --- /dev/null +++ b/examples/MLR003-simulation/config_board.h @@ -0,0 +1,42 @@ +#ifndef CONFIG_BOARD_H +#define CONFIG_BOARD_H + +////////////////////////////////////////////// +// If you use an ARDUINO or ESP32 board +////////////////////////////////////////////// + #if defined(ARDUINO_ARCH_AVR) || defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_WIO_TERMINAL) + #define Debug_Serial Serial // Select the right SerialX for Debug + + // Arduino's Serial Documentation : https://www.arduino.cc/reference/en/language/functions/communication/serial/ + // ESP32 Documentation + #define LoRa_Serial Serial1 // Select the right SerialX for the LoRaE5 connection + +////////////////////////////////////////////// +// If you use a STM32 NUCLEO board +////////////////////////////////////////////// + #elif defined(ARDUINO_ARCH_STM32) + #define RX_PIN_DEBUG PA3 // Select UART RX Pin for Debug + #define TX_PIN_DEBUG PA2 // Select UART TX Pin for Debug + HardwareSerial Debug_Serial(RX_PIN_DEBUG, TX_PIN_DEBUG); + + #define RX_PIN_LORA PA1 // Select UART RX Pin for the LoRaE5 connection + #define TX_PIN_LORA PA0 // Select UART TX Pin for the LoRaE5 connection + HardwareSerial LoRa_Serial(RX_PIN_LORA, TX_PIN_LORA); + + +////////////////////////////////////////////// +// /!\ Your card has never been tested yet ! +// Please let us know if you find the PIN configuration of your board +// So we can add it to the next version of this code +////////////////////////////////////////////// + + #else + #warning "Your board has never been tested with this lib" + #warning "Select the right Serial for Debug and LoRaE5 connection in config_board.h" + + #define Debug_Serial Serial + #define LoRa_Serial Serial1 + + #endif + +#endif //CONFIG_BOARD_H \ No newline at end of file diff --git a/library.properties b/library.properties index 487eb73..d21346c 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=LoRaWAN-Seeed-Grove-Wio-E5 -version=2.0.0 +version=2.0.1 author=Sylvain Montagny,sylvain.montagny@univ-smb.fr maintainer=Savoie Mont Blanc University sentence=Sending LoRaWAN frame with a Grove Wio E5 module. diff --git a/src/lorae5.cpp b/src/lorae5.cpp index 463c6e1..cee5a7b 100644 --- a/src/lorae5.cpp +++ b/src/lorae5.cpp @@ -1,4 +1,5 @@ #include +#include #include "lorae5.h" LORAE5::LORAE5(String devEUI, String appEUI, String appKey, String devAddr, String nwkSKey, String appSKey){ @@ -10,7 +11,54 @@ LORAE5::LORAE5(String devEUI, String appEUI, String appKey, String devAddr, Stri this->appSKey = appSKey; } -/// @brief Allow to set all the setup for our transmission +#if defined(ARDUINO_AVR_LEONARDO) +/// @brief Allow to set the hardware setup for our transmission +/// @param myDebugSerial is the debug serial link +/// @param myLoRaSerial is the LoRaE5 serial link +void LORAE5::setup_hardware(Serial_* myDebugSerial, HardwareSerial* myLoRaSerial){ + unsigned long startTime = millis(); + + this->serialD = myDebugSerial; + this->serialL = myLoRaSerial; + + (this->serialD)->begin(115200); + (this->serialL)->begin(9600); + + while (millis() - startTime < 2000); +} +#elif defined(ARDUINO_WIO_TERMINAL) +/// @brief Allow to set the hardware setup for our transmission +/// @param myDebugSerial is the debug serial link +/// @param myLoRaSerial is the LoRaE5 serial link +void LORAE5::setup_hardware(Serial_* myDebugSerial, Uart* myLoRaSerial){ + unsigned long startTime = millis(); + + this->serialD = myDebugSerial; + this->serialL = myLoRaSerial; + + (this->serialD)->begin(115200); + (this->serialL)->begin(9600); + + while (millis() - startTime < 2000); +} +#else +/// @brief Allow to set the hardware setup for our transmission +/// @param myDebugSerial is the debug serial link +/// @param myLoRaSerial is the LoRaE5 serial link +void LORAE5::setup_hardware(HardwareSerial* myDebugSerial, HardwareSerial* myLoRaSerial){ + unsigned long startTime = millis(); + + this->serialD = myDebugSerial; + this->serialL = myLoRaSerial; + + (this->serialD)->begin(115200); + (this->serialL)->begin(9600); + + while (millis() - startTime < 2000); +} +#endif + +/// @brief Allow to set the LoRaWAN setup for our transmission /// @param region is the region selected by the user /// @param mode is the mode selected by the user /// @param devClass is the class of the device selected by the user @@ -20,11 +68,7 @@ LORAE5::LORAE5(String devEUI, String appEUI, String appKey, String devAddr, Stri /// @param portUp is the uplink port selected by the user /// @param SEND_BY_PUSH_BUTTON is the push button condition selected by the user /// @param FRAME_DELAY is the frame delay selected by the user -void LORAE5::setup(uint8_t region, bool mode, uint8_t devClass, uint8_t sf, bool adr, bool confirmed, uint8_t portUp, bool SEND_BY_PUSH_BUTTON, uint32_t FRAME_DELAY){ - unsigned long startTime = millis(); - LoRa_Serial.begin(9600); - USB_Serial.begin(115200); - while (!USB_Serial && (millis() - startTime < 5000)); +void LORAE5::setup_lorawan(uint8_t region, bool mode, uint8_t devClass, uint8_t sf, bool adr, bool confirmed, uint8_t portUp, bool SEND_BY_PUSH_BUTTON, uint32_t FRAME_DELAY){ while(!checkBoard()); @@ -54,9 +98,9 @@ void LORAE5::setup(uint8_t region, bool mode, uint8_t devClass, uint8_t sf, bool /// @brief Allow to set the RX delay void LORAE5::setRXDelay(){ readResponse(1000,NO_DEBUG); - LoRa_Serial.println("AT+DELAY=RX1,1000"); + SERIAL_L("AT+DELAY=RX1,1000"); readResponse(400,NO_DEBUG); - LoRa_Serial.println("AT+DELAY=RX2,2000"); + SERIAL_L("AT+DELAY=RX2,2000"); readResponse(400,NO_DEBUG); } @@ -69,7 +113,7 @@ void LORAE5::setMode(bool mode){ if (mode == OTAA) strMode = "LWOTAA"; if (mode == ABP) strMode = "LWABP"; - LoRa_Serial.println("AT+MODE=" + strMode); + SERIAL_L("AT+MODE=" + strMode); readResponse(400,NO_DEBUG); } @@ -81,7 +125,7 @@ void LORAE5::setClass(uint8_t devClass){ this->devClass = devClass; if (devClass == CLASS_A) strClass = "A"; if (devClass == CLASS_C) strClass = "C"; - LoRa_Serial.println("AT+CLASS=" + strClass); + SERIAL_L("AT+CLASS=" + strClass); readResponse(400,NO_DEBUG); } @@ -90,29 +134,29 @@ void LORAE5::setClass(uint8_t devClass){ void LORAE5::setSF(uint8_t sf){ this->sf = sf; if ((this->region) == EU868){ - LoRa_Serial.println("AT+DR=DR" + String(-sf+12)); + SERIAL_L("AT+DR=DR" + String(-sf+12)); } if ((this->region) == US915){ - LoRa_Serial.println("AT+DR=DR" + String(-sf+10)); + SERIAL_L("AT+DR=DR" + String(-sf+10)); } - String response = LoRa_Serial.readStringUntil('\n'); + String response = (this->serialL)->readStringUntil('\n'); readResponse(400,NO_DEBUG); } /// @brief Allow to process and set the Spreading Factor (SF) received from the downlink void LORAE5::getSetSF(){ String response; - LoRa_Serial.setTimeout(500); - LoRa_Serial.println("AT+DR"); - response = LoRa_Serial.readStringUntil('\n'); + (this->serialL)->setTimeout(500); + SERIAL_L("AT+DR"); + response = (this->serialL)->readStringUntil('\n'); #if DEBUG_LEVEL == 2 - USB_Serial.println(response); // DEBUG + SERIAL_D(response); // DEBUG #endif if (this->adr == true){ - response = LoRa_Serial.readStringUntil('\n'); + response = (this->serialL)->readStringUntil('\n'); #if DEBUG_LEVEL == 2 - USB_Serial.println(response); // DEBUG + SERIAL_D(response); // DEBUG #endif } @@ -139,49 +183,49 @@ void LORAE5::getSetSF(){ /// @param adr is to enable or disable the Adaptive Data Rate void LORAE5::setADR(bool adr){ this->adr = adr; - LoRa_Serial.println("AT+ADR=" + ((adr == true)? String("ON") : String("OFF"))); + SERIAL_L("AT+ADR=" + ((adr == true)? String("ON") : String("OFF"))); readResponse(400,NO_DEBUG); } /// @brief Allow to set Device EUI /// @param deveui is the Device EUI void LORAE5::setDevEUI(String deveui){ - LoRa_Serial.println("AT+ID=DEVEUI," + devEUI); + SERIAL_L("AT+ID=DEVEUI," + devEUI); readResponse(400,NO_DEBUG); } /// @brief Allow to set Application EUI /// @param appeui is the Application EUI void LORAE5::setAppEUI(String appeui){ - LoRa_Serial.println("AT+ID=APPEUI," + appeui); + SERIAL_L("AT+ID=APPEUI," + appeui); readResponse(400,NO_DEBUG); } /// @brief Allow to set Application Key /// @param appkey is the Application Key void LORAE5::setAppKey(String appkey){ - LoRa_Serial.println("AT+KEY=APPKEY," + appkey); + SERIAL_L("AT+KEY=APPKEY," + appkey); readResponse(400,NO_DEBUG); } /// @brief Allow to set Device Address /// @param devaddr is the Device Address void LORAE5::setDevAddr(String devaddr){ - LoRa_Serial.println("AT+ID=DEVADDR," + devaddr); + SERIAL_L("AT+ID=DEVADDR," + devaddr); readResponse(400,NO_DEBUG); } /// @brief Allow to set Network Session Key /// @param nwkskey is the Network Session Key void LORAE5::setNwkSKey(String nwkskey){ - LoRa_Serial.println("AT+KEY=NWKSKEY," + nwkskey); + SERIAL_L("AT+KEY=NWKSKEY," + nwkskey); readResponse(400,NO_DEBUG); } /// @brief Allow to set Application Session Key /// @param appskey is the Application Session Key void LORAE5::setAppSKey(String appskey){ - LoRa_Serial.println("AT+KEY=APPSKEY," + appskey); + SERIAL_L("AT+KEY=APPSKEY," + appskey); readResponse(400,NO_DEBUG); } @@ -189,7 +233,7 @@ void LORAE5::setAppSKey(String appskey){ /// @param portUp is the uplink port selected by the user void LORAE5::setPortUp(uint8_t portUp){ this->portUp = portUp; - LoRa_Serial.println("AT+PORT=" + String(portUp)); + SERIAL_L("AT+PORT=" + String(portUp)); readResponse(400,NO_DEBUG); } @@ -198,13 +242,13 @@ void LORAE5::setPortUp(uint8_t portUp){ bool LORAE5::checkBoard(){ bool success; delay(500); - LoRa_Serial.println("AT"); - USB_Serial.println("\n\n\n\n"); + SERIAL_L("AT"); + SERIAL_D("\n\n\n\n"); if ( (success = checkResponse(400,"+AT: OK\r\n",NO_DEBUG)) == false){ - USB_Serial.println("> LoRa-E5 board not detected ..."); + SERIAL_D("> LoRa-E5 board not detected ..."); } else{ - USB_Serial.println("> LoRa-E5 board detected ...\n"); + SERIAL_D("> LoRa-E5 board detected ...\n"); } return success; } @@ -217,13 +261,13 @@ bool LORAE5::join(){ uint32_t index; delay(2000); - LoRa_Serial.setTimeout(10000); - LoRa_Serial.println("AT+JOIN"); + (this->serialL)->setTimeout(10000); + SERIAL_L("AT+JOIN"); do{ - response = LoRa_Serial.readStringUntil('\n'); + response = (this->serialL)->readStringUntil('\n'); #if DEBUG_LEVEL == 1 - USB_Serial.println(response); // DEBUG + SERIAL_D(response); // DEBUG #endif // Analyse DevAddr response @@ -240,8 +284,8 @@ bool LORAE5::join(){ strDevAddr += ":"; strDevAddr += response.charAt(index + 9); strDevAddr += response.charAt(index + 10); - USB_Serial.println("> SUCCESS JOINED OTAA !!!"); - USB_Serial.println("> DevAddr = " + strDevAddr); + SERIAL_D("> SUCCESS JOINED OTAA !!!"); + SERIAL_D("> DevAddr = " + strDevAddr); joined = true; } // Analyse end of Join procedure @@ -250,11 +294,11 @@ bool LORAE5::join(){ } // Analyse failed join else if ( (index = response.indexOf("Join failed")) != -1 ){ - USB_Serial.println("> JOIN FAILED ..."); + SERIAL_D("> JOIN FAILED ..."); failed = true; } } while((!joined || !done) && !failed ); - USB_Serial.println(""); + SERIAL_D(""); return joined; } @@ -262,27 +306,27 @@ bool LORAE5::join(){ /// @param payloadUp is the data to send /// @param sizePayloadUp is the size of the data to send void LORAE5::sendPayloadUp(uint8_t* payloadUp, uint8_t sizePayloadUp) { - USB_Serial.println("Sending " + String(this->confirmed ? "Confirmed " : "Unconfirmed ") + String("Data Up")); - USB_Serial.print("- Payload UP "); + SERIAL_D("Sending " + String(this->confirmed ? "Confirmed " : "Unconfirmed ") + String("Data Up")); + (this->serialD)->print("- Payload UP "); String stringPayloadUp = ""; for (uint8_t i = 0; i < sizePayloadUp; i++) { - USB_Serial.print(" 0x"); + (this->serialD)->print(" 0x"); if (payloadUp[i] < 0x10) { - USB_Serial.print('0'); + (this->serialD)->print('0'); stringPayloadUp += 0; } - USB_Serial.print(payloadUp[i], HEX); - USB_Serial.print(" "); + (this->serialD)->print(payloadUp[i], HEX); + (this->serialD)->print(" "); stringPayloadUp += String(payloadUp[i], HEX); } - USB_Serial.println(""); - USB_Serial.println("- PortUp\t" + String(this->portUp)); - USB_Serial.println("- SF\t\t" + String(this->sf)); - USB_Serial.println(""); + SERIAL_D(""); + SERIAL_D("- PortUp\t" + String(this->portUp)); + SERIAL_D("- SF\t\t" + String(this->sf)); + SERIAL_D(""); - LoRa_Serial.println("AT+" + String(this->confirmed ? "C" : "") + String("MSGHEX") + String("=") + stringPayloadUp); + SERIAL_L("AT+" + String(this->confirmed ? "C" : "") + String("MSGHEX") + String("=") + stringPayloadUp); } /// @brief Allow to manage the sending of uplink data @@ -292,37 +336,37 @@ void LORAE5::sendData(uint8_t* payloadUp, uint8_t sizePayloadUp){ bool transmissionDone = false; String response; uint32_t index; - LoRa_Serial.setTimeout(500); + (this->serialL)->setTimeout(500); getSetSF(); sendPayloadUp(payloadUp, sizePayloadUp); do{ - response = LoRa_Serial.readStringUntil('\n'); + response = (this->serialL)->readStringUntil('\n'); #if DEBUG_LEVEL == 3 - USB_Serial.println(response); // DEBUG + SERIAL_D(response); // DEBUG #endif if ( (index = response.indexOf("Start")) != -1 ){ - USB_Serial.println("Transmission Done\nWaiting for Downlink..."); + SERIAL_D("Transmission Done\nWaiting for Downlink..."); transmissionDone = true; } if ( (index = response.indexOf("Length error 0")) != -1 ){ - LoRa_Serial.println("AT+MSG"); + SERIAL_L("AT+MSG"); } } while (!transmissionDone); if(confirmed == true){ - response = LoRa_Serial.readStringUntil('\n'); + response = (this->serialL)->readStringUntil('\n'); #if DEBUG_LEVEL == 3 - USB_Serial.println(response); // DEBUG + SERIAL_D(response); // DEBUG #endif if ( (index = response.indexOf("Wait ACK")) != -1 ){ - USB_Serial.println("Waiting for ACK..."); + SERIAL_D("Waiting for ACK..."); } } - USB_Serial.println(""); + SERIAL_D(""); } /// @brief Allow to debug or consume characters from the LoRaE5 module @@ -332,12 +376,12 @@ void LORAE5::readResponse(uint32_t timeOut, bool debug){ uint32_t tstart = millis(); while (millis()-tstart < timeOut){ - if(LoRa_Serial.available() > 0) { + if((this->serialL)->available() > 0) { if (debug == DEBUG){ - USB_Serial.print((char)LoRa_Serial.read()); + (this->serialD)->print((char)(this->serialL)->read()); } else{ - LoRa_Serial.read(); + (this->serialL)->read(); } } } @@ -355,11 +399,11 @@ bool LORAE5::checkResponse(uint32_t timeOut, char *strCheck, bool debug){ bool success = false; while (millis()-tstart < timeOut){ - if(LoRa_Serial.available() > 0) { - c = LoRa_Serial.read(); + if((this->serialL)->available() > 0) { + c = (this->serialL)->read(); if (debug == DEBUG){ - USB_Serial.print(c); + (this->serialD)->print(c); } if( c == strCheck[i] ){ @@ -401,7 +445,7 @@ void LORAE5::getPortDown(String response){ } uint8_t portDown = strPortDown.toInt(); - USB_Serial.println("- Port " + String(portDown)); + SERIAL_D("- Port " + String(portDown)); this->portDown = portDown; } @@ -426,16 +470,16 @@ void LORAE5::getPayloadDown(uint8_t* payloadDown, uint8_t* sizePayloadDown, Stri String strByte =strPayloadDown.substring(i * 2, i * 2 + 2); payloadDown[i] = strtoul(strByte.c_str(), nullptr, 16); } - USB_Serial.print("- Payload DOWN "); + (this->serialD)->print("- Payload DOWN "); for (uint8_t i = 0 ; i < *sizePayloadDown ; i++){ - USB_Serial.print(" 0x"); + (this->serialD)->print(" 0x"); if (payloadDown[i] < 0x10){ - USB_Serial.print('0'); + (this->serialD)->print('0'); } - USB_Serial.print(payloadDown[i], HEX); - USB_Serial.print(" "); + (this->serialD)->print(payloadDown[i], HEX); + (this->serialD)->print(" "); } - USB_Serial.println(""); + SERIAL_D(""); } /// @brief Displays downlink channel @@ -454,11 +498,11 @@ void LORAE5::getChannelDown(String response){ uint8_t channelDown = strChannelDown.toInt(); if (channelDown == 0){ - USB_Serial.println("- Slot RXC"); + SERIAL_D("- Slot RXC"); } else { - USB_Serial.println("- Slot RX" + String(channelDown)); + SERIAL_D("- Slot RX" + String(channelDown)); } - USB_Serial.println(""); + SERIAL_D(""); } /// @brief Updates the Device Class @@ -476,35 +520,35 @@ uint8_t LORAE5::getADR(){ /// @brief Summarizes device parameters void LORAE5::printInfo(){ #ifndef ARDUINO_AVR_LEONARDO - USB_Serial.println("# For more information visit : https://github.com/SylvainMontagny/LoRaE5"); + SERIAL_D("# For more information visit : https://github.com/SylvainMontagny/LoRaE5"); - if(this->mode == OTAA) {USB_Serial.println("> OTAA");} - else {USB_Serial.println("> ABP");} + if(this->mode == OTAA) {SERIAL_D("> OTAA");} + else {SERIAL_D("> ABP");} - if(this->devClass == CLASS_A) {USB_Serial.println("> CLASS_A");} - if(this->devClass == CLASS_C) {USB_Serial.println("> CLASS_C");} + if(this->devClass == CLASS_A) {SERIAL_D("> CLASS_A");} + if(this->devClass == CLASS_C) {SERIAL_D("> CLASS_C");} - USB_Serial.println("> SF " + String(this->sf)); + SERIAL_D("> SF " + String(this->sf)); - if(this->adr == true) {USB_Serial.println("> ADR ON");} - else {USB_Serial.println("> ADR OFF");} + if(this->adr == true) {SERIAL_D("> ADR ON");} + else {SERIAL_D("> ADR OFF");} - USB_Serial.println(((this->confirmed == CONF)? String("> Confirmed") : String("> Unconfirmed"))); - USB_Serial.println("> Port " + String(this->portUp)); - USB_Serial.println(); - USB_Serial.println( "* DevEUI 0x " + this->devEUI); + SERIAL_D(((this->confirmed == CONF)? String("> Confirmed") : String("> Unconfirmed"))); + SERIAL_D("> Port " + String(this->portUp)); + SERIAL_D(); + SERIAL_D( "* DevEUI 0x " + this->devEUI); if (this->mode == ABP) { - USB_Serial.println("* DevAddr 0x " + this->devAddr); - USB_Serial.println("* NwkSKey 0x " + this->nwkSKey); - USB_Serial.println("* AppSKey 0x " + this->appSKey); + SERIAL_D("* DevAddr 0x " + this->devAddr); + SERIAL_D("* NwkSKey 0x " + this->nwkSKey); + SERIAL_D("* AppSKey 0x " + this->appSKey); } if (this->mode == OTAA){ - USB_Serial.println("* AppKey 0x " + this->appKey); - USB_Serial.println("* AppEUI-JoinEUI 0x " + this->appEUI); + SERIAL_D("* AppKey 0x " + this->appKey); + SERIAL_D("* AppEUI-JoinEUI 0x " + this->appEUI); } - USB_Serial.println(); + SERIAL_D(); #endif } @@ -518,12 +562,12 @@ uint8_t LORAE5::awaitForDownlinkClass_A(uint8_t* payloadDown, uint8_t* sizePaylo bool isDoneReceived = false; bool isAckReceived = false; - LoRa_Serial.setTimeout(500); + (this->serialL)->setTimeout(500); do{ - response += LoRa_Serial.readStringUntil('\n'); + response += (this->serialL)->readStringUntil('\n'); #if DEBUG_LEVEL == 4 - USB_Serial.println(response); // DEBUG + SERIAL_D(response); // DEBUG #endif /****** Test Done *******/ @@ -536,18 +580,18 @@ uint8_t LORAE5::awaitForDownlinkClass_A(uint8_t* payloadDown, uint8_t* sizePaylo //Confirmed part if ((confirmed == true)){ if (index = response.indexOf("ACK Received") != -1 ){ - USB_Serial.println("ACK received"); + SERIAL_D("ACK received"); isAckReceived = true; } else { - USB_Serial.println("No ACK received\n"); + SERIAL_D("No ACK received\n"); return RET_NO_ACK; } } //Processing data received if ((index = response.indexOf("PORT: ")) != -1) { - USB_Serial.println("Receiving Data Down:"); + SERIAL_D("Receiving Data Down:"); getPortDown(response); getPayloadDown(payloadDown, sizePayloadDown, response); getChannelDown(response); @@ -555,16 +599,16 @@ uint8_t LORAE5::awaitForDownlinkClass_A(uint8_t* payloadDown, uint8_t* sizePaylo } else if ( ((index = response.indexOf("RXWIN")) != -1) && (isAckReceived == false) ) { - USB_Serial.println("MAC command received :"); + SERIAL_D("MAC command received :"); getChannelDown(response); return RET_NO_DOWNLINK; } else { if(isAckReceived == false){ - USB_Serial.println("No Class_A Data Received."); + SERIAL_D("No Class_A Data Received."); } - USB_Serial.println(); + SERIAL_D(); return RET_NO_DOWNLINK; } @@ -580,20 +624,20 @@ uint8_t LORAE5::awaitForDownlinkClass_C(uint8_t* payloadDown, uint8_t* sizePaylo bool isDoneReceived = false; uint32_t startTime = millis(); - LoRa_Serial.setTimeout(500); + (this->serialL)->setTimeout(500); #ifndef ARDUINO_AVR_LEONARDO if( this->SEND_BY_PUSH_BUTTON == true ){ - USB_Serial.println("> Press 't' or receive a downlink.\n"); + SERIAL_D("> Press 't' or receive a downlink.\n"); }else if( this->SEND_BY_PUSH_BUTTON == false ){ - USB_Serial.println("> Press 't', receive a downlink or wait " + String(this->FRAME_DELAY) + String(" ms.\n")); + SERIAL_D("> Press 't', receive a downlink or wait " + String(this->FRAME_DELAY) + String(" ms.\n")); } #endif do{ - response += LoRa_Serial.readStringUntil('\n'); + response += (this->serialL)->readStringUntil('\n'); #if DEBUG_LEVEL == 4 - USB_Serial.println(response); // DEBUG + SERIAL_D(response); // DEBUG #endif /****** Test Done *******/ @@ -602,18 +646,18 @@ uint8_t LORAE5::awaitForDownlinkClass_C(uint8_t* payloadDown, uint8_t* sizePaylo } /****** Test 't' : transmission request *******/ - if ( USB_Serial.available() > 0 ) { - char userInput = USB_Serial.read(); + if ( (this->serialD)->available() > 0 ) { + char userInput = (this->serialD)->read(); if (userInput == 't' || userInput == 'T') { - USB_Serial.println("# User input 't'.\n"); + SERIAL_D("# User input 't'.\n"); return RET_T; } } /****** Test Timeout *******/ if ((this->SEND_BY_PUSH_BUTTON == false) && ((millis() - startTime) >= (this->FRAME_DELAY))){ - USB_Serial.println("No Class_C Data Received.\n"); - USB_Serial.println("# Timeout reached.\n"); + SERIAL_D("No Class_C Data Received.\n"); + SERIAL_D("# Timeout reached.\n"); return RET_TIMEOUT; } @@ -621,7 +665,7 @@ uint8_t LORAE5::awaitForDownlinkClass_C(uint8_t* payloadDown, uint8_t* sizePaylo //Processing data received if ((index = response.indexOf("PORT: ")) != -1) { - USB_Serial.println("Receiving Data Down:"); + SERIAL_D("Receiving Data Down:"); getPortDown(response); getPayloadDown(payloadDown, sizePayloadDown, response); getChannelDown(response); @@ -633,39 +677,39 @@ uint8_t LORAE5::awaitForDownlinkClass_C(uint8_t* payloadDown, uint8_t* sizePaylo /// @return Downlink data information (RET_T/RET_TIMEOUT) uint8_t LORAE5::sleep(){ uint32_t startTime = millis(); - LoRa_Serial.println("AT+LOWPOWER"); - String response = LoRa_Serial.readStringUntil('\n'); + SERIAL_L("AT+LOWPOWER"); + String response = (this->serialL)->readStringUntil('\n'); readResponse(5, NO_DEBUG); if (this->SEND_BY_PUSH_BUTTON == false) { while((millis() - startTime) < (this->FRAME_DELAY)){ - if (USB_Serial.available() > 0) { - char userInput = USB_Serial.read(); + if ((this->serialD)->available() > 0) { + char userInput = (this->serialD)->read(); if (userInput == 't' || userInput == 'T') { - LoRa_Serial.println("WAKE-UP"); - response = LoRa_Serial.readStringUntil('\n'); + SERIAL_L("WAKE-UP"); + response = (this->serialL)->readStringUntil('\n'); readResponse(5,NO_DEBUG); - USB_Serial.println("# User input 't'.\n"); + SERIAL_D("# User input 't'.\n"); return RET_T; } } } - LoRa_Serial.println("WAKE-UP"); - response = LoRa_Serial.readStringUntil('\n'); + SERIAL_L("WAKE-UP"); + response = (this->serialL)->readStringUntil('\n'); readResponse(5,NO_DEBUG); - USB_Serial.println("# Timeout reached.\n"); + SERIAL_D("# Timeout reached.\n"); return RET_TIMEOUT; } else { bool userTest = false; while (userTest == false){ - if (USB_Serial.available() > 0) { - char userInput = USB_Serial.read(); + if ((this->serialD)->available() > 0) { + char userInput = (this->serialD)->read(); if (userInput == 't' || userInput == 'T') { - LoRa_Serial.println("WAKE-UP"); - response = LoRa_Serial.readStringUntil('\n'); + SERIAL_L("WAKE-UP"); + response = (this->serialL)->readStringUntil('\n'); readResponse(5,NO_DEBUG); userTest = true; - USB_Serial.println("# User input 't'.\n"); + SERIAL_D("# User input 't'.\n"); return RET_T; } } @@ -678,18 +722,18 @@ void LORAE5::setFrequencyBand(){ String response; if ((this->region) == EU868){ - LoRa_Serial.println("AT+DR=EU868"); - response = LoRa_Serial.readStringUntil('\n'); + SERIAL_L("AT+DR=EU868"); + response = (this->serialL)->readStringUntil('\n'); } if ((this->region) == US915){ - LoRa_Serial.println("AT+DR=US915"); - response = LoRa_Serial.readStringUntil('\n'); + SERIAL_L("AT+DR=US915"); + response = (this->serialL)->readStringUntil('\n'); } #if DEBUG_LEVEL == 5 - LoRa_Serial.println("AT+CH"); - response = LoRa_Serial.readStringUntil('\n'); - USB_Serial.println(response); + SERIAL_L("AT+CH"); + response = (this->serialL)->readStringUntil('\n'); + SERIAL_D(response); #endif } \ No newline at end of file diff --git a/src/lorae5.h b/src/lorae5.h index 77ca43b..3ca7683 100644 --- a/src/lorae5.h +++ b/src/lorae5.h @@ -1,6 +1,5 @@ -#include -#define USB_Serial Serial -#define LoRa_Serial Serial1 +#define SERIAL_D(x) this->serialD->println(x) +#define SERIAL_L(x) this->serialL->println(x) #define EU868 0 #define US915 1 @@ -28,7 +27,7 @@ #define UNCONF false #define _HEXA 0 -#define _STRING 1 +#define _STRING 1 enum RETURN { RET_DOWNLINK, RET_NO_DOWNLINK, RET_NO_ACK, RET_T, RET_TIMEOUT }; @@ -47,6 +46,18 @@ class LORAE5{ uint8_t portUp; uint8_t portDown; +#if defined(ARDUINO_AVR_LEONARDO) || defined(ARDUINO_WIO_TERMINAL) + Serial_* serialD; +#else + HardwareSerial* serialD; +#endif + +#if defined(ARDUINO_WIO_TERMINAL) + Uart* serialL; +#else + HardwareSerial* serialL; +#endif + String devEUI; String devAddr; String nwkSKey; @@ -88,8 +99,17 @@ class LORAE5{ public: LORAE5(String devEUI, String appEUI, String appKey, String devAddr, String nwkSKey, String appSKey); - void setup(uint8_t band, bool mode, uint8_t devClass, uint8_t sf, bool adr, bool messageType, uint8_t portUp, bool SEND_BY_PUSH_BUTTON, uint32_t FRAME_DELAY); - void printInfo(); + +#if defined(ARDUINO_AVR_LEONARDO) + void setup_hardware(Serial_* myDebugSerial, HardwareSerial* myLoRaSerial); +#elif defined(ARDUINO_WIO_TERMINAL) +void setup_hardware(Serial_* myDebugSerial, Uart* myLoRaSerial); +#else + void setup_hardware(HardwareSerial* myDebugSerial, HardwareSerial* myLoRaSerial); +#endif + + void setup_lorawan(uint8_t band, bool mode, uint8_t devClass, uint8_t sf, bool adr, bool messageType, uint8_t portUp, bool SEND_BY_PUSH_BUTTON, uint32_t FRAME_DELAY); + void printInfo(void); bool join(void); @@ -98,4 +118,4 @@ class LORAE5{ uint8_t awaitForDownlinkClass_C(uint8_t* payloadDown, uint8_t* sizePayloadDown); uint8_t sleep(void); -}; +}; \ No newline at end of file