Ebyte LoRa E22 device for Arduino, esp32 or esp8266: power-saving WOR and structured data – 5
Now we’re looking at Wake On Radio (WOR) and power-saving, one of the essential features of our E22 UART LoRa device based on popular Semtech’s SX1262, SX1268 RF chips.
Then we’ll understand how to manage complex structures that are better optimized than string format data.
Here a selection of LoRa devices AliExpress (433MHz 5.5Km) - AliExpress (433MHz 10Km) - AliExpress (868MHz 915Mhz 5.5Km) - AliExpress (868MHz 915Mhz 10Km)
If you have trouble with the device freeze, you must put a pull-up 4.7k resistor or better connect to the device AUX pin.
These devices, respect E32 and E220 have a different management of WOR and sleep, you must set M0 and M1 for receiver and sender at the same manner.
Mode | M1 | M0 | Explanation |
---|---|---|---|
Normal | 0 | 0 | UART and wireless channel are open, transparent transmission is on (Supports configuration over air via special command) |
WOR Mode | 0 | 1 | Can be defined as WOR transmitter and WOR receiver |
Configuration mode | 1 | 0 | Users can access the register through the serial port to control the working state of the module |
Deep sleep mode | 1 | 1 | Sleep mode |
So we need to connect the sending device in WOR mode.
WOR Cycle
A critical configuration parameter is WOR Cycle, for the sender is essential because It adds a long preamble to the message (long as wake time), the receiver use wake time as a pull interval time check.
So if the receiver checks every 2000ms (polling time) if there is a message, the sender adds a 2000ms preamble. The receiver intercepts the message preamble, waits for the actual message to read It, and returns to power save mode.
So If you want to maximize the power save, you must put minimal WOR Cycle. If you want more efficiency, you must do the inverse.
The sender and receiver in this device must have the same WOR Cycle.
Here is the configuration for the WOR transmitter:
configuration.ADDL = 0x02;
configuration.ADDH = 0x00;
configuration.NETID = 0x00;
configuration.CHAN = 23;
configuration.SPED.uartBaudRate = UART_BPS_9600;
configuration.SPED.airDataRate = AIR_DATA_RATE_010_24;
configuration.SPED.uartParity = MODE_00_8N1;
configuration.OPTION.subPacketSetting = SPS_240_00;
configuration.OPTION.RSSIAmbientNoise = RSSI_AMBIENT_NOISE_DISABLED;
configuration.OPTION.transmissionPower = POWER_22;
configuration.TRANSMISSION_MODE.enableRSSI = RSSI_DISABLED;
configuration.TRANSMISSION_MODE.fixedTransmission = FT_FIXED_TRANSMISSION;
configuration.TRANSMISSION_MODE.enableRepeater = REPEATER_DISABLED;
configuration.TRANSMISSION_MODE.enableLBT = LBT_DISABLED;
configuration.TRANSMISSION_MODE.WORTransceiverControl = WOR_TRANSMITTER;
configuration.TRANSMISSION_MODE.WORPeriod = WOR_2000_011;
Sending sketch:
/*
* EBYTE LoRa E22
* Send a string message to a fixed point ADDH ADDL CHAN 0 3 23 with WOR preamble
* Write a string on serial monitor or reset to resend default value.
*
* You must set WOR SENDER configuration
*
* Send a fixed point message, you must check that the transmitter and receiver have different
* CHANNEL ADDL or ADDH, check down the correct configuration
*
* Pai attention e22 support RSSI, if you want use that functionality you must enable RSSI on configuration
* configuration.TRANSMISSION_MODE.enableRSSI = RSSI_ENABLED;
*
* and uncomment #define ENABLE_RSSI true in this sketch
*
* Renzo Mischianti <https://mischianti.org>
* https://mischianti.org/category/my-libraries/ebyte-lora-e22-devices/
*
* E22 ----- WeMos D1 mini ----- esp32 ----- Arduino Nano 33 IoT ----- Arduino MKR ----- ArduinoUNO
* M0 ----- D7 (or 3.3v) ----- 19 (or 3.3v) ----- 4 (or 3.3v) ----- 2 (or 3.3v) ----- 7 Volt div (or 3.3v)
* M1 ----- D6 (or GND) ----- 21 (or GND) ----- 6 (or GND) ----- 4 (or GND) ----- 6 Volt div (or GND)
* TX ----- D3 (PullUP) ----- TX2 (PullUP) ----- TX1 (PullUP) ----- 14 (PullUP) ----- 4 (PullUP)
* RX ----- D4 (PullUP) ----- RX2 (PullUP) ----- RX1 (PullUP) ----- 13 (PullUP) ----- 5 Volt div (PullUP)
* AUX ----- D5 (PullUP) ----- 15 (PullUP) ----- 2 (PullUP) ----- 0 (PullUP) ----- 3 (PullUP)
* VCC ----- 3.3v/5v ----- 3.3v/5v ----- 3.3v/5v ----- 3.3v/5v ----- 3.3v/5v
* GND ----- GND ----- GND ----- GND ----- GND ----- GND
*
*/
// WOR SENDER configuration
#define DESTINATION_ADDL 3
// If you want use RSSI uncomment //#define ENABLE_RSSI true
// and use relative configuration with RSSI enabled
// #define ENABLE_RSSI true
#include "Arduino.h"
#include "LoRa_E22.h"
// ---------- esp8266 pins --------------
//LoRa_E22 e22ttl(RX, TX, AUX, M0, M1); // Arduino RX <-- e220 TX, Arduino TX --> e220 RX
//LoRa_E22 e22ttl(D3, D4, D5, D7, D6); // Arduino RX <-- e220 TX, Arduino TX --> e220 RX AUX M0 M1
//LoRa_E22 e22ttl(D2, D3); // Config without connect AUX and M0 M1
//#include <SoftwareSerial.h>
//SoftwareSerial mySerial(D2, D3); // Arduino RX <-- e220 TX, Arduino TX --> e220 RX
//LoRa_E22 e22ttl(&mySerial, D5, D7, D6); // AUX M0 M1
// -------------------------------------
// ---------- Arduino pins --------------
//LoRa_E22 e22ttl(4, 5, 3, 7, 6); // Arduino RX <-- e220 TX, Arduino TX --> e220 RX AUX M0 M1
//LoRa_E22 e22ttl(4, 5); // Config without connect AUX and M0 M1
//#include <SoftwareSerial.h>
//SoftwareSerial mySerial(4, 5); // Arduino RX <-- e220 TX, Arduino TX --> e220 RX
//LoRa_E22 e22ttl(&mySerial, 3, 7, 6); // AUX M0 M1
// -------------------------------------
// ------------- Arduino Nano 33 IoT -------------
LoRa_E22 e22ttl(&Serial1, 2, 4, 6); // RX AUX M0 M1
// -------------------------------------------------
// ------------- Arduino MKR WiFi 1010 -------------
// LoRa_E22 e22ttl(&Serial1, 0, 2, 4); // RX AUX M0 M1
// -------------------------------------------------
// ---------- esp32 pins --------------
// LoRa_E22 e22ttl(&Serial2, 15, 21, 19); // RX AUX M0 M1
//LoRa_E22 e22ttl(&Serial2, 22, 4, 18, 21, 19, UART_BPS_RATE_9600); // esp32 RX <-- e220 TX, esp32 TX --> e220 RX AUX M0 M1
// -------------------------------------
void setup() {
Serial.begin(9600);
delay(500);
// Startup all pins and UART
e22ttl.begin();
e22ttl.setMode(MODE_1_WOR);
Serial.println("Hi, I'm going to send message!");
// Send message
ResponseStatus rs = e22ttl.sendFixedMessage(0, DESTINATION_ADDL, 23, "Hello, world?");
// Check If there is some problem of succesfully send
Serial.println(rs.getResponseDescription());
e22ttl.setMode(MODE_0_NORMAL);
}
void loop() {
// If something available
if (e22ttl.available()>1) {
// read the String message
#ifdef ENABLE_RSSI
ResponseContainer rc = e22ttl.receiveMessageRSSI();
#else
ResponseContainer rc = e22ttl.receiveMessage();
#endif
// Is something goes wrong print error
if (rc.status.code!=1){
Serial.println(rc.status.getResponseDescription());
}else{
// Print the data received
Serial.println(rc.status.getResponseDescription());
Serial.println(rc.data);
#ifdef ENABLE_RSSI
Serial.print("RSSI: "); Serial.println(rc.rssi, DEC);
#endif
}
}
if (Serial.available()) {
String input = Serial.readString();
ResponseStatus rsSend = e22ttl.sendFixedMessage(0, DESTINATION_ADDL, 23, "We have received the message!");
// Check If there is some problem of succesfully send
Serial.println(rsSend.getResponseDescription());
}
}
Now the receiver configuration:
configuration.ADDL = 0x03;
configuration.ADDH = 0x00;
configuration.NETID = 0x00;
configuration.CHAN = 23;
configuration.SPED.uartBaudRate = UART_BPS_9600;
configuration.SPED.airDataRate = AIR_DATA_RATE_010_24;
configuration.SPED.uartParity = MODE_00_8N1;
configuration.OPTION.subPacketSetting = SPS_240_00;
configuration.OPTION.RSSIAmbientNoise = RSSI_AMBIENT_NOISE_DISABLED;
configuration.OPTION.transmissionPower = POWER_22;
configuration.TRANSMISSION_MODE.enableRSSI = RSSI_DISABLED;
configuration.TRANSMISSION_MODE.fixedTransmission = FT_FIXED_TRANSMISSION;
configuration.TRANSMISSION_MODE.enableRepeater = REPEATER_DISABLED;
configuration.TRANSMISSION_MODE.enableLBT = LBT_DISABLED;
configuration.TRANSMISSION_MODE.WORTransceiverControl = WOR_RECEIVER;
configuration.TRANSMISSION_MODE.WORPeriod = WOR_2000_011;
And receiving sketch with wake up for ESP32:
/*
* EBYTE LoRa E22
* Stay in sleep mode and wait a wake up WOR message
* You must set WOR RECEIVER configuration
*
* You must configure the address with 0 3 23 with WOR receiver enable
* and pay attention that WOR period must be the same of sender
*
* Pai attention e22 support RSSI, if you want use that functionality you must enable RSSI on configuration
* configuration.TRANSMISSION_MODE.enableRSSI = RSSI_ENABLED;
*
* and uncomment #define ENABLE_RSSI true in this sketch
*
* https://mischianti.org
*
* E22 ----- WeMos D1 mini ----- esp32 ----- Arduino Nano 33 IoT ----- Arduino MKR ----- ArduinoUNO
* M0 ----- D7 (or 3.3v) ----- 19 (or 3.3v) ----- 4 (or 3.3v) ----- 2 (or 3.3v) ----- 7 Volt div (or 3.3v)
* M1 ----- D6 (or GND) ----- 21 (or GND) ----- 6 (or GND) ----- 4 (or GND) ----- 6 Volt div (or GND)
* TX ----- D3 (PullUP) ----- TX2 (PullUP) ----- TX1 (PullUP) ----- 14 (PullUP) ----- 4 (PullUP)
* RX ----- D4 (PullUP) ----- RX2 (PullUP) ----- RX1 (PullUP) ----- 13 (PullUP) ----- 5 Volt div (PullUP)
* AUX ----- D5 (PullUP) ----- 15 (PullUP) ----- 2 (PullUP) ----- 0 (PullUP) ----- 3 (PullUP)
* VCC ----- 3.3v/5v ----- 3.3v/5v ----- 3.3v/5v ----- 3.3v/5v ----- 3.3v/5v
* GND ----- GND ----- GND ----- GND ----- GND ----- GND
*
*/
// with this DESTINATION_ADDL 2 you must set
// WOR SENDER configuration to the other device and
// WOR RECEIVER to this device
#define DESTINATION_ADDL 2
// If you want use RSSI uncomment //#define ENABLE_RSSI true
// and use relative configuration with RSSI enabled
//#define ENABLE_RSSI true
#include "Arduino.h"
#include "LoRa_E22.h"
#include <WiFi.h>
#include "soc/rtc_cntl_reg.h"
#include "soc/rtc.h"
#include "driver/rtc_io.h"
#define FPM_SLEEP_MAX_TIME 0xFFFFFFF
void callback() {
Serial.println("Callback");
Serial.flush();
}
// ---------- esp8266 pins --------------
//LoRa_E22 e22ttl(RX, TX, AUX, M0, M1); // Arduino RX <-- e220 TX, Arduino TX --> e220 RX
//LoRa_E22 e22ttl(D3, D4, D5, D7, D6); // Arduino RX <-- e220 TX, Arduino TX --> e220 RX AUX M0 M1
//LoRa_E22 e22ttl(D2, D3); // Config without connect AUX and M0 M1
//#include <SoftwareSerial.h>
//SoftwareSerial mySerial(D2, D3); // Arduino RX <-- e220 TX, Arduino TX --> e220 RX
//LoRa_E22 e22ttl(&mySerial, D5, D7, D6); // AUX M0 M1
// -------------------------------------
// ---------- Arduino pins --------------
//LoRa_E22 e22ttl(4, 5, 3, 7, 6); // Arduino RX <-- e220 TX, Arduino TX --> e220 RX AUX M0 M1
//LoRa_E22 e22ttl(4, 5); // Config without connect AUX and M0 M1
//#include <SoftwareSerial.h>
//SoftwareSerial mySerial(4, 5); // Arduino RX <-- e220 TX, Arduino TX --> e220 RX
//LoRa_E22 e22ttl(&mySerial, 3, 7, 6); // AUX M0 M1
// -------------------------------------
// ------------- Arduino Nano 33 IoT -------------
// LoRa_E22 e22ttl(&Serial1, 2, 4, 6); // RX AUX M0 M1
// -------------------------------------------------
// ------------- Arduino MKR WiFi 1010 -------------
// LoRa_E22 e22ttl(&Serial1, 0, 2, 4); // RX AUX M0 M1
// -------------------------------------------------
// ---------- esp32 pins --------------
LoRa_E22 e22ttl(&Serial2, 15, 21, 19); // RX AUX M0 M1
//LoRa_E22 e22ttl(&Serial2, 22, 4, 18, 21, 19, UART_BPS_RATE_9600); // esp32 RX <-- e220 TX, esp32 TX --> e220 RX AUX M0 M1
// -------------------------------------
//The setup function is called once at startup of the sketch
void setup()
{
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB
}
delay(100);
e22ttl.begin();
e22ttl.setMode(MODE_1_WOR);
delay(1000);
Serial.println();
Serial.println("Start sleep!");
delay(100);
// if (ESP_OK == gpio_hold_en(GPIO_NUM_21)){
// Serial.println("HOLD 21");
// }else{
// Serial.println("NO HOLD 21");
// }
// if (ESP_OK == gpio_hold_en(GPIO_NUM_19)){
// Serial.println("HOLD 19");
// }else{
// Serial.println("NO HOLD 19");
// }
esp_sleep_enable_ext0_wakeup(GPIO_NUM_15,LOW);
// gpio_deep_sleep_hold_en();
//Go to sleep now
Serial.println("Going to sleep now");
delay(100);
esp_light_sleep_start();
delay(1);
// e22ttl.setMode(MODE_0_NORMAL);
// delay(1000);
Serial.println();
Serial.println("Wake and start listening!");
}
// The loop function is called in an endless loop
void loop()
{
if (e22ttl.available() > 1){
Serial.println("Message arrived!");
#ifdef ENABLE_RSSI
ResponseContainer rs = e22ttl.receiveMessageRSSI();
#else
ResponseContainer rs = e22ttl.receiveMessage();
#endif
// First of all get the data
String message = rs.data;
Serial.println(rs.status.getResponseDescription());
Serial.println(message);
e22ttl.setMode(MODE_0_NORMAL);
delay(1000);
e22ttl.sendFixedMessage(0, DESTINATION_ADDL, 23, "We have received the message!");
}
}
Pay attention in this receiver sketch only the LoRa E220 go in sleep mode, so in a real example, you must manage the sleep of the microcontroller. In the following articles, we will check the deep sleep of every microcontroller with detailed examples.
Send complex structure
To send and receive, you must set the normal mode; if you make a complete connection, the library does the correct setting automatically.
M0 | GND (Set normal mode) |
M1 | GND (Set normal mode) |
TX | PIN 2 (PullUP 4,7KΩ) |
RX | PIN 3 (PullUP 4,7KΩ & Voltage divider) |
AUX | Not connected (PullUP 4,7KΩ) |
VCC | 5v |
GND | GND |
and this configuration for Wemos D1 mini:
M0 | GND (Set normal mode) |
M1 | GND (Set normal mode) |
TX | PIN D2 (PullUP 4,7KΩ) |
RX | PIN D3 (PullUP 4,7KΩ) |
AUX | Not connected (PullUP 4,7KΩ) |
VCC | 3.3v/5v |
GND | GND |
ESP-32:
M0 | GND (Set normal mode) |
M1 | GND (Set normal mode) |
RX | TX2 (PullUP 4,7KΩ) |
TX | RX2 (PullUP 4,7KΩ) |
AUX | Not connected (PullUP 4,7KΩ) |
VCC | 3.3v/5v |
GND | GND |
Arduino MKR WiFi 1010:
We can use string as we want, use It as JSON format, and so on, but if you’re going to use structured messages in native mode (byte array) It’s more efficient.
The example code for the sender can be:
struct Message {
char type[5];
char message[8];
float temperature;
};
struct Message message = {"TEMP", ROOM, 19.2};
// Send message
ResponseStatus rs = e22ttl.sendFixedMessage(0, DESTINATION_ADDL, 23, &message, sizeof(Message));
// Check If there is some problem of succesfully send
Serial.println(rs.getResponseDescription());
and to receive:
// If something available
if (e22ttl.available()>1) {
// read the String message
#ifdef ENABLE_RSSI
ResponseStructContainer rsc = e22ttl.receiveMessageRSSI(sizeof(Message));
#else
ResponseStructContainer rsc = e22ttl.receiveMessage(sizeof(Message));
#endif
// Is something goes wrong print error
if (rsc.status.code!=1){
Serial.println(rsc.status.getResponseDescription());
}else{
// Print the data received
Serial.println(rsc.status.getResponseDescription());
struct Message message = *(Message*) rsc.data;
Serial.println(message.type);
Serial.println(message.message);
Serial.println(message.temperature);
#ifdef ENABLE_RSSI
Serial.print("RSSI: "); Serial.println(rsc.rssi, DEC);
#endif
}
}
To manage Sender and Receiver, you can use the FIXED SENDER and FIXED RECEIVER configuration:
Sender:
// ----------------------- FIXED SENDER -----------------------
configuration.ADDL = 0x02;
configuration.ADDH = 0x00;
configuration.NETID = 0x00;
configuration.CHAN = 23;
configuration.SPED.uartBaudRate = UART_BPS_9600;
configuration.SPED.airDataRate = AIR_DATA_RATE_010_24;
configuration.SPED.uartParity = MODE_00_8N1;
configuration.OPTION.subPacketSetting = SPS_240_00;
configuration.OPTION.RSSIAmbientNoise = RSSI_AMBIENT_NOISE_DISABLED;
configuration.OPTION.transmissionPower = POWER_22;
configuration.TRANSMISSION_MODE.enableRSSI = RSSI_DISABLED;
configuration.TRANSMISSION_MODE.fixedTransmission = FT_FIXED_TRANSMISSION;
configuration.TRANSMISSION_MODE.enableRepeater = REPEATER_DISABLED;
configuration.TRANSMISSION_MODE.enableLBT = LBT_DISABLED;
configuration.TRANSMISSION_MODE.WORTransceiverControl = WOR_TRANSMITTER;
configuration.TRANSMISSION_MODE.WORPeriod = WOR_2000_011;
And you must uncomment the relative define in the sketch:
// With FIXED SENDER configuration
#define DESTINATION_ADDL 3
#define ROOM "Kitchen"
Receiver:
// ----------------------- FIXED RECEIVER -----------------------
configuration.ADDL = 0x03;
configuration.ADDH = 0x00;
configuration.NETID = 0x00;
configuration.CHAN = 23;
configuration.SPED.uartBaudRate = UART_BPS_9600;
configuration.SPED.airDataRate = AIR_DATA_RATE_010_24;
configuration.SPED.uartParity = MODE_00_8N1;
configuration.OPTION.subPacketSetting = SPS_240_00;
configuration.OPTION.RSSIAmbientNoise = RSSI_AMBIENT_NOISE_ENABLED;
configuration.OPTION.transmissionPower = POWER_22;
configuration.TRANSMISSION_MODE.enableRSSI = RSSI_DISABLED;
configuration.TRANSMISSION_MODE.fixedTransmission = FT_FIXED_TRANSMISSION;
configuration.TRANSMISSION_MODE.enableRepeater = REPEATER_DISABLED;
configuration.TRANSMISSION_MODE.enableLBT = LBT_DISABLED;
configuration.TRANSMISSION_MODE.WORTransceiverControl = WOR_RECEIVER;
configuration.TRANSMISSION_MODE.WORPeriod = WOR_2000_011;
And you must uncomment the relative define in the sketch
// With FIXED RECEIVER configuration
#define DESTINATION_ADDL 2
#define ROOM "Bathroo"
Complete sender and receiver sketch:
/*
* EBYTE LoRa E22
* Send a structured message to a fixed point ADDH ADDL CHAN 0 3 23
*
* Write the float temperature value on serial (or reset device that send default message)
*
* Send a transparent message, you must check that the transmitter and receiver have the same
* CHANNEL ADDL and ADDH
*
* Pai attention e22 support RSSI, if you want use that functionality you must enable RSSI on configuration
* configuration.TRANSMISSION_MODE.enableRSSI = RSSI_ENABLED;
*
* and uncomment #define ENABLE_RSSI true in this sketch
*
* https://mischianti.org
*
* E22 ----- WeMos D1 mini ----- esp32 ----- Arduino Nano 33 IoT ----- Arduino MKR ----- ArduinoUNO
* M0 ----- D7 (or GND) ----- 19 (or GND) ----- 4 (or GND) ----- 2 (or GND) ----- 7 Volt div (or GND)
* M1 ----- D6 (or GND) ----- 21 (or GND) ----- 6 (or GND) ----- 4 (or GND) ----- 6 Volt div (or GND)
* TX ----- D3 (PullUP) ----- TX2 (PullUP) ----- TX1 (PullUP) ----- 14 (PullUP) ----- 4 (PullUP)
* RX ----- D4 (PullUP) ----- RX2 (PullUP) ----- RX1 (PullUP) ----- 13 (PullUP) ----- 5 Volt div (PullUP)
* AUX ----- D5 (PullUP) ----- 18 (PullUP) ----- 2 (PullUP) ----- 0 (PullUP) ----- 3 (PullUP)
* VCC ----- 3.3v/5v ----- 3.3v/5v ----- 3.3v/5v ----- 3.3v/5v ----- 3.3v/5v
* GND ----- GND ----- GND ----- GND ----- GND ----- GND
*
*/
// with this RECEIVER_ADDL 3 you must set
// FIXED RECEIVER configuration to the other device and
// FIXED SENDER to this device
#define DESTINATION_ADDL 3
// If you want use RSSI uncomment //#define ENABLE_RSSI true
// and use relative configuration with RSSI enabled
#define ENABLE_RSSI true
#include "Arduino.h"
#include "LoRa_E22.h"
// ---------- esp8266 pins --------------
//LoRa_E22 e22ttl(RX, TX, AUX, M0, M1); // Arduino RX <-- e220 TX, Arduino TX --> e220 RX
//LoRa_E22 e22ttl(D3, D4, D5, D7, D6); // Arduino RX <-- e220 TX, Arduino TX --> e220 RX AUX M0 M1
//LoRa_E22 e22ttl(D2, D3); // Config without connect AUX and M0 M1
//#include <SoftwareSerial.h>
//SoftwareSerial mySerial(D2, D3); // Arduino RX <-- e220 TX, Arduino TX --> e220 RX
//LoRa_E22 e22ttl(&mySerial, D5, D7, D6); // AUX M0 M1
// -------------------------------------
// ---------- Arduino pins --------------
//LoRa_E22 e22ttl(4, 5, 3, 7, 6); // Arduino RX <-- e220 TX, Arduino TX --> e220 RX AUX M0 M1
//LoRa_E22 e22ttl(4, 5); // Config without connect AUX and M0 M1
//#include <SoftwareSerial.h>
//SoftwareSerial mySerial(4, 5); // Arduino RX <-- e220 TX, Arduino TX --> e220 RX
//LoRa_E22 e22ttl(&mySerial, 3, 7, 6); // AUX M0 M1
// -------------------------------------
// ------------- Arduino Nano 33 IoT -------------
// LoRa_E22 e22ttl(&Serial1, 2, 4, 6); // RX AUX M0 M1
// -------------------------------------------------
// ------------- Arduino MKR WiFi 1010 -------------
// LoRa_E22 e22ttl(&Serial1, 0, 2, 4); // RX AUX M0 M1
// -------------------------------------------------
// ---------- esp32 pins --------------
LoRa_E22 e22ttl(&Serial2, 15, 21, 19); // RX AUX M0 M1
//LoRa_E22 e22ttl(&Serial2, 22, 4, 18, 21, 19, UART_BPS_RATE_9600); // esp32 RX <-- e220 TX, esp32 TX --> e220 RX AUX M0 M1
// -------------------------------------
struct Message {
char type[5];
char message[8];
byte temperature[4];
} message;
void setup() {
Serial.begin(9600);
delay(500);
// Startup all pins and UART
e22ttl100.begin();
Serial.println("Hi, I'm going to send message!");
struct Message {
char type[5] = "TEMP";
char message[8] = "Kitchen";
byte temperature[4];
} message;
*(float*)(message.temperature) = 19.2;
// Send message
ResponseStatus rs = e22ttl100.sendFixedMessage(0, DESTINATION_ADDL, 23, &message, sizeof(Message));
// Check If there is some problem of succesfully send
Serial.println(rs.getResponseDescription());
}
void loop() {
// If something available
if (e22ttl100.available()>1) {
// read the String message
#ifdef ENABLE_RSSI
ResponseStructContainer rsc = e22ttl100.receiveMessageRSSI(sizeof(Message));
#else
ResponseStructContainer rsc = e22ttl100.receiveMessage(sizeof(Message));
#endif
// Is something goes wrong print error
if (rsc.status.code!=1){
Serial.println(rsc.status.getResponseDescription());
}else{
// Print the data received
Serial.println(rsc.status.getResponseDescription());
struct Message message = *(Message*) rsc.data;
Serial.println(message.type);
Serial.println(message.message);
Serial.println(*(float*)(message.temperature));
#ifdef ENABLE_RSSI
Serial.print("RSSI: "); Serial.println(rsc.rssi, DEC);
#endif
}
}
if (Serial.available()) {
struct Message {
char type[5] = "TEMP";
char message[8] = "Kitchen";
byte temperature[4];
} message;
*(float*)(message.temperature) = Serial.parseFloat();
// Send message
ResponseStatus rs = e22ttl100.sendFixedMessage(0, DESTINATION_ADDL, 23, &message, sizeof(Message));
// Check If there is some problem of succesfully send
Serial.println(rs.getResponseDescription());
}
}
But real life is not so simple, and probably you have multiple sensors with different structures in your home, so you need to receive various structures. A possible solution is to read the first part of the structure and instantiate the rest as you want.
Read a piece of structure
So if you would have the TYPE of structure you are going to read:
// read the String message
char type[5]; // first part of structure
ResponseContainer rs = e22ttl.receiveInitialMessage(sizeof(type));
String typeStr = rs.data;
With this information, we can create specified structures from different devices, for example:
struct MessageTemperature {
char type[5];
char message[8];
byte temperature[4];
};
[...]
struct MessageTemperature messageT = { "TEMP", ROOM, 0 };
*(float*)(messageT.temperature) = 19.2;
// Send message
ResponseStatus rsT = e22ttl.sendFixedMessage(0, DESTINATION_ADDL, 23, &messageT, sizeof(MessageTemperature));
// Check If there is some problem of succesfully send
Serial.println(rsT.getResponseDescription());
or
struct MessageHumidity {
char type[5];
char message[8];
byte humidity;
};
[...]
struct MessageHumidity message = { "HUMI", ROOM, 80 };
// Send message
ResponseStatus rs = e22ttl.sendFixedMessage(0, DESTINATION_ADDL, 23, &message, sizeof(MessageHumidity));
// Check If there is some problem of succesfully send
Serial.println(rs.getResponseDescription());
And so you can load specified structure from the receiver:
// If something available
if (e22ttl.available() > 1) {
// read the String message
char type[5]; // first part of structure
ResponseContainer rs = e220ttl.receiveInitialMessage(sizeof(type));
String typeStr = rs.data;
// Is something goes wrong print error
if (rs.status.code != 1) {
Serial.println(rs.status.getResponseDescription());
} else {
Serial.println(typeStr);
if (typeStr == "TEMP") {
struct MessageTemperaturePartial {
char message[8];
byte temperature[4];
};
ResponseStructContainer rsc = e22ttl.receiveMessage( sizeof(MessageTemperaturePartial));
struct MessageTemperaturePartial message = *(MessageTemperaturePartial*) rsc.data;
Serial.println(*(float*)(message.temperature));
Serial.println(message.message);
rsc.close();
} else if (typeStr == "HUMI") {
struct MessageHumidityPartial {
char message[8];
byte humidity;
};
ResponseStructContainer rsc = e22ttl.receiveMessage(sizeof(MessageHumidityPartial));
struct MessageHumidityPartial message = *(MessageHumidityPartial*) rsc.data;
Serial.println(message.humidity);
Serial.println(message.message);
rsc.close();
} else {
Serial.println("Something goes wrong!!");
}
}
}
So with a sender sketches that send humidity and temperature, we can read the first part, the type, and execute the correct code to retrieve the rest of the data:
/*
* EBYTE LoRa E22
* send a structured message to the device that have ADDH ADDL CHAN -> 0 DESTINATION_ADDL 23
*
* The receiver read the first part of the packet and undestand the type.
* If the type is HUMI read the message and the humidity as int
* else read the temperature as float.
* I use byte array because some microcontroller can have different size for float
*
* You must configure 2 device: one as SENDER (with FIXED SENDER config) and uncomment the relative
* define with the correct DESTINATION_ADDL, and one as RECEIVER (with FIXED RECEIVER config)
* and uncomment the relative define with the correct DESTINATION_ADDL.
*
* Write a string on serial monitor or reset to resend default value.
*
* You must uncommend the correct constructor and set the correct AUX_PIN define.
*
* by Renzo Mischianti <https://mischianti.org>
*
* https://mischianti.org
*
* E22 ----- WeMos D1 mini ----- esp32 ----- Arduino Nano 33 IoT ----- Arduino MKR ----- ArduinoUNO
* M0 ----- D7 (or GND) ----- 19 (or GND) ----- 4 (or GND) ----- 2 (or GND) ----- 7 Volt div (or GND)
* M1 ----- D6 (or GND) ----- 21 (or GND) ----- 6 (or GND) ----- 4 (or GND) ----- 6 Volt div (or GND)
* TX ----- D3 (PullUP) ----- TX2 (PullUP) ----- TX1 (PullUP) ----- 14 (PullUP) ----- 4 (PullUP)
* RX ----- D4 (PullUP) ----- RX2 (PullUP) ----- RX1 (PullUP) ----- 13 (PullUP) ----- 5 Volt div (PullUP)
* AUX ----- D5 (PullUP) ----- 15 (PullUP) ----- 2 (PullUP) ----- 0 (PullUP) ----- 3 (PullUP)
* VCC ----- 3.3v/5v ----- 3.3v/5v ----- 3.3v/5v ----- 3.3v/5v ----- 3.3v/5v
* GND ----- GND ----- GND ----- GND ----- GND ----- GND
*
*/
#define MESSAGE_TYPE "HUMI"
// With FIXED SENDER configuration
#define DESTINATION_ADDL 3
#define ROOM "Kitchen"
// With FIXED RECEIVER configuration
//#define DESTINATION_ADDL 2
//#define ROOM "Bathroo"
// If you want use RSSI uncomment //#define ENABLE_RSSI true
// and use relative configuration with RSSI enabled
// #define ENABLE_RSSI true
#include "Arduino.h"
#include "LoRa_E22.h"
// ---------- esp8266 pins --------------
//LoRa_E22 e22ttl(RX, TX, AUX, M0, M1); // Arduino RX <-- e22 TX, Arduino TX --> e22 RX
//LoRa_E22 e22ttl(D3, D4, D5, D7, D6); // Arduino RX <-- e22 TX, Arduino TX --> e22 RX AUX M0 M1
//LoRa_E22 e22ttl(D2, D3); // Config without connect AUX and M0 M1
//#include <SoftwareSerial.h>
//SoftwareSerial mySerial(D2, D3); // Arduino RX <-- e22 TX, Arduino TX --> e22 RX
//LoRa_E22 e22ttl(&mySerial, D5, D7, D6); // AUX M0 M1
// -------------------------------------
// ---------- Arduino pins --------------
//LoRa_E22 e22ttl(4, 5, 3, 7, 6); // Arduino RX <-- e22 TX, Arduino TX --> e22 RX AUX M0 M1
//LoRa_E22 e22ttl(4, 5); // Config without connect AUX and M0 M1
//#include <SoftwareSerial.h>
//SoftwareSerial mySerial(4, 5); // Arduino RX <-- e22 TX, Arduino TX --> e22 RX
//LoRa_E22 e22ttl(&mySerial, 3, 7, 6); // AUX M0 M1
// -------------------------------------
// ------------- Arduino Nano 33 IoT -------------
LoRa_E22 e22ttl(&Serial1, 2, 4, 6); // RX AUX M0 M1
// -------------------------------------------------
// ------------- Arduino MKR WiFi 1010 -------------
// LoRa_E22 e22ttl(&Serial1, 0, 2, 4); // RX AUX M0 M1
// -------------------------------------------------
// ---------- esp32 pins --------------
// LoRa_E22 e22ttl(&Serial2, 15, 21, 19); // RX AUX M0 M1
//LoRa_E22 e22ttl(&Serial2, 22, 4, 18, 21, 19, UART_BPS_RATE_9600); // esp32 RX <-- e22 TX, esp32 TX --> e22 RX AUX M0 M1
// -------------------------------------
struct MessageTemperature {
char type[5];
char message[8];
byte temperature[4];
};
struct MessageHumidity {
char type[5];
char message[8];
byte humidity;
};
void setup() {
Serial.begin(9600);
while(!Serial);
delay(500);
// Startup all pins and UART
e22ttl.begin();
Serial.println("Hi, I'm going to send message!");
struct MessageHumidity message = { "HUMI", ROOM, 80 };
// Send message
ResponseStatus rs = e22ttl.sendFixedMessage(0, DESTINATION_ADDL, 23, &message, sizeof(MessageHumidity));
// Check If there is some problem of succesfully send
Serial.println(rs.getResponseDescription());
delay(1000);
struct MessageTemperature messageT = { "TEMP", ROOM, 0 };
*(float*)(messageT.temperature) = 19.2;
// Send message
ResponseStatus rsT = e22ttl.sendFixedMessage(0, DESTINATION_ADDL, 23, &messageT, sizeof(MessageTemperature));
// Check If there is some problem of succesfully send
Serial.println(rsT.getResponseDescription());
}
void loop() {
// If something available
if (e22ttl.available() > 1) {
// read the String message
char type[5]; // first part of structure
ResponseContainer rs = e22ttl.receiveInitialMessage(sizeof(type));
String typeStr = rs.data;
// Is something goes wrong print error
if (rs.status.code != 1) {
Serial.println(rs.status.getResponseDescription());
} else {
Serial.println(typeStr);
if (typeStr == "TEMP") {
struct MessageTemperaturePartial {
char message[8];
byte temperature[4];
};
ResponseStructContainer rsc = e22ttl.receiveMessage( sizeof(MessageTemperaturePartial));
struct MessageTemperaturePartial message = *(MessageTemperaturePartial*) rsc.data;
Serial.println(*(float*)(message.temperature));
Serial.println(message.message);
rsc.close();
} else if (typeStr == "HUMI") {
struct MessageHumidityPartial {
char message[8];
byte humidity;
};
ResponseStructContainer rsc = e22ttl.receiveMessage(sizeof(MessageHumidityPartial));
struct MessageHumidityPartial message = *(MessageHumidityPartial*) rsc.data;
Serial.println(message.humidity);
Serial.println(message.message);
rsc.close();
} else {
Serial.println("Something goes wrong!!");
}
}
}
if (Serial.available()) {
if (MESSAGE_TYPE == "HUMI") {
struct MessageHumidity message = { "HUMI", ROOM, 0 };
message.humidity = Serial.parseInt();
// Send message
ResponseStatus rs = e22ttl.sendFixedMessage(0, DESTINATION_ADDL, 23, &message, sizeof(MessageHumidity));
// Check If there is some problem of succesfully send
Serial.println(rs.getResponseDescription());
} else {
struct MessageTemperature message = { "TEMP", ROOM, 0 };
*(float*)(message.temperature) = Serial.parseFloat();
// Send message
ResponseStatus rs = e22ttl.sendFixedMessage(0, DESTINATION_ADDL, 23, &message, sizeof(MessageTemperature));
// Check If there is some problem of succesfully send
Serial.println(rs.getResponseDescription());
}
}
}
Thanks
And this was the last part of my little tutorial. Next, we will examine the power saving of the microcontroller in detail, not only the LoRa device.
- Ebyte LoRa E22 device for Arduino, esp32 or esp8266: settings and basic usage
- Ebyte LoRa E22 device for Arduino, esp32 or esp8266: library
- Ebyte LoRa E22 device for Arduino, esp32 or esp8266: configuration
- Ebyte LoRa E22 device for Arduino, esp32 or esp8266: fixed transmission, broadcast, monitor, and RSSI
- Ebyte LoRa E22 device for Arduino, esp32 or esp8266: power-saving and sending structured data
- Ebyte LoRa E22 device for Arduino, esp32 or esp8266: repeater mode and remote settings
- Ebyte LoRa E22 device for Arduino, esp32 or esp8266: WOR microcontroller and Arduino shield
- Ebyte LoRa E22 device for Arduino, esp32 or esp8266: WOR microcontroller and WeMos D1 shield
- Ebyte LoRa E22 device for Arduino, esp32 or esp8266: WOR microcontroller and esp32 dev v1 shield
Shield and PCB
Hi Renzo, just wanted to ask the data format that is sent by this lora and this library when sending the structured message, is the data from struct like float.char,int etc converted to DEC and then sent to another lora with DEC format? or its just sending String? sorry i’m still learning and got confused
Hi Algie,
you can send string or structure, but you must pay attention when sending the same variable type across different microcontrollers because some variables can use more bytes in some systems.
Bye Renzo
I see, any chance we can see what is the actual thing that was sent by the module with this command?
i mean i know it will send the TEMP, Kitchen, and 19.2 . But is it just send that value directly? or that value converted to HEX or Dec or ASCII format and then it send that converted value maybe?
Hi Algie,
you can send It directly if the microcontrollers (sender and receiver) use the same size for the float variable.
Bye Renzo
I am working toward sending weather station data to the internet by way of a 2-hop LoRa transmission using 3 E22-900T30D radios controlled by ESP32s. The middle one will be a WOR repeater, when I get past the problem I’m having to make sleep/wakeup functionality work. I’ve faithfully duplicated the sending and receiving scripts you provided above. The sender claims success but the receiver doesn’t wake up. I tried uncommenting the pin-holding code without success. With the same hardware configuration, I’ve successfully implemented transparent mode and repeater transmissions, so I’m confident that the wiring is ok. I’d be grateful for debugging advice.
I raised an issue (#26) on the setConfiguration method, which may not set E22-900 parameters correctly and wonder if that could be a symptom to look into. Am I right in supposing that the AUX pin is only for waking the ESP32, if it has been put into some power-saving mode? Also I’m confused that I can’t find anything in the repository that relies on the WiFi or rtc includes or the callback routine.
Hi Sid,
you can find all information about how to manage the sleep mode of the E22 here
Ebyte LoRa E22 device for Arduino, esp32 or esp8266: power-saving WOR and structured data – 5
And the specified commands for ESP32 here
Ebyte LoRa E32 device for Arduino, esp32 or esp8266: WOR (wake on radio) and new ESP32 shield – 8
If you need more information open a topic, so we try to adapt the code for you.
Bye Renzo
Hi Renzo, thanks for the library and the help. I’m setting up a small peer-to-peer network to get weather data from a weather station site via a repeater which relays it to an internet gateway. It’s working on my desk.
I want to reduce power requirements by putting the three esp32s and e22-900-t30ds to sleep during the 5-minute intervals between data transmissions. But can the repeater be in both repeater and WOR modes at once? It seems not, since the repeater node e22 could be configured either as WOR_TRANSMITTER or WOR_RECEIVER but not both. Apparently this means that none of the e22s can be in WOR mode. Is that true?
Hi Sid,
I use WOR in various project, and I publish this
LoRa remote water tank level and pump controller (ReWaL): intro – 1
In this case (if I remember) I put in WOR_RECEIVER then when wake up I change the configuration on the fly and I start to send messages.
So, I think for the repeater there isn’t a good solution, because if you start in WOR and switch to repeater I think you can’t return to WOR (never try that), but for WOR_RECEIVER and WOR_SENDER you can change the configuration on the fly.
Bye Renzo
As you suggest, I abandoned the repeater approach and instead configure the repeater node first as a fixed WOR receiver and then on the fly as fixed WOR sender.
Heheheh.. Perfect Sid.
We are happy if you want share your project and your solutions, I think It’s very interesting.
Bye Renzo
Hi Renzo thanks for the great library and the documentation, in the above the code you have given for WOR, can the Transmitter receive messages from the receiver, it seemed like that, when I went through the code , but the transmitter is not getting the message sent from the receiver when I implemented it, what could be the issue that I’m facing, would be really glad if you could help me out. Thank you
Hi Maverick,
Check the power supply and the WOR time, and then if the devices are too close, add an antenna and move It.
Bye Renzo