ESP32 LORA: Gas Sensor, Humidity, and Temperature by SMS
by Fernando Koyanagi in Circuits > Microcontrollers
15043 Views, 17 Favorites, 0 Comments
ESP32 LORA: Gas Sensor, Humidity, and Temperature by SMS
Sensors, with an ESP32 LORA, can be easily designed for safety purposes involving gas, temperature, and humidity. Today, I’m going to show you precisely how to use this microcontroller module as a Sender and Receiver. Also, I'll show you how to use an Arduino Nano with an Ethernet module, and communicate over the Network. Considering that this subject is extensive, I promise to create a second article concerning this subject for next week, as well as a new video.
In this project, we have a simple assembly, which will work as an alarm to send SMS messages to your smartphone if problems arise. To do so, we will first employ a gas sensor module, MQ2, and the temperature and humidity sensor DHT22 (AM2302). Both will be read by the first ESP32 LORA, which will function as the Sender, and will send an alert to the second ESP32 Lora, which will be a Receiver. This provides safety for a situation such as a gas leak, for example.
Using a gas leak simulation, as in our demonstration (image above), the Sender will send a signal to the Receiver, which will turn on the Buzzer and the red LED. As the SPI port of this Receiver will already be busy, it will send the data via UART to the Arduino Nano. Through the SPI, it will then communicate with the Ethernet interface. The software on this Receiver will then send an SMS to your cell phone notifying a potential gas leak hazard.
The ESP32 will read the analog value and indicate the quantity of gas involved, and the risk of explosion in the analyzed location. This information will be directed to the SMS.
In our assembly, I placed an Ethernet cable interface on the Receiver. Why is this performed? Because we need reliability in this project, where there is guaranteed access even during WiFi failure. This ensures the sending of SMS, which can be replaced by email or connection, according to your preference and gateway availability.
Operation (Data Transmission)
Here is a diagram of how the assembly works.
Resources Used
2 ESP32 LORA OLED Display
1 Arduino Nano ATmega328
1 Ethernet Module ENC28J60 for Arduino
1 Gas sensor module MQ2
1 Humidity and Temperature Sensor DHT22 (AM2302)
2 330 ohm resistors
1 4k7 ohm resistor
1 Buzzer 5V
1 green LED
1 red LED
Jumpers
Features - Sender
1 ESP32 LORA Display
1 Gas sensor module MQ2
1 Humidity and Temperature Sensor DHT22 (AM2302)
1 4k7 ohm resistor
Jumpers
Features Used - Receiver
1 ESP32 LORA OLED Display
1 Arduino Nano ATmega328
1 Ethernet Module ENC28J60 for Arduino
2 330 ohm resistors
1 Buzzer 5V
1 green LED
1 red LED
Jumpers
MQ-2 Gas Sensor Sensitivity
The resistance (Rs / Ro) of the sensor is higher or lower according to the existing gas concentration (ppm). This concentration can be visualized by the output of pin A0.
The MQ-2 gas sensor has high sensitivity to gases:
• LPG (liquefied petroleum gas);
• Propane (C3H8);
• Hydrogen (H2);
• Methane (CH4);
• Fuel gases, such as Propane, CO, Alcohol, and Butane (used in lighters).
Sender Mount --- Pinout ESP32 LORA OLED
Sender Circuit
Sender Mounting
Mounting Receiver --- Pinout Arduino Nano ATmega328
Receiver Circuit
Receiver Mounting
Green LED indicates that the Arduino is connected to the Ethernet client.
Red LED indicates that SMS has been sent.
When sending the SMS, the Arduino is disconnected so that no more messages are sent.
DHT Library Installation
1. Go to Sketch->Include Library->Library Manager.
2. Search for SimpleDHT and click Install.
Sender - Organization of the Code
Setup
Loop
- readDhtSensor: Function responsible for reading the sensor and obtaining values of temperature and humidity.
- gasDetected: Function responsible for reading the sensor and verifying that the gas has been detected.
- sendPacket: Function responsible for sending the package via LORA to the Receiver.
- showDisplay: Function responsible for displaying the messages and values obtained on the display.
Sender Code [Includes and Defines]
First, we will include the libraries to make the definition of the pins.
#include <SPI.h> //serial peripheral interface (SPI) library #include <LoRa.h> //wifi lora library #include <Wire.h> //communication i2c library #include "SSD1306.h" //display communication library #include <SimpleDHT.h> //dht communication library //Descomment the line below which dht sensor type are you using //#define DHTTYPE DHT11 // DHT 11 //#define DHTTYPE DHT21 // DHT 21 (AM2301) #define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321</p><p>// Pins definition #define SCK 5 // GPIO5 -- SX127x's SCK #define MISO 19 // GPIO19 -- SX127x's MISO #define MOSI 27 // GPIO27 -- SX127x's MOSI #define SS 18 // GPIO18 -- SX127x's CS #define RST 14 // GPIO14 -- SX127x's RESET #define DI00 26 // GPIO26 -- SX127x's IRQ(Interrupt Request) #define MQ_analog 12 //analog gas sensor pin #define MQ_dig 13 //digital gas sensor pin #define BAND 433E6 //Radio frequency, we can still use: 433E6, 868E6, 915E6
We will deal with the sensor of the variables used to receive the analog and digital signal, in addition to defining the minimum trigger value of the gas sensor.
// DHT Sensor<br>const int DHTPin = 23; int analog_value; //variable used to receive the analog signal from sensor (from 100 to 10000) int dig_value; //variable used to receive the digital signal from sensor int gas_limit = 0; //used to indicates the minimum value to active the gas sensor (that value changes as the sensor screw is adjusted) //h = humidity; c = Celsius temperature float h, c; String packSize; //variable used to receive the size of package converted in string String packet = "OK"; //part of packet, that informs the status of sensor. That variable will be concatenate with the string "values" String values = "|-|-"; //humidity and temperature values, separated by pipe //parameters: address,SDA,SCL SSD1306 display(0x3c, 4, 15); //display object SimpleDHT22 dht22;
Sender Code [Setup]
In the Setup, we will first configure the pins and the display.
void setup() { //set the humidity and temperature values with zero h = c = 0; //initialize the Serial with 9600b per second Serial.begin(9600); //configures analog pin as input pinMode(MQ_analog, INPUT); //configures digital pin as input pinMode(MQ_dig, INPUT); //configures oled pins as output pinMode(16,OUTPUT); //reset oled digitalWrite(16, LOW); //wait 50ms delay(50); //while the oled is on, GPIO16 must be HIGH digitalWrite(16, HIGH); //initializes the display display.init(); //flip vertically the display display.flipScreenVertically();
Next, we will define the print characteristics on the display, and start the serial communication with LORA. We then will proceed to its configuration.
//set display font display.setFont(ArialMT_Plain_10); //wait 1500ms delay(1500); //clear the display display.clear(); //initializes serial interface SPI.begin(SCK,MISO,MOSI,SS); //set Lora pins LoRa.setPins(SS,RST,DI00); //initializes the lora, seting the radio frequency if (!LoRa.begin(BAND)) { //draw in the position 0,0 the message in between quotation marks display.drawString(0, 0, "Starting LoRa failed!"); //turns on the LCD display display.display(); //do nothing forever while (true); } }
Sender Code [Loop]
In the Loop, we also work with the characteristics of the display, and indicate the procedures of reading the sensors, as well as gas detection and the sending of alerts by the LORA.
<p>void loop()<br>{ //clear the display display.clear(); //set the text alignment to left display.setTextAlignment(TEXT_ALIGN_LEFT); //sets the text font display.setFont(ArialMT_Plain_16); //draw in the position 0,0 the message in between quotation marks display.drawString(0, 0, "Running..."); //reads temperature sensor values readDhtSensor(); //it concatenates on string the humidity and temperature values separated by pipe values="|"+String(h)+"|"+String(c); //if the digital signal of sensor is lower, it means gas detected (inverse logic) if(gasDetected()) { //sets the value of the packet string to "ALARM" packet = "ALARM"; //it concatenates the packet with the values packet+=values; //sends package by LoRa sendPacket(); //shows display, true = gas detected showDisplay(true); }
We define the information that will be sent by SMS.
else { //sets the value of the packet string to "OK" packet = "OK"; //it concatenates the packet with the values packet+=values; //sends package by LoRa sendPacket(); //shows display, false = no gas detected showDisplay(false); } //waits 250ms delay(250); }
Sender Code [showDisplay]
Again, we deal with the display of data on the LORA’s display.
void showDisplay(bool gasDetected) { //clear the display display.clear(); //set the text alignment to left display.setTextAlignment(TEXT_ALIGN_LEFT); //sets the text font display.setFont(ArialMT_Plain_16); //draw in the position 0,0 the message in between quotation marks display.drawString(0, 0, "Running...");</p><p> //if flag = true if(gasDetected) { //draw in the position 0,20 the message in between quotation marks display.drawString(0, 20, "Status: ALARM"); //draw in the position 0,40 the message in between quotation marks display.drawString(0, 40, "Gas detected!"); //turns on the LCD display display.display(); } else { //draw in the position 0,20 the message in between quotation marks display.drawString(0, 20, "Status: OK"); //draw in the position 0,40 the message in between quotation marks display.drawString(0, 40, "H: "+String(h)+" T: "+String(c)+"°"); //turns on the LCD display display.display(); } }
Sender Code [gasDetected]
Here, we have the function responsible for triggering a message if the sensor detects some type of gas leakage.
bool gasDetected() { //reads the analog value of the sensor analog_value = analogRead(MQ_analog); //reads the digital value of the sensor dig_value = digitalRead(MQ_dig); //obs: the serial views in this code do not influence the operation of the prototype //shows value to the serial Serial.print(analog_value); //shows tab "||" to the serial Serial.print(" || "); //inverse logic if(dig_value == 0) { //sets the minimum analog value if(gas_limit == 0 || gas_limit > analog_value) gas_limit = analog_value; //shows 'gas detected' to the serial Serial.println("GAS DETECTED !!!"); //shows the minimum gas limit to the serial Serial.println("Gas limit: "+String(gas_limit)); //gas detected return true; } else { //shows 'no gas detected' to the serial Serial.println("No gas detected..."); //if first time, shows 'X' to the serial if(gas_limit == 0) Serial.println("Gas limit: X"); else //shows gas limit to the serial Serial.println("Gas limit: "+String(gas_limit)); //no gas detected return false; } }
Sender Code [readDhtSensor]
void readDhtSensor() { // declaration of variables that will receive the new temperature and humidity float novoC, novoH; //waits 250ms delay(250); //set dht22 sensor values tovariables &novoC and &novoH int err = dht22.read2(DHTPin, &novoC, &novoH, NULL); //checks for an error if (err != SimpleDHTErrSuccess) { //shows error in the serial Serial.print("Read DHT22 failed, err="); Serial.println(err); return; } //if no error //sets the variable values c = novoC; h = novoH; //shows values in the serial Serial.print((float)c); Serial.println(" *C "); Serial.print((float)h); Serial.println(" H"); //waits 250ms delay(250); }
Sender Code [sendPacket]
Finally, we opened a package to add the data for SMS sending.
void sendPacket() { //starts a connection to write UDP data LoRa.beginPacket(); //send packet LoRa.print(packet); //returns an int: 1 if the packet was sent successfully, 0 if there was an error LoRa.endPacket(); }