Monitoraggio remoto di umidità e temperatura con un'app Android Java utilizzando MQTT e una scheda ESP8266 NodeMcu

Il progetto illustra come ottenere su un telefono Android i valori di umidità e temperatura di un ambiente remoto utilizzando una scheda ESP8266 NodeMCU e il protocollo di messaggistica MQTT. L''umidità e la temperatura sono rilevate da un sensore DHT11.

MQTT è un protocollo publish/subscribe molto leggero ed efficiente e viene comunemente usato per le applicazioni di Internet of Things. Uno degli utilizzi più diffusi di MQTT è quello di permettere la comunicazione tra i dispositivi embedded, basati ad esempio su Arduino o ESP8266, e i nostri smartphone. In questo caso grazie a MQTT è possibile leggere sul nostro telefonino, da qualsiasi angolo del mondo, l'umidità e la temperatura misurati in un ambiente.

mqttdht11

Il progetto spiega in dettaglio come programmare, utilizzando l'IDE di Arduino, la scheda ESP8266 NodeMCU interfacciata con il sensore DHT11, e come sviluppare l'app android in ambiente Java Android Studio

 Codice dello sketch Arduino Ide sulla scheda ESP8266 NodeMCU

/*
 * -------------------------------------------------------
 * Prof. Mauro De Berardis 2021
 * ------------------------------------------------------- 
 * Il progetto illustra  come ottenere su un telefono Android i valori di temperatura e umidità 
 * di un ambiente remoto utilizzando una scheda ESP8266 NodeMCU e il protocollo di messaggistica 
 * MQTT. L''umidità e la temperatura  sono rilevate da un sensore DHT11.
 * Lo sketch realizza il client MQTT della scheda ESP8266 NodeMCU
 */
#include <ESP8266WiFi.h> 
//La libreria ESP8266WiFi permette la connessione della scheda  alla rete WiFi 
 
#include <PubSubClient.h>
/*La libreria PubSubClient consente al client di connettersi al broker MQTT e di
 *pubblicare messaggi e/o sottoscrivere topic 
*/
#include <DHT.h>      //libreria necessaria per utilizzare il sensore DHT11
#define sensorePin D1 
// pin di ESP8266 NodeMCU collegato all'uscita (pin OUT) del sensore DHT1
#define tipoDHT DHT11 
/* definisce il tipo di sensore della famiglia DHT:  in questo caso viene selezionato   
   DHT11, ma esistono sono altri sensori quali DHT21 e DHT22 
*/
DHT dht(sensorePin,tipoDHT);  //Istanzia l'oggetto dht della classe DHT    
float H;          //umidità   
float T;         //temperatura
 
//***Configurazione WiFI: impostazione delle credenziali di rete
const char* ssid = "MySSID";        //Inserire qui l'SSID
const char* password = "MyPassword"; //Inserire qui la password WiFi
 
// MQTT Broker
/*
 * Per questo progetto, utilizziamo un server broker pubblico e gratuito  per l'apprendimento, 
 * il test  e  la prototipazione MQTT. Qualsiasi dispositivo può pubblicare e sottoscrivere 
 * argomenti su di esso e non esiste una protezione della privacy. Non usarlo mai in produzione
 */
const char  *mqttServer = "broker.emqx.io";
const char  *mqttUser = "emqx";
const char  *mqttPassword = "public";
const int    mqttPort = 1883;
const char  *topic =  "mdb/leggi_dht11";
 
 
//Creazione un oggetto clientMQTT che chiamiamo semplicemente 'client'
WiFiClient  wificlient;
PubSubClient client(wificlient);
char messaggio[30];
 
void setup() {
  delay(1000);
  pinMode(sensorePin, INPUT);  
  dht.begin(); //inizializza l'oggetto dht
  // apre una connessione seriale. A scopo di debug inviamo messaggi al monitor seriale
  Serial.begin(115200); 
  WiFi.begin(ssid, password);   //Si connette al router WiFi
  Serial.println("Connessione al WiFi in corso..");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("ESP8266 NodeMCU connessa alla rete WiFI: ");
  Serial.print(ssid);
  Serial.print("  con il numero IP : ");
  Serial.println(WiFi.localIP());//l'IP di ESP8266 viene assegnato automaticamente dal DHCP
  Serial.println();
 
 /* Per creare una connessione ad un broker dobbiamo: 
  *  1. usare il metodo setServer  e fornire indirizzo e porta del broker 
  *  2. creare una funzione di callback (che chiamiamo MQTTcallback) e
  *  impostare  il metodo setCallback(MQTcallback) per ricevere messaggi
  */
  client.setServer(mqttServer, mqttPort);
  client.setCallback(MQTTcallback);
  connettiMQTT(); 
  client.subscribe(topic); 
 // il client sottoscrive il topic "mdb/leggi_dht11" che riguarda i messaggi  pubblicati dall'app 
 
}//----chiude setup()--------------------
 
 
void loop() 
{
  client.loop();
  if( !client.connected()){
    connettiMQTT();
    if(client.connected())      client.subscribe(topic); 
  }
}
 
void MQTTcallback(char* topic, byte* payload, unsigned int length) 
{
  /* la funzione di callback serve ad  elaborare i messaggi man mano ricevuti. Accetta  tre 
   *  argomenti: topic (char), payload (il messaggio effettivo in byte),lunghezza del payload
 */
  Serial.print("Messagi in arrivo al topic: ");
  Serial.println(topic);
 
  Serial.print("Messaggio:");
 
  String message;
  for (int i = 0; i < length; i++) {
    message = message + (char)payload[i];  
    //Converte il messaggio da byte a String
  }
  Serial.println(message);
  // in  questo caso è previsto solo al'arrivo del messaggio "leggi" 
  if(message == "leggi")
  {
    // legge l'umidità H  e la temperatura T
    leggeHT(); 
 
    // pubblica i valori di H e T sul topic "mdb/valori_dht11"  sottoscritto dall'app android   
    pubblicaHT(); 
  }
 
  Serial.println("--------------------------------------------------");  
}
void connettiMQTT(){
 
 while (!client.connected())
  {
    Serial.println("Connessione a  MQTT in corso..");
    //
    if (client.connect("ESP8266", mqttUser, mqttPassword ))
    {
        Serial.println("MQTT connesso");    
        digitalWrite(Led, 1);
    } 
    else 
    {
      Serial.print("Errore connessione MQTT");
      Serial.println(client.state());  
      delay(2000);
    }
  }
 
}
 
void leggeHT(){
   // faccio 3 letture in modo che i valori letti dal sensore, che non è velocissimo, si     
   // stabilizzino 
    for(int i=0;i<3;i++)
    { 
        H = dht.readHumidity();     // Lettura dell'umidità  
        T = dht.readTemperature();  // Lettura della temperatura in gradi Celsius 
        delay(200);
    } 
}
 
void pubblicaHT(){
  if (isnan(H) || isnan(T))  //Verifica se  si presenta un errore di lettura   
    {  
          Serial.println("Errore di lettura...");  
          H=0.0;
          T=0.0;
    } 
    else
    {
          String s="#"+String(H)+"#"+String(T);
          char msg[30];
          s.toCharArray(msg, 30);
          Serial.print("valori inviati: "); 
          Serial.println(msg);
          client.publish("mdb/valori_dht11",msg);
    }   
}

 

Scarica il progetto completo

Vai alla pagina dei downloads Categoria: Arduino ESP8266 IoT