Introduction: Energy Manager Using Heltec LoRa 32 WiFi and Arduino

This project involves the implementation of a system responsible for collecting data about the electric energy generated by an off grid photovoltaic system and transmitting them to an LED panel through wireless, using two LoRa 32 WiFi controllers, responsible for monitoring electrical energy data generated by a photovoltaic system, transferring them via LoRa protocol and sending the collected information to an Arduino Uno, responsible for writing on a 96x16 LED display composed of three panels P10.

Step 1: Materials

● 1 LED display XYWP 96x16 (Composed of 3 panels P10);

● 1 Arduino Uno;

● 2 Heltec LoRa 32 WiFi;

● Resistors (1x22 kΩ, 1x20 kΩ, 2x10 kΩ, 1x1.7 kΩ, 1x1 kΩ);

● 2 Contact Matrices.

Step 2: Block Diagram

Step 3: System Operation

The transmission system of data collected from the photovoltaic system works with two LoRa 32 WiFi controllers communicating through UDP Protocol (User Datagram Protocol). On this protocol, a LoRa is configured as Sender (responsible for collecting data from the photovoltaic system), and another is configured as Receiver (responsible for reading information from the Sender). The Receiver is connected to an Arduino Uno by RX-TX (system responsible for sending and receiving data). The Arduino controls the LED display, printing the information previously collected.

Step 4: Procedures and Programming

In order to compile the codes for LoRa 32 WiFi controllers, you need to perform a tutorial that aims to use the board on Arduino IDE (Integrated Development Environment).

Briefly, the procedure consists in upgrading the Arduino IDE to the latest version, installing the Git program and choosing the “Clone Existing Repository” option. After that, insert the link "https://github.com/espressif/arduino-esp32.git" into the "Source Location" field and fill in the "Target Directory" field with the address of the Arduino folder on your computer and click "Clone". Once the cloning is done, open Git Bash and access esp32 folder (created during the cloning). After that, execute the command "git submodule update --init --recursive" to make any necessary updates so that the procedure works correctly. After completing any updates, you must execute "get.exe" file located inside the esp32\tools folder, which will create two new files. Done that, your PC will be able to use LoRa 32 WiFi. To update the Arduino IDE with support for the used development board, open Git GUI and click on "Open Recent Repository", go to the "Remote" tab, click "Fetch From" and "Origin". The updates will be performed automatically and you can close the program. After completing the process, you must install the development board driver, accessible here.

For a more detailed explanation of the procedure to be performed, access this link.

When the tutorial above is executed, the communication process of LoRa controllers can be started.

After the connection is made, you must configure which information will be sent from Sender to Receiver. This information is stored on packets that will be transmitted and read later.

After that, you must connect LoRa Receiver to Arduino via RX-TX ports, following the procedure shown on the block diagram on the Picture 1.

Once the connection above is made, the Arduino must be connected to the LED Display, as shown on the block diagram on the Picture 2.

The connection of the LED display using Arduino is based on the instructable "Display Text at P10 LED Display Using Arduino", available here.

The DMD2 library was used to establish communication between the controller and the display, available for download here.

To be able to use the library, just use the command #include on your code and include the style of the letter to be shown. In this case, we chose Arial Black 16 with "#include <fonts/Arial_Black_16.h>".

Step 5: LoRa 32 WiFi (Sender) Code

The Sender is responsible for reading the voltage and sending this information via LoRa to the Receiver.Sender’s code can be seen here.

LoRa 32 WIFI Sender Code

#include<SPI.h>
#include<LoRa.h>
#include<Wire.h>//responsible for i2c communication
#include"SSD1306Wire.h"
#defineSS18
#defineRST14
#defineDI026
#definecurrent13//current value
float v=0,p=0,e=0;//voltage, power and energy values
SSD1306Wire display(0x3c, 4, 15);
voidsetup() {
//set pins as output
pinMode(16,OUTPUT);//OLED RST
pinMode(25,OUTPUT);
digitalWrite(16, LOW);//reset OLED
delay(50);
digitalWrite(16, HIGH);//while OLED is on, GPIO16 might be HIGH
//starts LoRa's display
display.init();
display.flipScreenVertically();
display.setFont(ArialMT_Plain_10);
SPI.begin(5, 19, 27, 18);
LoRa.setPins(SS, RST, DI0);
Serial.begin(4800);
while (!Serial);
//clear LoRa's display
display.clear();
//433E6, 868E6, 915E6
if (!LoRa.begin(433E6)) {
Serial.println("Starting LoRa failed!");
display.drawString(0, 0, "LoRa Initial failed!");
while (1);
} else {
display.drawString(0, 0, "LoRa Initial success!");
}
//showcase the string on LoRa's display
display.display();
}
voidloop() {
//reads output voltage and calculates input voltage
v=(analogRead(36)*3.35/4096)*(23700/1700);
if(v>3)
v+=3;
//gets power value
p=v*current;
//add power to energy
e+=((p/1000)/3600);//divide p by 1000 to obtain kW and by 3600s(1h) to get kWh
//starts LoRa packet
LoRa.beginPacket();
//writes on the packet
LoRa.print(v);
LoRa.print("V POWER: ");
LoRa.print(p);
LoRa.print("W ENERGY: ");
LoRa.print(e);
LoRa.print("kWh");
//ends the packet
LoRa.endPacket();
//dlear LoRa's display
display.clear();
display.drawString(0, 0, "GSE - SENDER");
display.drawString(0, 10, "Packet: ");
String rssi = (String)LoRa.packetRssi();
display.drawString(0, 20, "RSSI:");
display.drawString(50, 20, rssi);
display.display();//showcase the string on LoRa's display
//pause for 1 seconds
delay(1000);
}
view rawLoRa_sender.ino hosted with ❤ by GitHub

Step 6: LoRa 32 WiFi (Receiver) Code

The Receiver is responsible for reading Sender’s information and transmit it to Arduino via RX-TX connection.

Receiver’s code is here.

LoRa 32 WIFI Receiver

#include<SPI.h>
#include<LoRa.h>
#include<Wire.h>//responsible for i2c communication
#include"SSD1306Wire.h"
#defineSS18
#defineRST14
#defineDI026
SSD1306Wire display(0x3c, 4, 15);
voidsetup() {
//battery
pinMode(32, INPUT);
//set pin as output
pinMode(16,OUTPUT); //OLED RST
pinMode(25,OUTPUT);
digitalWrite(16, LOW); //resets OLED
delay(50);
digitalWrite(16, HIGH); //while OLED is on, GPIO might be HIGH
//Starts LoRa's display
display.init();
display.flipScreenVertically();
display.setFont(ArialMT_Plain_10);
SPI.begin(5, 19, 27, 18);
LoRa.setPins(SS, RST, DI0);
Serial.begin(4800);
while (!Serial);
//433E6, 868E6, 915E6
if (!LoRa.begin(433E6)) {
Serial.println("Starting LoRa failed!");
while (1);
}
//clear LoRa's display
display.clear();
display.drawString(0, 0, "LoRa Initial success!");
display.display();//showcase the string on LoRa's display
}
voidloop() {
String packet="", rssi;
float bat=analogRead(32);//reads battery value
int packetSize = LoRa.parsePacket();
if(packetSize){
//while there's something on LoRa's packet
while (LoRa.available())
packet += (char)LoRa.read();//reads and save the string
//sends string to Serial
for(int i=0;ilength();i++)
Serial.write(packet[i]);
rssi = (String)LoRa.packetRssi();
//clear LoRa's display
display.clear();
display.drawString(0, 0, "GSE - RECEIVER");
display.drawString(0, 10, "RSSI:");
display.drawString(50, 10, rssi);
display.drawString(0, 20, "Packet:");
display.drawString(50, 20, packet);
display.drawString(0, 30, "Battery:");
display.drawString(50, 30, (String)bat);
display.display();//showcase the string on LoRa's display
}
//pause for 1 second for each byte
delay(1000*packet.length());
//clear other packets
LoRa.flush();
}

Step 7: Arduino Code

Arduino reads data from Receiver and print it on the LED display. To control the LED display, DMD2 library was used. You can see the code here.

Arduino_to_led_code.ino

#include<SPI.h>
#include<DMD2.h>
#include<fonts/Arial_Black_16.h>//include the library of the fonts used on the LED display
#include<string.h>
//starts LED display with 3 columns and 1 line of matrix (1x1 matrix = 16x16 LEDs)
SoftDMD dmd(3,1);
DMD_TextBox box(dmd);
String save=""; //starts a string responsible to save the data
voidsetup() {
//set the brightness of the LED display
dmd.setBrightness(30);
//set the font used on the LED display
dmd.selectFont(Arial_Black_16);
dmd.begin();
//set the data rate in bits per second for serial data transmission
Serial.begin(4800);
}
voidloop(){
//if there's something on Serial
if(Serial.available()>0){
//reset save
save=" PV SYSTEM VOLTAGE: ";
//while there's something on Serial
while(Serial.available())
//reads string and saves it
save+=(char)Serial.read();
}
//print each letter of 'save' on LED display
for(int i=0;ilength();i++){
box.print(save[i]);
//pause for 0.3 second
delay(300);
}
}

Step 8: Electric Scheme

To test data transmission system via LoRa and write to the LED display, a prototype of a controller board was created on a contact matrix. The circuit is available on the Picture 3 and Picture 4.

To simulate the voltage measurement, a voltage divider circuit was made on a contact matrix connected to a power supply capable of reaching the maximum voltage generated by the solar panels.

The voltage divider was used so that LoRa Sender can measure the system voltage through one of its analogic inputs. The maximum voltage supported LoRa analog pins is 3.3 V and the photovoltaic system generates a maximum voltage of 46V. The circuit is responsible for matching the voltage of the solar panels to the LoRa 32 WiFi scale. See the circuit at Picture 5 and Picture 6.

After the simulations were performed, a PCB was created to replace the contact matrix used to receive the information and write it on the LED display. See the layout at the Picture 7.

With the circuit’s layout, the PCB of Picture 8 was made.

Step 9: Results

After connecting everything and compiling the codes to all controller boards, we succeeded in transmitting the data - voltage, power and energy - collected from the PV system. For now, we are using a direct current, set on the Sender’s code, but in the future a current sensor is going to be used to read the current generated from the photovoltaic system.

The project's result is disponible in the video.