Final Year 2022 is very near. In this Blog i have come up with an LoRa based IOT Projects.
We can send data with our node directly to our server but let imagine if we have to deploy this system
In Remote Region where internet is not there so at that time this Lora based node will required
Each node will collect data and send to one central system so called Gateway which can be setup way far
from remote area(Depends on LoRa module (10km can also achieve easily in Line of sight)
So our gateways have Internet it will upload data to Internet from there we can access it any where in the world.
Write code on Arduino IDE
Step 1:- Download Arduino IDE Through this link directly —— https://www.arduino.cc/en/donate/

Click on just download
Step2:-Click on this link to download ZIP file of library for LoRa Module — https://github.com/sandeepmistry/arduino-LoRa

Rename Downloaded ZIP folder with Arduino-LoRa

Step 3 :- Install LoRa library in Arduino IDE
Click on sketch >> Include library >> Add zip Library

Select Zip file >>

LoRa Library Successfully added
Step4 :- Now add Install 2 More library in Arduino IDE for OLED Screen
Click on Sketch >> Include Library >> Manage Libraries

1 — Adafruit GFX and click on install

2 — Adafruit SSD1306 and click on install

Library Installation Done
Step 5:- Write Code For Node 1
Open Arduino IDE Click on file >> New and Paste this code >>
************************************* Node 1 ****************************************
// www.elconics.com
// Node 1
/*
Lora Node1
The IoT Projects
*/
#include <SPI.h> // include libraries
#include <LoRa.h>
#define ss 5
#define rst 14
#define dio0 2
String outgoing; // outgoing message
byte msgCount = 0; // count of outgoing messages
byte MasterNode = 0xFF;
byte Node1 = 0xBB;
int AirValue = 590; //you need to replace this value with Value_1
int WaterValue = 300; //you need to replace this value with Value_2
int SensorPin = 23;
int soilMoistureValue = 0;
int soilmoisturepercent = 0;
String Mymessage = "";
void setup() {
Serial.begin(115200); // initialize serial
while (!Serial);
Serial.println("LoRa Node1");
LoRa.setPins(ss, rst, dio0);
if (!LoRa.begin(433E6)) {
Serial.println("Starting LoRa failed!");
while (1);
}
}
void loop() {
soilMoistureValue = random(1,1023); //put Sensor insert into soil
soilmoisturepercent = map(soilMoistureValue, AirValue, WaterValue, 0, 100);
// parse for a packet, and call onReceive with the result:
onReceive(LoRa.parsePacket());
}
void onReceive(int packetSize) {
if (packetSize == 0) return; // if there's no packet, return
// read packet header bytes:
int recipient = LoRa.read(); // recipient address
byte sender = LoRa.read(); // sender address
byte incomingMsgId = LoRa.read(); // incoming msg ID
byte incomingLength = LoRa.read(); // incoming msg length
String incoming = "";
while (LoRa.available()) {
incoming += (char)LoRa.read();
}
if (incomingLength != incoming.length()) { // check length for error
// Serial.println("error: message length does not match length");
;
return; // skip rest of function
}
// if the recipient isn't this device or broadcast,
if (recipient != Node1 && recipient != MasterNode) {
//Serial.println("This message is not for me.");
;
return; // skip rest of function
}
Serial.println(incoming);
int Val = incoming.toInt();
if (Val == 10)
{
Mymessage = Mymessage + soilMoistureValue + "," + soilmoisturepercent;
//Mymessage = Mymessage + random(1,100);
sendMessage(Mymessage, MasterNode, Node1);
delay(100);
Mymessage = "";
Serial.println(Mymessage);
}
}
void sendMessage(String outgoing, byte MasterNode, byte Node1) {
LoRa.beginPacket(); // start packet
LoRa.write(MasterNode); // add destination address
LoRa.write(Node1); // add sender address
LoRa.write(msgCount); // add message ID
LoRa.write(outgoing.length()); // add payload length
LoRa.print(outgoing); // add payload
LoRa.endPacket(); // finish packet and send it
msgCount++; // increment message ID
}
Step6 :- The circuit diagram below can be used to design NODE1, Connect LoRa Module.

Step :-7 Code for node 2
Open new tab and paste this code in another ESP module
**************************************************************************************
// Node 2
#include <SPI.h> // include libraries
#include <LoRa.h>
#include <DHT.h>
#define DHTPIN 4 //pin where the dht22 is connected
DHT dht(DHTPIN, DHT22);
#define ss 5
#define rst 14
#define dio0 2
String outgoing; // outgoing message
byte msgCount = 0; // count of outgoing messages
byte MasterNode = 0xFF;
byte Node2 = 0xCC;
float temperature;
float humidity;
String Mymessage = "";
String incoming = "";
void setup() {
Serial.begin(115200); // initialize serial
dht.begin();
while (!Serial);
Serial.println("LoRa Node2");
LoRa.setPins(ss, rst, dio0);
if (!LoRa.begin(433E6)) {
Serial.println("Starting LoRa failed!");
while (1);
}
LoRa.setSyncWord(0xF3);
Serial.println("LoRa Initializing OK!");
}
void loop() {
temperature = dht.readTemperature();
humidity = dht.readHumidity();
// parse for a packet, and call onReceive with the result:
onReceive(LoRa.parsePacket());
}
void onReceive(int packetSize) {
if (packetSize == 0) return; // if there's no packet, return
// read packet header bytes:
int recipient = LoRa.read(); // recipient address
byte sender = LoRa.read(); // sender address
byte incomingMsgId = LoRa.read(); // incoming msg ID
byte incomingLength = LoRa.read(); // incoming msg length
String incoming = "";
while (LoRa.available()) {
incoming += (char)LoRa.read();
}
if (incomingLength != incoming.length()) { // check length for error
// Serial.println("error: message length does not match length");
;
return; // skip rest of function
}
// if the recipient isn't this device or broadcast,
if (recipient != Node2 && recipient != MasterNode) {
//Serial.println("This message is not for me.");
;
return; // skip rest of function
}
Serial.println(incoming);
int Val = incoming.toInt();
if (Val == 20)
{
Mymessage = Mymessage + temperature + "," + humidity;
sendMessage(Mymessage, MasterNode, Node2);
delay(100);
Mymessage = "";
}
}
void sendMessage(String outgoing, byte MasterNode, byte Node2) {
LoRa.beginPacket(); // start packet
LoRa.write(MasterNode); // add destination address
LoRa.write(Node2); // add sender address
LoRa.write(msgCount); // add message ID
LoRa.write(outgoing.length()); // add payload length
LoRa.print(outgoing); // add payload
LoRa.endPacket(); // finish packet and send it
msgCount++; // increment message ID
}
Step:- 8 Circuit Diagram For node 2

Now Write Code For Master Gateway
Step 9 :- Paste This Code In new Tab And Upload to another ESP32 Controller
// www.elconics.com
// Today i successfully created LORAWAN
// Using One master and two nodes, One nodes for sending temp and humi and other random value
********************************master code**********************************
#include <SPI.h> // include libraries
#include <LoRa.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#define ss 5 //GPIO 15
#define rst 14 //GPIO 16
#define dio0 2 //GPIO 4
byte MasterNode = 0xFF;
byte Node1 = 0xBB;
byte Node2 = 0xCC;
String SenderNode = "";
String outgoing; // outgoing message
byte msgCount = 0; // count of outgoing messages
// Tracks the time since last event fired
unsigned long previousMillis=0;
unsigned long int previoussecs = 0;
unsigned long int currentsecs = 0;
unsigned long currentMillis = 0;
int interval= 1 ; // updated every 1 second
int Secs = 0;
void setup() {
Serial.begin(9600); // initialize serial
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
delay(2000);
display.clearDisplay();
display.setTextColor(WHITE);
LoRa.setPins(ss, rst, dio0);
if (!LoRa.begin(433E6)) { // initialize ratio at 915 MHz
Serial.println("LoRa init failed. Check your connections.");
while (true); // if failed, do nothing
}
Serial.println("LoRa init succeeded.");
}
void loop() {
currentMillis = millis();
currentsecs = currentMillis / 1000;
if ((unsigned long)(currentsecs - previoussecs) >= interval) {
Secs = Secs + 1;
//Serial.println(Secs);
if ( Secs >= 11 )
{
Secs = 0;
Serial.println("Counting restart");
}
if ( (Secs >= 1) && (Secs <= 5) )
{
Serial.println("I am in first node");
String message = "10";
sendMessage(message,MasterNode, Node1);
}
if ( (Secs >= 6 ) && (Secs <= 10))
{
Serial.println("I am in second node");
String message = "20";
sendMessage(message,MasterNode, Node2);
}
previoussecs = currentsecs;
}
// parse for a packet, and call onReceive with the result:
onReceive(LoRa.parsePacket());
Serial.println(Secs);
}
void sendMessage(String outgoing, byte MasterNode, byte otherNode) {
LoRa.beginPacket(); // start packet
LoRa.write(otherNode); // add destination address
LoRa.write(MasterNode); // add sender address
LoRa.write(msgCount); // add message ID
LoRa.write(outgoing.length()); // add payload length
LoRa.print(outgoing); // add payload
LoRa.endPacket(); // finish packet and send it
msgCount++; // increment message ID
Serial.println("Message send");
}
void onReceive(int packetSize) {
if (packetSize == 0) return; // if there's no packet, return
// read packet header bytes:
int recipient = LoRa.read(); // recipient address
byte sender = LoRa.read(); // sender address
if( sender == 0XBB )
SenderNode = "Node1:";
if( sender == 0XCC )
SenderNode = "Node2:";
byte incomingMsgId = LoRa.read(); // incoming msg ID
byte incomingLength = LoRa.read(); // incoming msg length
String incoming = "";
while (LoRa.available()) {
incoming += (char)LoRa.read();
}
if (incomingLength != incoming.length()) { // check length for error
//Serial.println("error: message length does not match length");
;
return; // skip rest of function
}
// if the recipient isn't this device or broadcast,
if (recipient != Node1 && recipient != MasterNode) {
// Serial.println("This message is not for me.");
;
return; // skip rest of function
}
// if message is for this device, or broadcast, print details:
//Serial.println("Received from: 0x" + String(sender, HEX));
//Serial.println("Sent to: 0x" + String(recipient, HEX));
//Serial.println("Message ID: " + String(incomingMsgId));
// Serial.println("Message length: " + String(incomingLength));
// Serial.println("Message: " + incoming);
//Serial.println("RSSI: " + String(LoRa.packetRssi()));
// Serial.println("Snr: " + String(LoRa.packetSnr()));
// Serial.println();
//clear display
display.clearDisplay();
display.setTextSize(2);
display.setCursor(0,0);
display.print(SenderNode);
if( sender == 0XBB )
{
display.setTextSize(2);
display.setCursor(0, 28);
display.print(incoming + "Reading");
}
if( sender == 0XCC )
{
display.setTextSize(2);
display.setCursor(0, 20);
display.println("Temp,Humi ");
display.setTextSize(2);
display.print(incoming);
}
display.display();
}
Step 10 :- Connect LoRa module and OLED Screen According to circuit diagram

Now you successfully completed master gateway and node
Connect ESP to the power supply of 5v through cable and place node to some distance of master gateway and you can see humidity temperature data has been displayed in master Gateway Screen.
You can follow this Same process to make more then one node to get data from different location of a farm or a place.

BUY Components through Amazon directly
Esp32 Wroom – https://amzn.to/3tJoBO4
LORA MODULE – https://amzn.to/3OrPVd1 (buy 2 – 1 as transmitter , 1 as receiver)
1 channel relay –https://amzn.to/3XgLLbP
Oled i2c –https://amzn.to/3tJvi2l
Pir motion sensor –https://amzn.to/3gjnaTb
You can go though Our YouTube Channel >>
1 thought on “Node and Gateway with ESP32 | Final Year best IOT project 2022”
Pingback: Connect Multiple ESP32 Without Internet - Elconics