ESP32 LORA: Sensor de Gás, Umidade e Temperatura por SMS - Pt1 e Pt2



Já sabe como utilizar sensores destinados à segurança, envolvendo gás, temperatura e umidade, por exemplo, com um ESP32 Lora? Pois, hoje, você vai ver aqui como utilizar esse módulo deste microcontrolador como Sender e Receiver. Ainda, vou mostrar como usar um Arduino Nano com módulo Ethernet e efetuar comunicação pela Rede. Destaco que, como o assunto é extenso, prometo um segundo artigo sobre este assunto, assim como um novo vídeo, para a próxima semana.

ESP32 Lora Dispotivos de Segurança com Sender e Receiver

Neste projeto temos uma montagem simples, que vai funcionar como um alarme que vai enviar mensagem SMS para o seu smartphone em caso de algum tipo de problema. Para tal, empregaremos um módulo sensor de gás MQ2 e um sensor de temperatura e umidade DHT22 (AM2302). Ambos serão lidos por um primeiro ESP32 Lora, que funcionará como Sender, e enviará alerta para um segundo ESP32 Lora, que estará como Receiver, caso haja algum tipo de vazamento de gás, por exemplo.

Montagem

Usando, então, uma simulação de vazamento de gás, como na nossa demonstração (imagem acima), o Sender vai enviar um sinal ao Receiver, que vai ligar o Buzzer e transmitir uma mensagem para o Arduino Nano via serial para acender um Led vermelho. Como a porta SPI deste Receiver já vai estar ocupada, ele vai enviar os dados via UART ao Arduino Nano, que via SPI vai se comunicar com a interface Ethernet. O software que está no Arduino Nano, comandado pelo Receiver vai, então, enviar um SMS ao seu celular te avisando sobre um possível perigo de vazamento de gás.
Portanto, o ESP32 é que vai ler o valor analógico e indicar quanto de gás e qual o risco de explosão no local analisado, informações que serão direcionadas ao SMS.
Na nossa montagem, portanto, coloquei no Receiver uma interface Ethernet de cabo. Por quê? Porque neste projeto precisamos de confiabilidade, garantindo acesso em caso de falha do WiFi. Com isso garantimos o envio do SMS, que pode ser substituído por e-mail ou ligação, conforme sua preferência e disponibilidade de gateway.

 Funcionamento (Transmissão de dados)

Aqui temos um diagrama sobre o funcionamento da montagem.

Funcionamento da Trasmissão de Dados

Recursos usados

  • 2 ESP32 LoRa Display OLED
  • 1 Arduino Nano ATmega328
  • 1 Módulo Ethernet ENC28J60 para Arduino
  • 1 Módulo Sensor de gás MQ2
  • 1 Sensor de temperatura e humidade DHT22 (AM2302)
  • 2 Resistores de 330 ohm
  • 1 Resistor de 4k7 ohm
  • 1 Buzzer 5V
  • 1 Led verde
  • 1 Led vermelho
  • Jumpers

Recursos usados – Sender

Recursos utilizados
  • 1 ESP32 LoRa Display
  • 1 Módulo Sensor de gás MQ2
  • 1 Sensor de temperatura e humidade DHT22 (AM2302)
  • 1 Resistor de 4k7 ohm
  • Jumpers


Recursos usados – Receiver

Recursos utilizados
  • 1 ESP32 LoRa Display OLED
  • 1 Arduino Nano ATmega328
  • 1 Módulo Ethernet ENC28J60 para Arduino
  • 2 Resistores de 330 ohm
  • 1 Buzzer 5V
  • 1 Led verde
  • 1 Led vermelho
  • Jumpers


Sensibilidade do sensor de gás MQ-2

A resistência (Rs/Ro) do sensor é mais alta ou mais baixa de acordo com a concentração de gás (ppm) existente. Esta concentração pode ser visualizada pela saída do pino A0.
O sensor de gás MQ-2 tem alta sensibilidade aos gases:
·         LPG (Gás liquefeito de petróleo);
·         Propano (C3H8);
·         Hidrogênio (H2);
·         Metano (CH4);
·         Gases combustíveis, como o Propano, CO, Álcool e Butano (utilizado em isqueiros).

Tabela de Sensibilidade do sensor de gás MQ-2



Montagem Sender

Pinout ESP32 Lora OLED

Pinout ESP32 Lora Oled

Sender Circuito

Circuito do Sender

Sender Montagem

Montagem do Sender



Montagem Receiver

Pinout Arduino Nano ATmega328

Pinout Arduino Nano ATmega328

Receiver Circuito

Circuito do Receiver

Receiver Montagem

Led verde sinaliza que o arduino foi inicializado.
Led vermelho indica que o SMS foi enviado.
Ao enviar o SMS, o arduino é desconectado para que não sejam enviadas mais mensagens.
Montagem do Receiver

Instalação da biblioteca do DHT

1. Vá em Sketch->Incluir Biblioteca->Gerenciador de Bibliotecas.
2. Pesquise por SimpleDHT e clique em instalar.

Biblioteca do DHT

Código Sender

Sender – Organização do código

Fluxograma de organização do código

Setup

Loop
- readDhtSensor: Função responsável por ler sensor e obter valores de temperatura e umidade.
-  gasDetected: Função responsável por ler sensor e verificar se o gás foi detectado.
- sendPacket: Função responsável por enviar o pacote via LoRa para o Receiver.
- showDisplay: Função responsável por exibir no display as mensagens e valores obtidos.

Código Sender [Includes e Defines]

De início, vamos incluir as bibliotecas e fazer a definição dos pinos.

Código do Sender

#include <SPI.h> //lib para comunicação serial
#include <LoRa.h> //lib para comunicação com o WIFI Lora
#include <Wire.h>  //lib para comunicação i2c
#include "SSD1306.h" //lib para comunicação com o display
#include <SimpleDHT.h>//lib para comunicação com o dht

//Descomente as linhas abaixo para o tipo do sensor DHT que você estiver usando!

//#define DHTTYPE DHT11   // DHT 11
//#define DHTTYPE DHT21   // DHT 21 (AM2301)
#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321

// Definição dos pinos 
#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//pino analógico do sensor de gás
#define MQ_dig 13    //pino digital do sensor de gás

#define BAND    433E6  //Frequencia do radio - podemos utilizar ainda : 433E6, 868E6, 915E6

Vamos tratar do sensor de das variáveis usadas para receber o sinal analógico e digital, além de definir o valor mínimo de acionamento do sensor de gás.

Código do Sender

// DHT Sensor
const int DHTPin = 23;

int analog_value;    //variável usada para receber o sinal analógico do sensor (de 100 a 10000)
int dig_value;       //variável usada para receber o sinal digital do sensor
int gas_limit = 0;   //usado para indicar o valor mínimo de acionamento do sensor de gás (este valor varia conforme for ajustado o parafuso do sensor)

//h = humidade; c = temperatura em graus celsius
float h, c;

String packSize; //variável usada para receber tamanho do pacote convertido em String
String packet = "OK";   //variável usada para armazenar a string enviada, ao final ela é concatenada com a variável "values" abaixo
String values = "|-|-"; //valores de humidade e temperatura são separados por pipe

//parametros: address,SDA,SCL 
SSD1306 display(0x3c, 4, 15); //construtor do objeto que controlaremos o display


Código Sender [Setup]

No Setup, primeiro vamos configurar os pinos e o display.

Código do Sender

void setup()
{
  //inicializa valores de humidade e temperatuda com zero
  h = c = 0;
  //inicia serial com 9600 bits por segundo
  Serial.begin(9600);
  //configura pino analog. do sensor como entrada
  pinMode(MQ_analog, INPUT);
  //configura pino digital do sensor como entrada
  pinMode(MQ_dig, INPUT);
  //configura os pinos oled como saida
  pinMode(16,OUTPUT); //pino RST do oled display
  //reseta o OLED
  digitalWrite(16, LOW);    
  //aguarda 50ms
  delay(50); 
  //enquanto o OLED estiver ligado, GPIO16 deve estar HIGH
  digitalWrite(16, HIGH); 
  //inicializa o display
  display.init(); 
  //inverte verticalmente o display (de ponta cabeça)
  display.flipScreenVertically();

Na sequência, definimos características de impressão no display e iniciamos a comunicação serial com o Lora, seguindo com sua configuração.

Código do Sender

//configura a fonte para um tamanho maior
  display.setFont(ArialMT_Plain_10); 
  //aguarda 1500ms
  delay(1500);
  //apaga todo o conteúdo da tela do display
  display.clear();
  
  //inicia a comunicação serial com o Lora
  SPI.begin(SCK,MISO,MOSI,SS); 
  //configura os pinos que serão utlizados pela biblioteca (deve ser chamado antes do LoRa.begin)
  LoRa.setPins(SS,RST,DI00); 
  
  //inicializa o Lora com a frequencia específica
  if (!LoRa.begin(BAND))
  {
    //escreve na pos 0,0 a mensagem entre aspas
    display.drawString(0, 0, "Starting LoRa failed!");
    //mostra o conteúdo na tela
    display.display(); 
    //fica em loop infinito até que o ESP seja reiniciado
    while (true);
  }    
}


Código Sender [Loop]

No Loop também trabalhamos com características do display e indicamos os procedimentos de leitura dos sensores, bem como de detecção de gás e o envio de alerta pelo Lora.

Código do Sender

void loop()
{
  //apaga o conteúdo do display
  display.clear();
  //alinha texto do display à esquerda
  display.setTextAlignment(TEXT_ALIGN_LEFT);
  //configura fonte do texto
  display.setFont(ArialMT_Plain_16);
  //exibe na pos 0,0 a mensagem entre aspas
  display.drawString(0, 0, "Running...");
  //lê valores do sensor de temperatura
  readDhtSensor();  
  //insere na string os valores de humidade e temperatura separados por pipe
  values="|"+String(h)+"|"+String(c);  
  //se no pino digital do sensor receber sinal baixo, significa que foi detectado gás
  if(gasDetected())
  {
    //atribui à variável o texto ALARM
    packet = "ALARM";   
    //concatena com o pacote os valores, separados por pipe 
    packet+=values;
    //envia pacote por LoRa
    sendPacket();
    //chama função para exibir no display com flag true, indicando gás detectado
    showDisplay(true);
  }

Definimos as informações que serão enviadas por SMS.


Código do Sender


 else
  { 
    //atribui à variável o texto OK
    packet = "OK"; 
    //concatena com o pacote os valores, separados por pipe 
    packet+=values;
    //envia pacote por LoRa
    sendPacket();
    //chama função para exibir no display, com flag false, indicando gás não detectado
    showDisplay(false);
  }
  //aguarda 250ms
  delay(250);
}

Código Sender [showDisplay]

Novamente tratamos da exibição de dados no display do Lora.

Código do Sender

void showDisplay(bool gasDetected)
{
  //apaga o conteúdo do display
  display.clear();
  //alinha texto do display à esquerda
  display.setTextAlignment(TEXT_ALIGN_LEFT);
  //configura fonte do texto
  display.setFont(ArialMT_Plain_16);
  //exibe na pos 0,0 a mensagem
  display.drawString(0, 0, "Running...");

  //se o gás foi detectado
  if(gasDetected)
  {
    //escreve na pos 0,20 a mensagem
    display.drawString(0, 20, "Status: ALARM");
    //escreve na pos 0,40 a mensagem
    display.drawString(0, 40, "Gas detected!");
    //exibe display
    display.display(); 
  }  


Código do Sender

 else
  {
    //escreve na pos 0,20 a mensagem
    display.drawString(0, 20, "Status: OK");    
    //escreve na pos 0,40 a mensagem  
    display.drawString(0, 40, "H: "+String(h)+" T: "+String(c)+"°");   
    //exibe no display
    display.display(); 
  }
}


Código Sender [gasDetected]

Aqui temos a função responsável por disparar mensagem caso o sensor detecte algum tipo de vazamento de gás.

Código do Sender

//função responsável por disparar mensagem caso o sensor detectar gás
bool gasDetected()
{  
  //lê o valor analógico do sensor (servirá apenas como informativo pela serial)
  analog_value = analogRead(MQ_analog); 
  //lê o valor digital do sensor, caso sinal baixo o gás foi detectado
  dig_value = digitalRead(MQ_dig);
 
  //obs: as exibições pela serial neste código não influenciam o funcionamento do protótipo
  //exibe valor pela serial
  Serial.print(analog_value);
  //exibe separador "||" pela serial
  Serial.print(" || ");

  //lógica inversa, se "0" então foi detectado gás
  if(dig_value == 0)
  {
    //define o valor analógico mínimo (servirá apenas como informativo pela serial)
    if(gas_limit == 0 || gas_limit > analog_value)
      gas_limit = analog_value;

    //exibe na serial "Gas detectado"
    Serial.println("GAS DETECTED !!!");
    //exibe o limite mínimo de gás captado para o evento ocorrer
    Serial.println("Gas limit: "+String(gas_limit));

    //retorna verdadeiro
    return true;
  }


Código do Sender

 else 
  {
    //exibe na serial "Gas ausente" 
    Serial.println("No gas detected...");

    //exibe o limite mínimo default "X" caso não foi acionado pela primeira vez
    if(gas_limit == 0)
      Serial.println("Gas limit: X");
    else //exibe o limite mínimo de gás captado para o evento ocorrer
      Serial.println("Gas limit: "+String(gas_limit));

    //retorna falso
    return false;
  }
}

Código Sender [readDhtSensor]

Código do Sender

void readDhtSensor()
{
  //declara variaveis que receberão a nova temperatura e humidade
  float novoC, novoH;
  //aguarda 250ms
  delay(250);
  //lê valores do sensor dht22 para as variaveis &c e &h
  int err = dht22.read2(DHTPin, &novoC, &novoH, NULL);
  //verifica se ocorreu algum erro
  if (err != SimpleDHTErrSuccess) 
  {
    //informa o erro pela serial
    Serial.print("Read DHT22 failed, err="); 
    Serial.println(err);
    return;
  }
  //se foi possível ler a temperatura, então atribui para as variáveis
  c = novoC;
  h = novoH;
  //exibe valores pela serial
  Serial.print((float)c); Serial.println(" *C ");
  Serial.print((float)h); Serial.println(" H");
  //aguarda 250ms
  delay(250);
}

Código Sender [sendPacket]

Por fim, abrimos um pacote para adicionarmos os dados para envio por SMS.

Código do Sender

void sendPacket()
{
  //beginPacket : abre um pacote para adicionarmos os dados para envio
  LoRa.beginPacket();
  //envia pacote
  LoRa.print(packet);
  //endPacket : fecha o pacote e envia
  LoRa.endPacket(); //retorno= 1:sucesso | 0: falha
}



Faça o download dos arquivos:


9 comentários:

  1. Boa noite Fernando,ensina para nos como sé faz uma impressora 3d com arduino ou melhor ainda com Esp32

    ResponderExcluir
  2. Fernando. Qual realmente é melhor? Esp32 ou Esp8266 ?

    ResponderExcluir
    Respostas
    1. Olá. Os dois são muito bons, você precisa avaliar de acordo com sua aplicação desejada. O ESP32 tem melhor processamento que o ESP8266. Abraço!

      Excluir
  3. Bom dia Fernando, obrigado pela aula :) o ficheiro .rar com o INO está a dar erro e não abre. Abraços!

    ResponderExcluir
    Respostas
    1. Olá. Fiz um teste aqui e abriu normalmente. Tente novamente, por favor: http://download.fernandok.com/ESP32LoraDispositivosSegurança.rar

      Excluir
  4. Obrigado, devia ser deste pc... com o winrar continua a dar erro, mas tentei noutro pc com o 7zip e já consegui abrir. Peço desculpa ;)

    ResponderExcluir
  5. olá Fernando tudo bem??? muito boa essa aula estou aprendendo bastante com suas video aulas, fui compilar o sender deu os seguintes erros:

    C:\Users\ddspe\Downloads\ESP32LoraDispositivosSegurança\Código\OLED_LoRa_Sender\OLED_LoRa_Sender.ino: In function 'void setup()':

    OLED_LoRa_Sender:79: error: no matching function for call to 'LoRaClass::begin(double)'

    In file included from C:\Users\ddspe\Downloads\ESP32LoraDispositivosSegurança\Código\OLED_LoRa_Sender\OLED_LoRa_Sender.ino:2:0:

    C:\Users\ddspe\Documents\Arduino\hardware\espressif\esp32\libraries\LoRa\src/LoRa.h:24:7: note: candidate: int LoRaClass::begin(long int, bool)

    int begin(long frequency,bool PABOOST);

    ^

    C:\Users\ddspe\Documents\Arduino\hardware\espressif\esp32\libraries\LoRa\src/LoRa.h:24:7: note: candidate expects 2 arguments, 1 provided

    exit status 1
    no matching function for call to 'LoRaClass::begin(double)'

    o que vc acha que pode ser??

    Obrigado.

    ResponderExcluir
    Respostas
    1. descobri era poor causa do PABOOST
      defini o PABOOST e adicionei na linha if
      (!LoRa.begin(BAND,PABOOST))
      ai resolveu.
      Abraço

      Excluir
  6. Boa noite Fernando, tenho algumas duvidas sobre um projeto que estou montando, voce tem algum contato para mim estar explicando melhor? desde ja agradeço.

    ResponderExcluir

Tecnologia do Blogger.