0% found this document useful (0 votes)
5 views22 pages

LoRa Transciever Code

The document contains code for a LoRa transmitter and receiver using Arduino, which includes libraries for SPI, LoRa, and sensors. The transmitter collects environmental data (temperature, humidity, pressure, gas) and sends it to a master device, while the receiver processes incoming messages and displays the data on an OLED screen. The code also includes functionality for resetting the LoRa module and handling communication between multiple slave devices.

Uploaded by

drawinga36
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views22 pages

LoRa Transciever Code

The document contains code for a LoRa transmitter and receiver using Arduino, which includes libraries for SPI, LoRa, and sensors. The transmitter collects environmental data (temperature, humidity, pressure, gas) and sends it to a master device, while the receiver processes incoming messages and displays the data on an OLED screen. The code also includes functionality for resetting the LoRa module and handling communication between multiple slave devices.

Uploaded by

drawinga36
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 22

Transmitter LoRa Code:

#include <SPI.h>
#include <LoRa.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_BME680.h"
#include <Wire.h>

#define SEALEVELPRESSURE_HPA (1013.25)

//----------------------------------------
Adafruit_BME680 bme; // I2C

//---------------------------------------- Defines LED Pins.


#define MQ4 A1
#define MQ7 A2
#define SoundSensorPin A0

//---------------------------------------- LoRa Pin / GPIO configuration.


#define ss 10
#define rst 9
#define dio0 2

//----------------------------------------String variable for LoRa


String Incoming = "";
String Message = "";

//Uncomment Slave1 Address if code is getting compiled in Node1 and others are commented. Same for all Nodes
//byte LocalAddress = 0x02; //--> address of this device (Slave 1).
//byte LocalAddress = 0x03; //--> address of this device (Slave 2).
//byte LocalAddress = 0x04; //--> address of this device (Slave 3).

byte Destination_Master = 0x01; //--> destination to send to Master (ESP32).

//---------------------------------------- Variable declarations for temperature and humidity values.


float Temperature;
float Humidity;
float Pressure;
float Gas;
float Altitude;
int m4 = 0;
int m7 = 0;
int sd = 0;

//---------------------------------------- Variable declaration for Millis/Timer.


unsigned long previousMillis_UpdateBME = 0;
const long interval_UpdateBME = 2000;

unsigned long previousMillis_RestartLORA = 0;


const long interval_RestartLORA = 1000;

// Declaration of variable as counter to restart Lora Ra-02.


byte Count_to_Rst_LORA = 0;

//________________________________________________________________________________ Subroutines for sending data (LoRa Ra-02).


void sendMessage(String Outgoing, byte Destination) {
LoRa.beginPacket(); //--> start packet
LoRa.write(Destination); //--> add destination address
LoRa.write(LocalAddress); //--> add sender address
LoRa.write(Outgoing.length()); //--> add payload length
LoRa.print(Outgoing); //--> add payload
LoRa.endPacket(); //--> finish packet and send it
}

//________________________________________________________________________________ Subroutines for receiving data (LoRa Ra-02).


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 incomingLength = LoRa.read(); //--> incoming msg length
//---------------------------------------- Condition that is executed if message is not from Master.
if (sender != Destination_Master) {
Serial.println();
Serial.println("i"); //--> "i" = Not from Master, Ignore.
//Serial.println("Not from Master, Ignore");

// Resets the value of the Count_to_Rst_LORA variable.


Count_to_Rst_LORA = 0;
return; //--> skip rest of function
}

// Clears Incoming variable data.


Incoming = "";

//---------------------------------------- Get all incoming data.


while (LoRa.available()) {
Incoming += (char)LoRa.read();
}

// Resets the value of the Count_to_Rst_LORA variable.


Count_to_Rst_LORA = 0;

//---------------------------------------- Check length for error.


if (incomingLength != Incoming.length()) {
Serial.println();
Serial.println("er"); //--> "er" = error: message length does not match length.
//Serial.println("error: message length does not match length");
return; //--> skip rest of function
}

//---------------------------------------- Checks whether the incoming data or message for this device.
if (recipient != LocalAddress) {
Serial.println();
Serial.println("!"); //--> "!" = This message is not for me.
//Serial.println("This message is not for me.");

// Calls the Processing_incoming_data_for_LEDs() subroutine.


return; //--> skip rest of function
} else {
// if message is for this device, or broadcast, print details:
Serial.println();
Serial.println("Rc from: 0x" + String(sender, HEX));
Serial.println("Message: " + Incoming);

// Calls the Processing_incoming_data() subroutine.


Processing_incoming_data();
}
}

//________________________________________________________________________________ Subroutine to process the data to be sent, after


that it sends a message to the Master.

void Processing_incoming_data() {

// Fill in the "Message" variable with the value of humidity, temperature and the last state of the LED.
Message = String(Temperature) + "," + String(Humidity) + "," + String(Pressure) + "," + String(Gas) + "," + String(Altitude) + "," +
String(m4) + "," + String(m7) + "," + String(sd);

Serial.println();
Serial.println("Tr to : 0x" + String(Destination_Master, HEX));
Serial.println("Message: " + Message);

// Send a message to Master.


sendMessage(Message, Destination_Master);
}
//________________________________________________________________________________

String GetValue(String data, char separator, int index) {


int found = 0;
int strIndex[] = { 0, -1 };
int maxIndex = data.length() - 1;

for (int i = 0; i <= maxIndex && found <= index; i++) {


if (data.charAt(i) == separator || i == maxIndex) {
found++;
strIndex[0] = strIndex[1] + 1;
strIndex[1] = (i == maxIndex) ? i+1 : i;
}
}
return found > index ? data.substring(strIndex[0], strIndex[1]) : "";
}
//________________________________________________________________________________

//________________________________________________________________________________ Subroutine to reset Lora Ra-02.


void Rst_LORA() {
LoRa.setPins(ss, rst, dio0);

Serial.println();
Serial.println(F("Restart LoRa..."));
Serial.println(F("Start LoRa init..."));
if (!LoRa.begin(433E6)) { // initialize ratio at 915 or 433 MHz
Serial.println(F("LoRa init failed. Check your connections."));
while (true); // if failed, do nothing
}
Serial.println(F("LoRa init succeeded."));

// Resets the value of the Count_to_Rst_LORA variable.


Count_to_Rst_LORA = 0;
}

//________________________________________________________________________________ VOID SETUP


void setup() {
// put your setup code here, to run once:

Serial.begin(115200);
// Calls the Rst_LORA() subroutine.
Rst_LORA();

if (!bme.begin()) {
Serial.println("Could not find a valid BME680 sensor, check wiring!");
while (1);
}

// Set up oversampling and filter initialization


bme.setTemperatureOversampling(BME680_OS_8X);
bme.setHumidityOversampling(BME680_OS_2X);
bme.setPressureOversampling(BME680_OS_4X);
bme.setIIRFilterSize(BME680_FILTER_SIZE_3);
bme.setGasHeater(320, 150); // 320*C for 150 ms
}

//________________________________________________________________________________ VOID LOOP


void loop() {

//---------------------------------------- Millis / Timer to update the temperature and humidity values from the DHT11 sensor every 2
seconds (see the variable interval_UpdateDHT11).
unsigned long currentMillis_UpdateBME = millis();

if (currentMillis_UpdateBME - previousMillis_UpdateBME >= interval_UpdateBME) {


previousMillis_UpdateBME = currentMillis_UpdateBME;

// Reading temperature or humidity takes about 250 milliseconds!


Humidity = bme.humidity;
Temperature = bme.temperature;
Pressure = bme.pressure / 100.0;
Gas = bme.gas_resistance / 1000.0;
Altitude = bme.readAltitude(SEALEVELPRESSURE_HPA);
m4 = analogRead(MQ4);
m7 = analogRead(MQ7);

for (int i = 0; i < 32; i++) //create a for loop to read


{
sd += analogRead(SoundSensorPin); //read the sound sensor
}

sd >>= 5; //bitshift operation


if (sd > 500) {
return;
}

// Check if any reads failed and exit early (to try again).
if (isnan(Temperature) || isnan(Humidity)) {
Serial.println(F("Failed to read from BME sensor!"));
return;
}
}

//---------------------------------------- Millis/Timer to reset Lora Ra-02.

unsigned long currentMillis_RestartLORA = millis();

if (currentMillis_RestartLORA - previousMillis_RestartLORA >= interval_RestartLORA) {


previousMillis_RestartLORA = currentMillis_RestartLORA;

Count_to_Rst_LORA++;
if (Count_to_Rst_LORA > 30) {
LoRa.end();
Rst_LORA();
}
}

//---------------------------------------- parse for a packet, and call onReceive with the result:
onReceive(LoRa.parsePacket());
//----------------------------------------

Receiver LoRa Code

//---------------------------------------- Include Library.

#include <SPI.h>

#include <LoRa.h>

#include <Wire.h>

#include <WiFi.h>

#include <ArduinoOTA.h>

#include <WiFiClientSecure.h>

#include <AsyncTCP.h>

#include "html.h"

#include <ESPAsyncWebServer.h>

#include <Adafruit_GFX.h>

#include <Adafruit_SSD1306.h>

#include <RTClib.h>

//---------------------------------------- Configure OLED screen size in pixels.

#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);

//----------------------------------------

RTC_DS3231 rtc;
//---------------------------------------- LoRa Pin / GPIO configuration.

#define ss 10

#define rst 9

#define dio0 2

#define WIFI_SSID "BVC-Elec"

#define WIFI_PASSWORD "nerar52nera"

AsyncWebServer server(80);

AsyncEventSource events("/events");

const char* host = "script.google.com";

const int httpsPort = 443;

unsigned long lastTime = 0;

unsigned long timerDelay = 30000;

//----------------------------------------

//---------------------------------------- Variable declaration to hold incoming and outgoing data.

String Incoming = "";

String Message = "";

//----------------------------------------

//---------------------------------------- LoRa data transmission configuration.

byte LocalAddress = 0x01; //--> address of this device (Master Address).

byte Destination_ESP32_Slave_1 = 0x02; //--> destination to send to Slave 1 (ESP32).

byte Destination_ESP32_Slave_2 = 0x03; //--> destination to send to Slave 2 (ESP32).

//byte Destination_ESP32_Slave_3 = 0x04; //--> destination to send to Slave 2 (ESP32).

//----------------------------------------

//---------------------------------------- Variable declaration for Millis/Timer.

unsigned long previousMillis_SendMSG = 0;

const long interval_SendMSG = 1000;

unsigned long previousMillis_RestartLORA = 0;

const long interval_RestartLORA = 1000;

//---------------------------------------- Variable declaration to get temperature and humidity values received from Slaves.

float Humd[3];

float Temp[3];

float Pres[3];

float Gas[3];
float Alt[3];

int MQ4[3];

int MQ7[3];

int SD[3];

char timestamp[20];

//----------------------------------------

String GAS_ID;

String sheets1 = "AKfycbxSwPSkFj25Dc9_BPWjHhH7d_x4JgJNC3HfXHc2WTjMZdD_0mHBfKcxEQ1tuTNag_IAow"; //--> spreadsheet script ID;

String sheets2 = "AKfycby-PqY9Yc5PwjBi6Z9MOkc-kuieX69ibnR2JF_E9SKtAwrv9uad8AVRlLBiHAMyB7kENQ"; //--> spreadsheet script ID;

String sheets3 = "AKfycbwmiv0KUf-7o-s1fBZruky-CER5-S_8yLPnvlK8tcnFUNx80XtRPxYOJ47L9aKV_aE"; //--> spreadsheet script ID;

String SenderNode = "";

// Variable declaration to count slaves.

byte Slv = 0;

// Declare a variable as a counter to update the OLED LCD display if there is no incoming message from the slaves.

byte Count_OLED_refresh_when_no_data_comes_in = 0;

// Variable declaration to get the address of the slaves.

byte SL_Address;

// Declaration of variable as counter to restart Lora Ra-02.

byte Count_to_Rst_LORA = 0;

WiFiClientSecure client;

String processor(const String& var){

if(var == "TEMPERATURE1"){

return String(Temp[0]);

else if(var == "HUMIDITY1"){

return String(Humd[0]);

else if(var == "PRESSURE1"){

return String(Pres[0]);

else if(var == "GAS1"){

return String(Gas[0]);

else if(var == "ALTITUDE1"){


return String(Alt[0]);

else if(var == "SOUNDVALUE1"){

return String(SD[0]);

else if(var == "METHANE1"){

return String(MQ4[0]);

else if(var == "MONOXIDE1"){

return String(MQ7[0]);

else if(var == "TEMPERATURE2"){

return String(Temp[1]);

else if(var == "HUMIDITY2"){

return String(Humd[1]);

else if(var == "PRESSURE2"){

return String(Pres[1]);

else if(var == "GAS2"){

return String(Gas[1]);

else if(var == "ALTITUDE2"){

return String(Alt[1]);

else if(var == "SOUNDVALUE2"){

return String(SD[1]);

else if(var == "METHANE2"){

return String(MQ4[1]);

else if(var == "MONOXIDE2"){

return String(MQ7[1]);

return String();

//____________________________ Subroutines for sending data (LoRa Ra-02).

void sendMessage(String Outgoing, byte Destination) {

LoRa.beginPacket(); //--> start packet


LoRa.write(Destination); //--> add destination address

LoRa.write(LocalAddress); //--> add sender address

LoRa.write(Outgoing.length()); //--> add payload length

LoRa.print(Outgoing); //--> add payload

LoRa.endPacket(); //--> finish packet and send it

//____________________________

//____________________________ Subroutines for receiving data (LoRa Ra-02).

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 incomingLength = LoRa.read(); //--> incoming msg length

//----------------------------------------

// Get the address of the senders or slaves.

SL_Address = sender;

// Clears Incoming variable data.

Incoming = "";

//---------------------------------------- Get all incoming data / message.

while (LoRa.available()) {

Incoming += (char)LoRa.read();

//----------------------------------------

// Resets the value of the Count_to_Rst_LORA variable if a message is received.

Count_to_Rst_LORA = 0;

// Reset the value of the Count_OLED_refresh_when_no_data_comes_in variable if a message is received.

Count_OLED_refresh_when_no_data_comes_in = 0;

//---------------------------------------- Check length for error.

if (incomingLength != Incoming.length()) {

Serial.println();

Serial.println("er"); //--> "er" = error: message length does not match length.

//Serial.println("error: message length does not match length");

return; //--> skip rest of function

}
//----------------------------------------

//---------------------------------------- Checks whether the incoming data or message for this device.

if (recipient != LocalAddress) {

Serial.println();

Serial.println("!"); //--> "!" = This message is not for me.

//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();

Serial.println("Rc from: 0x" + String(sender, HEX));

Serial.println("Message: " + Incoming);

//----------------------------------------

// Calls the Processing_incoming_data() subroutine.

Processing_incoming_data();

//____________________________

void Processing_incoming_data() {

//---------------------------------------- Conditions for processing data or messages from Slave 1 (ESP32 Slave 1).

if (SL_Address == Destination_ESP32_Slave_1) {

Temp[0] = GetValue(Incoming, ',', 0).toFloat();

Humd[0] = GetValue(Incoming, ',', 1).toFloat();

Pres[0] = GetValue(Incoming, ',', 2).toFloat();

Gas[0] = GetValue(Incoming, ',', 3).toFloat();

Alt[0] = GetValue(Incoming, ',', 4).toFloat();

MQ4[0] = GetValue(Incoming, ',', 5).toInt();

MQ7[0] = GetValue(Incoming, ',', 6).toInt();

SD[0] = GetValue(Incoming, ',', 7).toInt();

//----------------------------------------

//---------------------------------------- Conditions for processing data or messages from Slave 2 (ESP32 Slave 2).

if (SL_Address == Destination_ESP32_Slave_2) {

Temp[1] = GetValue(Incoming, ',', 0).toFloat();

Humd[1] = GetValue(Incoming, ',', 1).toFloat();

Pres[1] = GetValue(Incoming, ',', 2).toFloat();

Gas[1] = GetValue(Incoming, ',', 3).toFloat();

Alt[1] = GetValue(Incoming, ',', 4).toFloat();


MQ4[1] = GetValue(Incoming, ',', 5).toInt();

MQ7[1] = GetValue(Incoming, ',', 6).toInt();

SD[1] = GetValue(Incoming, ',', 7).toInt();

//----------------------------------------

//----------------------------------------

/* if (SL_Address == Destination_ESP32_Slave_3) {

Temp[2] = GetValue(Incoming, ',', 0).toFloat();

Humd[2] = GetValue(Incoming, ',', 1).toFloat();

Pres[2] = GetValue(Incoming, ',', 2).toFloat();

Gas[2] = GetValue(Incoming, ',', 3).toFloat();

Alt[2] = GetValue(Incoming, ',', 4).toFloat();

MQ4[2] = GetValue(Incoming, ',', 5).toInt();

MQ7[2] = GetValue(Incoming, ',', 6).toInt();

SD[2] = GetValue(Incoming, ',', 7).toInt();

} */

// Calls the Update_OLED_Display() subroutine.*/

Update_OLED_Display();

//____________________________

//____________________________ Subroutine to display message content from slaves on OLED LCD.

void Update_OLED_Display() {

if ( SL_Address == 0x02 ) {

display.clearDisplay();

display.setTextSize(1);

display.setCursor(0,0);

display.print("Node1:");

display.setTextSize(1);

display.setCursor(45,0);

display.print(WiFi.localIP());

display.setTextSize(1);

display.setCursor(0, 20);

display.print("Time:");

display.print(timestamp);

display.setCursor(0, 35);

display.print("Temp:");

display.print(Temp[0]);

display.setCursor(60, 35);

display.print(",Hum:");

display.print(Humd[0]);

display.setCursor(0, 50);
display.print("Alt:");

display.print(Alt[0]);

display.display();

delay(1000);

if ( SL_Address == 0x03 ) {

display.clearDisplay();

display.setTextSize(1);

display.setCursor(0,0);

display.print("Node2:");

display.setTextSize(1);

display.setCursor(45,0);

display.print(WiFi.localIP());

display.setTextSize(1);

display.setCursor(0, 20);

display.print("Time:");

display.print(timestamp);

display.setCursor(0, 35);

display.print("Temp:");

display.print(Temp[1]);

display.setCursor(60, 35);

display.print(",Hum:");

display.print(Humd[1]);

display.setCursor(0, 50);

display.print("Alt:");

display.print(Alt[1]);

display.display();

delay(1000);

/*if ( SL_Address == 0x04 ) {

//GAS_ID = "AKfycbwmiv0KUf-7o-s1fBZruky-CER5-S_8yLPnvlK8tcnFUNx80XtRPxYOJ47L9aKV_aE"; //--> spreadsheet script ID

display.clearDisplay();

display.setTextSize(1);

display.setCursor(0,0);

display.print("Node3:");

display.setTextSize(1);

display.setCursor(45,0);

display.print(WiFi.localIP());

display.setTextSize(1);

display.setCursor(0, 20);

display.print("Temp:");
display.print(Temp[2]);

display.setCursor(60, 20);

display.print(",Hum:");

display.print(Humd[2]);

display.setCursor(0, 35);

display.print("Pre:");

display.print(Pres[2]);

display.setCursor(60, 35);

display.print(",Gas:");

display.print(Gas[2]);

display.setCursor(0, 50);

display.print("Alt:");

display.print(Alt[2]);

display.setCursor(60, 50);

display.print(",MQ4:");

display.print(MQ4[2]);

display.setCursor(0, 65);

display.print("MQ7:");

display.print(MQ7[2]);

display.setCursor(40, 65);

display.print("SD:");

display.print(SD[2]);

display.display();

delay(1000);

}*/

// Clears Incoming variable data.

Incoming = "";

//____________________________

void Getting_data_for_the_first_time() {

Serial.println();

Serial.println("Getting data for the first time...");

//---------------------------------------- Loop to get data for the first time.

while(true) {

unsigned long currentMillis_SendMSG = millis();

if (currentMillis_SendMSG - previousMillis_SendMSG >= interval_SendMSG) {

previousMillis_SendMSG = currentMillis_SendMSG;

Slv++;
if (Slv > 3) {

Slv = 0;

Serial.println();

Serial.println("Getting data for the first time has been completed.");

break;

Message = "N,N";

//::::::::::::::::: Condition for sending message / command data to Slave 1 (ESP32 Slave 1).

if (Slv == 1) {

Serial.println();

Serial.print("Send message to ESP32 Slave " + String(Slv));

Serial.println(" for first time : " + Message);

sendMessage(Message, Destination_ESP32_Slave_1);

//:::::::::::::::::

//::::::::::::::::: Condition for sending message / command data to Slave 2 (ESP32 Slave 2).

if (Slv == 2) {

Serial.println();

Serial.print("Send message to ESP32 Slave " + String(Slv));

Serial.println(" for first time : " + Message);

sendMessage(Message, Destination_ESP32_Slave_2);

//:::::::::::::::::

/* if (Slv == 3) {

Serial.println();

Serial.print("Send message to ESP32 Slave " + String(Slv));

Serial.println(" for first time : " + Message);

sendMessage(Message, Destination_ESP32_Slave_3);

}*/

//---------------------------------------- parse for a packet, and call onReceive with the result:

onReceive(LoRa.parsePacket());

//----------------------------------------

//----------------------------------------

//____________________________
//____________________________ String function to process the data received

// I got this from : https://www.electroniclinic.com/reyax-lora-based-multiple-sensors-monitoring-using-arduino/

String GetValue(String data, char separator, int index) {

int found = 0;

int strIndex[] = { 0, -1 };

int maxIndex = data.length() - 1;

for (int i = 0; i <= maxIndex && found <= index; i++) {

if (data.charAt(i) == separator || i == maxIndex) {

found++;

strIndex[0] = strIndex[1] + 1;

strIndex[1] = (i == maxIndex) ? i+1 : i;

return found > index ? data.substring(strIndex[0], strIndex[1]) : "";

//____________________________

//____________________________ Subroutine to reset Lora Ra-02.

void Rst_LORA() {

LoRa.setPins(ss, rst, dio0);

Serial.println();

Serial.println("Restart LoRa...");

Serial.println("Start LoRa init...");

if (!LoRa.begin(433E6)) { // initialize ratio at 915 or 433 MHz

Serial.println("LoRa init failed. Check your connections.");

while (true); // if failed, do nothing

Serial.println("LoRa init succeeded.");

// Reset the value of the Count_to_Rst_LORA variable.

Count_to_Rst_LORA = 0;

//____________________________

//____________________________ VOID SETUP

void setup() {

// put your setup code here, to run once:

Serial.begin(115200);

if (!rtc.begin()) {

Serial.println("Couldn't find RTC");


while (1);

// Set the RTC to a specific date & time

rtc.adjust(DateTime(F(_DATE), F(TIME_))); // Uncomment this line to set the RTC to the time this sketch was compiled

//rtc.adjust(DateTime(2024, 7, 8, 4, 29, 0)); // Set to specific time: YYYY, MM, DD, HH, MM, SS

//---------------------------------------- SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally.

// Address 0x3C for 128x32 and Address 0x3D for 128x64.

// But on my 128x64 module the 0x3D address doesn't work. What works is the 0x3C address.

// So please try which address works on your module.

if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {

Serial.println(F("SSD1306 allocation failed"));

for(;;); //--> Don't proceed, loop forever

//----------------------------------------

//----------------------------------------

display.clearDisplay();

display.setTextSize(1);

display.setTextColor(WHITE);

display.setCursor(32, 15);

display.println("ESP32 LORA");

display.setCursor(17, 35);

display.println("WEATHER STATION");

display.display();

//----------------------------------------

delay(2000);

//---------------------------------------- Clears the values of the Temp and Humd array variables for the first time.

for (byte i = 0; i < 3; i++) {

Temp[i] = 0.00;

Humd[i] = 0.00;

Pres[i] = 0.00;

Gas[i] = 0.00;

Alt[i] = 0.00;

MQ4[i] = 0;

MQ7[i] = 0;

SD[i] = 0;

//----------------------------------------
// Calls the Update_OLED_Display() subroutine.

Update_OLED_Display();

delay(1000);

// Calls the Rst_LORA() subroutine.

Rst_LORA();

// Calls the Getting_data_for_the_first_time() subroutine.

Getting_data_for_the_first_time();

WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

Serial.print("Connecting to WiFi");

while (WiFi.status() != WL_CONNECTED) {

Serial.print(".");

delay(250);

Serial.println("");

Serial.print("Successfully connected to : ");

Serial.println(WIFI_SSID);

Serial.print("IP address: ");

Serial.println(WiFi.localIP());

Serial.println();

ArduinoOTA.begin();

client.setInsecure();

server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){

request->send_P(200, "text/html", index_html, processor);

});

events.onConnect([](AsyncEventSourceClient *client){

if(client->lastId()){

Serial.printf("Client reconnected! Last message ID that it got is: %u\n", client->lastId());

client->send("hello!", NULL, millis(), 10000);

});

server.addHandler(&events);

server.begin();

//____________________________
//____________________________ VOID LOOP

void loop() {

ArduinoOTA.handle();

DateTime now = rtc.now();

sprintf(timestamp, "%02d:%02d:%02d", now.hour(), now.minute(), now.second());

unsigned long currentMillis_SendMSG = millis();

if (currentMillis_SendMSG - previousMillis_SendMSG >= interval_SendMSG) {

previousMillis_SendMSG = currentMillis_SendMSG;

//::::::::::::::::: The condition to update the OLED LCD if there is no incoming message from all slaves.

Count_OLED_refresh_when_no_data_comes_in++;

if (Count_OLED_refresh_when_no_data_comes_in > 5) {

Count_OLED_refresh_when_no_data_comes_in = 0;

Processing_incoming_data();

//:::::::::::::::::

//::::::::::::::::: Count the slaves.

Slv++;

if (Slv > 4) Slv = 1;

//:::::::::::::::::

//::::::::::::::::: Condition for sending message / command data to Slave 1 (ESP32 Slave 1).

if (Slv == 1) {

Serial.println();

Serial.println("Tr to : 0x" + String(Destination_ESP32_Slave_1, HEX));

Serial.println("Message: " + Message);

Temp[0] = 0.00;

Humd[0] = 0.00;

Pres[0] = 0.00;

Gas[0] = 0.00;

Alt[0] = 0.00;

MQ4[0] = 0;

MQ7[0] = 0;

SD[0] = 0;

sendMessage(Message, Destination_ESP32_Slave_1);

//:::::::::::::::::

//::::::::::::::::: Condition for sending message / command data to Slave 2 (ESP32 Slave 2).

if (Slv == 2) {
Serial.println();

Serial.println("Tr to : 0x" + String(Destination_ESP32_Slave_2, HEX));

Serial.println("Message: " + Message);

Temp[1] = 0.00;

Humd[1] = 0.00;

Pres[1] = 0.00;

Gas[1] = 0.00;

Alt[1] = 0.00;

MQ4[1] = 0;

MQ7[1] = 0;

SD[1] = 0;

sendMessage(Message, Destination_ESP32_Slave_2);

//:::::::::::::::::

//:::::::::::::::::

/* if (Slv == 3) {

Serial.println();

Serial.println("Tr to : 0x" + String(Destination_ESP32_Slave_3, HEX));

Serial.println("Message: " + Message);

Temp[2] = 0.00;

Humd[2] = 0.00;

Pres[2] = 0.00;

Gas[2] = 0.00;

Alt[2] = 0.00;

MQ4[2] = 0;

MQ7[2] = 0;

SD[2] = 0;

sendMessage(Message, Destination_ESP32_Slave_3);

} */

//----------------------------------------

unsigned long currentMillis_RestartLORA = millis();

if (currentMillis_RestartLORA - previousMillis_RestartLORA >= interval_RestartLORA) {

previousMillis_RestartLORA = currentMillis_RestartLORA;

Count_to_Rst_LORA++;

if (Count_to_Rst_LORA > 30) {

LoRa.end();

Rst_LORA();

}
}

if ((millis() - lastTime) > timerDelay) {

events.send("ping",NULL,millis());

events.send(String(Temp[0]).c_str(),"Temperature1",millis());

events.send(String(Humd[0]).c_str(),"Humidity1",millis());

events.send(String(Pres[0]).c_str(),"Pressure1",millis());

events.send(String(Gas[0]).c_str(),"Gas1",millis());

events.send(String(Alt[0]).c_str(),"Altitude1",millis());

events.send(String(SD[0]).c_str(),"SoundValue1",millis());

events.send(String(MQ4[0]).c_str(),"Methane1",millis());

events.send(String(MQ7[0]).c_str(),"Monoxide1",millis());

events.send(String(Temp[1]).c_str(),"Temperature2",millis());

events.send(String(Humd[1]).c_str(),"Humidity2",millis());

events.send(String(Pres[1]).c_str(),"Pressure2",millis());

events.send(String(Gas[1]).c_str(),"Gas2",millis());

events.send(String(Alt[1]).c_str(),"Altitude2",millis());

events.send(String(SD[1]).c_str(),"SoundValue2",millis());

events.send(String(MQ4[1]).c_str(),"Methane2",millis());

events.send(String(MQ7[1]).c_str(),"Monoxide2",millis());

/* events.send(String(Temp[2]).c_str(),"Temperature3",millis());

events.send(String(Humd[2]).c_str(),"Humidity3",millis());

events.send(String(Pres[2]).c_str(),"Pressure3",millis());

events.send(String(Gas[2]).c_str(),"Gas3",millis());

events.send(String(Alt[2]).c_str(),"Altitude3",millis());

events.send(String(SD[2]).c_str(),"SoundValue3",millis());

events.send(String(MQ4[2]).c_str(),"Methane3",millis());

events.send(String(MQ7[2]).c_str(),"Monoxide3",millis());

*/

lastTime = millis();

//----------------------------------------

if ((now.minute() == 0 || now.minute() == 30) && now.second() == 0) {

sendData(sheets1,Temp[0],Humd[0],Pres[0],Gas[0],Alt[0],MQ4[0],MQ7[0],SD[0]); //--> Calls the sendData Subroutine

sendData(sheets2,Temp[1],Humd[1],Pres[1],Gas[1],Alt[1],MQ4[1],MQ7[1],SD[1]); //--> Calls the sendData Subroutine

delay(60000);

//----------------------------------------parse for a packet, and call onReceive with the result:

onReceive(LoRa.parsePacket());
//----------------------------------------

//____________________________

void sendData(String GAS_ID,float a,float b,float c,float d,float e,int f,int g,int h) {

Serial.println("==========");

Serial.print("connecting to ");

Serial.println(host);

//----------------------------------------Connect to Google host

if (!client.connect(host, httpsPort)) {

Serial.println("connection failed");

return;

//----------------------------------------

//----------------------------------------Processing data and sending data

String string_param1 = String(a);

String string_param2 = String(b);

String string_param3 = String(c);

String string_param4 = String(d);

String string_param5 = String(e);

String string_param6 = String(f);

String string_param7 = String(g);

String string_param8 = String(h);

String url = "/macros/s/" + GAS_ID + "/exec?param1=" + string_param1 + "&param2=" + string_param2 + "&param3=" + string_param3 +
"&param4=" + string_param4 + "&param5=" + string_param5 + "&param6=" + string_param6 + "&param7=" + string_param7 + "&param8=" +
string_param8;

Serial.print("requesting URL: ");

Serial.println(url);

client.print(String("GET ") + url + " HTTP/1.1\r\n" +

"Host: " + host + "\r\n" +

"User-Agent: BuildFailureDetectorESP8266\r\n" +

"Connection: close\r\n\r\n");

Serial.println("request sent");

//----------------------------------------

//----------------------------------------Checking whether the data was sent successfully or not

while (client.connected()) {

String line = client.readStringUntil('\n');

if (line == "\r") {

Serial.println("headers received");
break;

String line = client.readStringUntil('\n');

if (line.startsWith("{\"state\":\"success\"")) {

Serial.println("esp8266/Arduino CI successfull!");

} else {

Serial.println("esp8266/Arduino CI has failed");

Serial.print("reply was : ");

Serial.println(line);

Serial.println("closing connection");

Serial.println("==========");

Serial.println();

//----------------------------------------

client.stop();

Dashboard Code:
Open a new tab add the below code, save it with “html.h” as file name and link it to the main LoRa Receiver code using the include property to get a webserver page for
displaying data on Dashboards

Google Script Code:

function doGet(e) {
Logger.log( JSON.stringify(e) );
var result = 'Ok';
if (e.parameter == 'undefined') {
result = 'No Parameters';
}
else {
var sheet_id = 'Spreadsheet I’d to be placed here';
var sheet = SpreadsheetApp.openById(sheet_id).getActiveSheet();
var newRow = sheet.getLastRow() + 1;
var rowData = [];
var Curr_Date = new Date();
rowData[0] = Curr_Date; // Date in column A
var Curr_Time = Utilities.formatDate(Curr_Date, "Asia/Kolkata", 'HH:mm:ss');
rowData[1] = Curr_Time; // Time in column B
for (var param in e.parameter) {
Logger.log('In for loop, param=' + param);
var value = stripQuotes(e.parameter[param]);
Logger.log(param + ':' + e.parameter[param]);
switch (param) {
case 'param1':
rowData[2] = value;
result = 'Temperature Written on column C';
break;
case 'param2':
rowData[3] = value;
result += ' ,Humidity Written on column D';
break;
case 'param3':
rowData[4] = value;
result += 'Pressure Written on column E';
break;
case 'param4':
rowData[5] = value;
result += 'Gas Written on column F';
break;
case 'param5':
rowData[6] = value;
result += 'Altitude Written on column G';
break;
case 'param6':
rowData[7] = value;
result += 'Methane Written on column H';
break;
case 'param7':
rowData[8] = value;
result += 'Monoxide Written on column I';
break;
case 'param8':
rowData[9] = value;
result += 'Sound Written on column J';
break;
default:
result = "unsupported parameter";
}
}
Logger.log(JSON.stringify(rowData));
var newRange = sheet.getRange(newRow, 1, 1, rowData.length);
newRange.setValues([rowData]);
}
return ContentService.createTextOutput(result);
}
function stripQuotes( value ) {
return value.replace(/^["']|['"]$/g, "");
}

You might also like