LoRa point to point on Arduino and ESP32 PLCs
Connections
M-Duino Family
The M-Duino family PLCs use the following pins to communicate with the RFM95 LoRa module:
- RESET PIN: 13
- SLAVE SELECT PIN: 12
- INTERRUPTION PIN: 2
In addition to this pins, the SPI from the Arduino Mega are also connected to the module.
Ardbox LoRa Family
The Ardbox LoRa is based on Arduino Leonardo. This means that the pinout differs from the Arduino Mega, and the LoRa pins are the following:
- RESET PIN: 3
- SLAVE SELECT PIN: 23
- INTERRUPTION PIN: 2
In addition to this pins, the SPI from the Arduino Leonardo are also connected to the module.
Thanks to the pins definitions, there is no problem on compiling the program for an M-Duino LoRa PLC or for an Ardbox LoRa, as the pins are automatically set and changed within boards.
ESP32 LoRa Family
The ESP32 LoRa family PLCs use the following pins to communicate with the RN2483 module:
- RESET PIN: 0x2306
- SLAVE SELECT: 12
In addition to the reset pin, the module communicates with the ESP32 CPU through an UART Expansor, which utilizes the SPI from the ESP32 board
ESP32 14 LoRa PLC
The ESP32 14 LoRa PLC uses the following pin to communicate with the RN2483 module:
- RESET PIN: 0x2003
In addition to the reset pin, the module communicates with the ESP32 CPU through an UART Expansor, which utilizes I2C from the ESP32 board. The address for the I2C slave expansion port is 0x78.
As seen, the LoRa module used in both ESP32 based CPU PLC is the same, although the internal connections are very different and therefore, the pin definitions differ.
Module initialization
First of all, let's take a look at how any LoRa module from Industrial Shields based PLC is initiated in an Arduino IDE sketch:
#include <LoRa.h> uint32_t counter = 0UL; void setup() { Serial.begin(9600L); // Begin LoRa hardware if (!LoRa.begin()) { Serial.println("LoRa begin error: is LoRa module connected?"); while (true); } // Set LoRa working frequency if (!LoRa.setFrequency(868.0)) { Serial.println("LoRa set frequency error"); while (true); } Serial.println("Send started"); }
#include <LoRa.h> uint32_t counter = 0UL; void setup() { Serial.begin(9600L); // Begin LoRa hardware if (!LoRa.begin()) { Serial.println("LoRa begin error: is LoRa module connected?"); while (true); } // Set LoRa working frequency if (!LoRa.setFrequency(868.0)) { Serial.println("LoRa set frequency error"); while (true); } Serial.println("Send started"); }
- We include the LoRa library to be able to use its functions.
- In the setup function, after starting the Serial bus, we start the LoRa object. This function resets the module using the RESET pin mentioned before, and initiates the module using the Radio Head library. Thanks to using this other library, we can adapt the already done Radio Head library to our own PLCs, while maintaining the packet formats and configurations for a lot of LoRa modules, making it very easy to communicate with third party modules.
- Finally, we can set the frequency for the module. On M-Duino and Ardbox it is only set in MHz, as in this example (868.0). On ESP32 PLCs you can use MHz or Hz (868000000); Hz is recommended because it is more precise.
Sending through LoRa
After the setup function, the module is ready to send and receive. To send some data, you can try to use the following sketch:
void loop() { // Send counter as packet payload LoRa.send((uint8_t*) &counter, sizeof(counter)); Serial.println("Sending counter..."); // Wait packet to be sent LoRa.waitPacketSent(); Serial.println("Counter sent!"); // The packet is sent, increment the counter and wait to send the next one ++counter; delay(5000); }
void loop() { // Send counter as packet payload LoRa.send((uint8_t*) &counter, sizeof(counter)); Serial.println("Sending counter..."); // Wait packet to be sent LoRa.waitPacketSent(); Serial.println("Counter sent!"); // The packet is sent, increment the counter and wait to send the next one ++counter; delay(5000); }
In it, we first send through LoRa a counter number, then we print the value and finally increment it before waiting 5 seconds and repeating the process. As the LoRa protocol does not use and acknowledgement message after each transmission, there is a possibility that the sender does not know if the receiver has successfully received the message. In case of wanting to implement this feature, it has to be done by the user.
Receiving through LoRa
Like the last case, receiving is also possible after the seen setup function. In order to receive, use:
void loop() { // Wait packets from Send example if (LoRa.available()) { uint32_t value; uint8_t len = sizeof(value); // Save the received packet payload into value if (LoRa.recv((uint8_t *) &value, &len)) { Serial.print("Received value: "); Serial.println(value); } } }
void loop() { // Wait packets from Send example if (LoRa.available()) { uint32_t value; uint8_t len = sizeof(value); // Save the received packet payload into value if (LoRa.recv((uint8_t *) &value, &len)) { Serial.print("Received value: "); Serial.println(value); } } }
Before trying to read a LoRa packet, it is very important that we check whether we have a pending message to read. If so, we can then proceed to store the data in the value variable and print its contents.
In addition to unique integers, the LoRa.recv() can also receive strings, storing them into an array and modifying the len variable to fit the length of the array, to allow it to be printed or operated easily.
There are no comments for now.