IoT con WeMos D1 Mini usando Arduino IDE e Blynk

Durante le mie attività di formazione più volte mi è giunta la richiesta da persone non professioniste del settore elettronico o informatico, la realizzazione di progetti elettronici in grado di interagire via WiFi. Svolgere tale attività può richiedere competenze di livello più elevato che ovviamente tutti possono acquisire, ma per non aggiungere scoraggiamento nella fase iniziale di apprendimento ed invogliare sempre di più a sperimentare progetti sempre più complessi è forse bene partire da qualcosa di semplice che sono sicuro farà “esplodere” la vostra fantasia 🙂

Per questa breve introduzione utilizzerò: Arduino IDE, Blynk con scheda WeMos D1 Mini

Blynk

Avevo fatto una breve segnalazione tempo fa. Blynk è un’applicazione (per dirla in informatiche meglio parlare di freamework) che consente mediante dispositivi mobili (iOS e Android) utilizzando un sistema completamente grafico la realizzazione dei propri widget per comandare ad esempio l’azionamento via WiFi di dispositivi di automazione industriale o implementare progetti di domotica, ma anche di rilevare grandezze fisiche esterne e visualizzarle direttamente sul vostro dispositivo mobile.
Blynk può interagire con Arduino o Raspberry Pi se connessi ad una WiFi o a moltissimi dispositivi basati su ESP8266, modulo WiFi dotato di Input/Output General Purpose e processore ARM. Attualmente sono disponibili una grande quantità di board basate su ESP identificate tutti da un ID da ESP-01 a ESP-13 e la differenza tra una scheda e l’altra dipende dalla quantità di memoria disponibile, il numero di GPIO e il tipo di antenna WiFi.

Wemos D1 Mini

Per darvi un’idea di cosa è la Wemos D1 Mini si potrebbe fare la seguente analogia (non me ne vogliano i puristi mi serve solo per dare l’idea per chi incomincia), immaginate un Arduino micro dotato di una connessione WiFi ad un costo di non più di € 5 che potrà essere programmato in modo grafico con Blynk oppure attraverso l’IDE Arduino o ancora con NodeMCU (vedremo più avanti).
Wemos D1 Mini ospita un ESP-12F, dispone di 11 pin I/O digitali, 1 ingresso analogico, tutti i pin I/O gestiscono interrupt, pwm, I2C e ISP e tutti i pin I/O funzionano con una tensione di alimentazione di 3,3V e dispone di una memoria di 4MB.

01

02

Nell’immagine sopra riportata noterete che il nome usato sulla scheda è diverso da quello utilizzato nell’IDE di Arduino, fate riferimento ai numeri scritti in verde in fase di programmazione.

06

07

Come si evince dalle immagini sopra inserite la scheda è dotata di un connettore micro USB che vi permette di caricare gli sketch, ciò non accade per altre tipologie di schede che necessitano di un debugger per il caricamento di programmi.

On-line potete trovare su diversi store una serie di shield (per un elenco completo seguire il link) che possono esser impilati su questa piccolissima scheda.

03La scheda in genere viene venduta con diverse tipologie di pin header non saldati: maschio, femmina, femmina impilabile e ciò vi permette di adattarla ad ogni tipologia di circuito.

04

E’ presente un pulsante di reset

05

Sul pin analogico è possibile leggere tensioni fino a 3,2 V.

La conversione USB a UART viene realizzata dal chip CH340G (ben visibile nell’immagine sopra), presente su moltissimi cloni Arduino cinesi tra cui gli economicissimi Arduino nano. Gli utenti windows potranno procedere tranquillamente scaricando i driver dal seguente link su cui trovate anche i driver per MacOS X, però se avete l’ultima versione di MacOS X  Sierra  (10.12.x) utilizzate la procedura ben dettagliata a questo link. Sempre per gli utenti Mac, nel caso abbiate installato una precedente versione del driver seguite la procedura che trovate al seguente link.

Vedremo nei successivi passaggi l’utilizzo di WeMos D1 con l’Arduino IDE e con Blynk.

Usare WeMos D1 Mini con IDE Arduino

Per poter utilizzare WeMos D1 mini con l’Arduino mini trovate a questo link un tutorial che vi guida passo passo nell’installazione, ma ho replicato il procedimento mettendo in evidenza alcuni passi con immagini che chiariscono alcuni passaggi importanti.

Aprite l’IDE e selezionate “Preferences”

08

Individuate l’area “Additional Board Manager URLs” evidenziata in rosso nell’immagine che segue:

09

10

Inserite il link indicato:

http://arduino.esp8266.com/stable/package_esp8266com_index.json

Selezionate: Tools > Boards Manager…

11

Verrà mostrata la finestra corrispondente:

12

Nel campo di ricerca inserite: wemos

13

13b

Selezionate la riga trovata e procedete con l’installazione facendo click su “Install”

14

La fase di installazione necessita di qualche minuto, vedrete la barra di avanzamento al fondo della finestra:

15

Al termine comparirà l’indicazione: INSTALLED

16

Dal menù: Tools > Board selezionate: WeMos D1 R2 & mini

17

17b

Siamo pronti adesso per scrivere il nostro primo codice e pilotare da pagina web l’accensione e lo spegnimento di un LED, installando un WebServer sul WeMos D1 mini che risponderà alle nostre richieste. Tutte le informazioni per il controllo via WiFi le trovate partendo dal seguente link sul sito Arduino.cc e sull’ESP8266 Community Forum. Di seguito vi fornisco direttamente lo sketch definitivo, all’interno trovate con commenti la descrizione del funzionamento di ogni elemento, rimanderò ad una guida passo passo più avanti quando spiegherò il funzionamento dell’ESP8266 nei minimi dettagli, per ora l’obiettivo e introdurre all’uso semplice del WeMos D1 mini quindi per ora portate pazienza 🙂

Colleghiamo il catodo del LED al pin G (che identifica il ground) e l’anodo al pin D4 (precisazione… sappiamo che in serie al LED ci andrebbe una resistenza per limitare la corrente che lo attraversa e così bisogna fare, ma in questo caso per velocità di assemblaggio possiamo evitare… e poi come mi diceva un mio insegnante questi LED sono dei “muli” sopportano 🙂 )

18

/*
 * Prof. Michele Maffucci
 * 01.05.2017
 * accensione/spegnimento LED da pagina web
 * per maggiori informazioni:
 * https://www.arduino.cc/en/Reference/WiFi
 * https://github.com/esp8266
 */

#include <WiFiUdp.h>
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>

// La connessione di WeMos D1 mini al un network WiFi viene
// realizzata usando un personal encryption WEP e WPA2
// Per poter sapere a quale rete connettersi bisogna
// effettuare un broadcast dell'SSID (nome del network) 

// definizione di due array di caratteri
// in cui memorizzare nome della rete WiFi e password

const char ssid[] = "nome della rete";       // inserire l'ssid della rete
const char pass[] = "password della rete";   // password della rete

// Creazione di un server web in ascolto sulla porta 80
// attende contenuti (pagine html, immagini, css, ecc...)
WiFiServer server(80);

int pinLed = D4;                   // LED connesso tra pin D4 e ground

void setup() {
  Serial.begin(115200);           // inizializzazione Serial Monitor
  delay(10);

  pinMode(pinLed, OUTPUT);         
  digitalWrite(pinLed, LOW);      // LED inizialmente spento

  // Connessione alla rete WiFi
  
  Serial.println();
  Serial.println();
  Serial.println("------------- Avvio connessione ------------");
  Serial.print("Tentativo di connessione alla rete: ");
  Serial.println(ssid);

  /* 
   *  Viene impostata l'impostazione station (differente da AP o AP_STA)
   * La modalità STA consente all'ESP8266 di connettersi a una rete Wi-Fi
   * (ad esempio quella creata dal router wireless), mentre la modalità AP 
   * consente di creare una propria rete e di collegarsi
   * ad altri dispositivi (ad esempio il telefono).
   */
  
  WiFi.mode(WIFI_STA);

  /* 
   *  Inizializza le impostazioni di rete della libreria WiFi e fornisce lo stato corrente della rete,
   *  nel caso in esempio ha come parametri ha il nome della rete e la password.
   *  Restituisce come valori:
   *  
   *  WL_CONNECTED quando connesso al network
   *  WL_IDLE_STATUS quando non connesso al network, ma il dispositivo è alimentato
  */
  WiFi.begin(ssid, pass);

  /* 
   *  fino a quando lo non si è connessi alla WiFi
   *  compariranno a distanza di 250 ms dei puntini che
   *  evidenziano lo stato di avanzamento della connessione
  */  
  while (WiFi.status() != WL_CONNECTED) {
    delay(250);
    Serial.print(".");
  }

  // se connesso alla WiFi stampa sulla serial monitor
  // nome della rete e stato di connessione
  Serial.println("");
  Serial.print("Sei connesso ora alla rete: ");
  Serial.println(ssid);
  Serial.println("WiFi connessa");

  // Avvia il server
  server.begin();
  Serial.println("Server avviato");

  // Stampa l'indirizzo IP
  Serial.print("Usa questo URL : ");
  Serial.print("http://");
  Serial.print(WiFi.localIP()); // Restituisce i'IP della scheda
  Serial.println("/");
}

void loop() {

  // Verifca se il client e' connesso
  WiFiClient client = server.available();
  if (!client) {
    return;
  }

  // Aspetta fino a quando il client invia dei dati
  Serial.println("Nuovo client");
  while (!client.available()) {
    delay(1);
  }

  // Legge la prima richiesta
  
  /* 
   *  readStringUntil() legge i caratteri dal buffer seriale
   * all'interno di una stringa fino a quando non riceve il
   * carattere di terminazione in questo cas \r
   * oppure si verivica un time out
   */
   
  String request = client.readStringUntil('\r');
  Serial.println(request);
  client.flush();                               // flush() elimina il buffer una volta che
                                                // tutti i caratteri in uscita sono stati inviati.

  // Verifica quale richiesta e' stata fatta

  /*
   * Individua un carattere o una stringa all'interno di un'altra stringa (nell'esempio la strina è request).
   * Per impostazione predefinita, ricerche dall'inizio della stringa,
   * ma è possibile effettuare la ricerca partendo da un dato indice,
   * permettendo di individuare tutte le istanze del carattere o della stringa.
   * Se il valore restituito è -1 allora la stringa non è stata trovata.
   */

  int valore = LOW;
  if (request.indexOf("/LED=ON") != -1) {
    digitalWrite(pinLed, HIGH);
    valore = HIGH;
  }
  if (request.indexOf("/LED=OFF") != -1) {
    digitalWrite(pinLed, LOW);
    valore = LOW;
  }

  // Restituisce la risposta
  
  /*
   * La pagina web dovrà essere formattata con la sua intestazione html
   * e variando il messaggio che identifica lo stato del LED 
   */
   
  // intestazione pagina html
  client.println("HTTP/1.1 200 OK");
  client.println("Content-Type: text/html");
  client.println(""); //  non dimenticare questa linea
  client.println("<!DOCTYPE HTML>");
  client.println("<html>");

  // titolo della pagina
  client.println("<h2>Intefaccia di controllo LED mediante WeMos D1 Mini</h2>");

  // includiamo tutto il testo in un div in cui il font è impostato a 20 px
  // N.B. ricorda che per poter considerare le " come stringa e' necessario farle precedere da uno \
  client.print("<div style=\"font-size: 20px;\">");
  client.print("Il LED e': ");

  if (valore == HIGH) {
    // stampa ON di colore verde
    client.print("<strong style=\"color:green;\">ON</strong>");
  } else {
    // stampa OFF di colore rosso
    client.print("<strong style=\"color:red;\">OFF</strong>");
  }
  // stampa una riga separatrice
  client.println("<hr>");
  // lista puntata
  client.println("<ul>");
  client.println("<li>Fai click <a href=\"/LED=ON\">QUI</a> per portare ad ON il LED sul pin D4</li>");
  client.println("<li>Fai click <a href=\"/LED=OFF\">QUI</a> per portare ad OFF il LED sul pin D4</li>");
  client.println("</ul>");
  client.print("</div>");
  client.println("</html>");

// chiusura connessione
  delay(1);
  Serial.println("Client disconnesso");
  Serial.println("");
}

Questo è ciò che viene visualizzato sulla Serial Monitor all’avvio:

28

Copiare ed incollare l’indirizzo fornito sulla Serial Monitor in una pagina di un browser:

29

Il click sui link permette di accendere e spegnere il LED

30

Sulla Serial Monitor si potranno visualizzare le richieste inviate al WebServer:

31

Passiamo ora alla lettura di un sensore esterno e pubblichiamo il valore letto su una pagina web ogni volta che si ricarica la pagina web. Procediamo in modo analogo a quanto fatto precedentemente realizzando un Web Server che ci restituisce temperatura ed umidità rilevata da un sensore di temperatura e umidità DHT 11.

Nel caso non fosse disponibile installiamo la libreria DHT11 di Adafruit direttamente dall’IDE Arduino: Sketch > Manage Libraries…

43

44

Nel campo di ricerca inserite DHT11 e selezionate la prima voce che vi compare:

45

Procedete con l’installazione dell’ultima versione:

46

Al termine dell’installazione la libreria sarà disponibile tra l’elenco delle librerie installate nel vostro IDE

47

Variando il programma precedente con le informazioni che potete trovare nella cartella esempi della libreria per i sensori DHT che avete installato, lo sketch diventa:

/*
   Prof. Michele Maffucci
   01.05.2017
   rilevazione temperatura e umidità da pagina web
   per maggiori informazioni:
   https://www.arduino.cc/en/Reference/WiFi
   https://github.com/esp8266

   Per esempi sul DHT11 guardare gli esempi all'interno della libreria
*/

#include <WiFiUdp.h>
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include "DHT.h"

#define DHTTYPE DHT11   // DHT 11

// La connessione di WeMos D1 mini al un network WiFi viene
// realizzata usando un personal encryption WEP e WPA2
// Per poter sapere a quale rete connettersi bisogna
// effettuare un broadcast dell'SSID (nome del network)

// definizione di due array di caratteri
// in cui memorizzare nome della rete WiFi e password

const char ssid[] = "nome della rete";       // inserire l'ssid della rete
const char pass[] = "password della rete";   // password della rete

// Creazione di un server web in ascolto sulla porta 80
// attende contenuti (pagine html, immagini, css, ecc...)
WiFiServer server(80);

// Sensore DHT
const int pinDHT = D4;

// Inizializzazione del sensore DHT
DHT dht(pinDHT, DHTTYPE);

// Variabili temporanee
static char tempCelsius[7];
static char tempUmidita[7];

void setup() {
  Serial.begin(115200);
  delay(10);                // inizializzazione Serial Monitor
  dht.begin();              // inizializzazione del DHT


  // Connessione alla rete WiFi

  Serial.println();
  Serial.println();
  Serial.println("------------- Avvio connessione ------------");
  Serial.print("Tentativo di connessione alla rete: ");
  Serial.println(ssid);

  /*
      Viene impostata l'impostazione station (differente da AP o AP_STA)
     La modalità STA consente all'ESP8266 di connettersi a una rete Wi-Fi
     (ad esempio quella creata dal router wireless), mentre la modalità AP
     consente di creare una propria rete e di collegarsi
     ad altri dispositivi (ad esempio il telefono).
  */

  WiFi.mode(WIFI_STA);

  /*
      Inizializza le impostazioni di rete della libreria WiFi e fornisce lo stato corrente della rete,
      nel caso in esempio ha come parametri ha il nome della rete e la password.
      Restituisce come valori:

      WL_CONNECTED quando connesso al network
      WL_IDLE_STATUS quando non connesso al network, ma il dispositivo è alimentato
  */
  WiFi.begin(ssid, pass);

  /*
      fino a quando lo non si è connessi alla WiFi
      compariranno a distanza di 250 ms dei puntini che
      evidenziano lo stato di avanzamento della connessione
  */
  while (WiFi.status() != WL_CONNECTED) {
    delay(250);
    Serial.print(".");
  }

  // se connesso alla WiFi stampa sulla serial monitor
  // nome della rete e stato di connessione
  Serial.println("");
  Serial.print("Sei connesso ora alla rete: ");
  Serial.println(ssid);
  Serial.println("WiFi connessa");

  // Avvia il server
  server.begin();
  Serial.println("Server avviato");

  // Stampa l'indirizzo IP
  Serial.print("Usa questo URL : ");
  Serial.print("http://");
  Serial.print(WiFi.localIP()); // Restituisce i'IP della scheda
  Serial.println("/");
}

void loop() {

  // Verifca se il client e' connesso
  WiFiClient client = server.available();
  if (!client) {
    return;
  }

  // Aspetta fino a quando il client invia dei dati
  Serial.println("Nuovo client");
  while (!client.available()) {
    delay(1);
  }

  // Legge la prima richiesta

  /*
     readStringUntil() legge i caratteri dal buffer seriale
     all'interno di una stringa fino a quando non riceve il
     carattere di terminazione in questo cas \r
     oppure si verivica un time out
  */

  String request = client.readStringUntil('\r');
  Serial.println(request);
  client.flush();                               // flush() elimina il buffer una volta che
                                                // tutti i caratteri in uscita sono stati inviati.

  // La lettura da parte del sensore può richiedere anche più di 2 secondi

  // lettura dell'umidità
  float h = dht.readHumidity();

  // Lettura temperatura in gradi Celsius
  float t = dht.readTemperature();

  // Verifica se la lettura è riuscita altrimenti si ripete la rilevazione
  if (isnan(h) || isnan(t)) {
    Serial.println("Impossibile leggere i dati dal sensore DHT!");
    strcpy(tempCelsius, "Fallito");
    strcpy(tempUmidita, "Fallito");
  }
  else {
    // Calcola i valori di temperatura in Celsius e Umidità

    float hic = dht.computeHeatIndex(t, h, false);

    dtostrf(hic, 6, 2, tempCelsius);

    dtostrf(h, 6, 2, tempUmidita);
    
    Serial.print("Temperatura: ");
    Serial.print(t);
    Serial.print(" *C ");
    
    Serial.print("Umidita': ");
    Serial.print(h);
    Serial.println(" %\t");

  }

  // intestazione pagina html
  client.println("HTTP/1.1 200 OK");
  client.println("Content-Type: text/html");
  client.println(""); //  non dimenticare questa linea
  client.println("<!DOCTYPE HTML>");
  client.println("<html>");
  client.println("<body>");

  // titolo della pagina
  client.println("<h2>Sensore di Temperatura e Umidita' mediante WeMos D1 Mini e DHT11</h2>");

  // stampa una riga separatrice
  client.println("<hr>");

  // includiamo tutto il testo in un div in cui il font è impostato a 20 px
  // N.B. ricorda che per poter considerare le " come stringa e' necessario farle precedere da uno \
  client.println("<div style=\"font-size: 20px;\">");

  client.println("<ul>");
  client.print("<li>Temperature in Celsius: ");
  client.print(tempCelsius);
  client.println(" *C</li>");

  client.print("<li>Umidita': ");
  client.print(tempUmidita);
  client.println("%</li>");
  client.println("</ul>");
  client.println("</div>");
  client.println("</body>");
  client.println("</html>");

  // chiusura connessione
  delay(1);
  Serial.println("Client disconnesso");
  Serial.println("");
}

48

49

Nel caso volessimo che la lettura fosse automatica, ad esempio ogni 5 secondi è sufficiente aggiungere nell’intestazione della pagina html l’istruzione:

<head> <meta http-equiv=”refresh” content=”5″ /> </head>

/*
   Prof. Michele Maffucci
   01.05.2017
   rilevazione temperatura e umidità da pagina web
   per maggiori informazioni:
   https://www.arduino.cc/en/Reference/WiFi
   https://github.com/esp8266

   Per esempi sul DHT11 guardare gli esempi all'interno della libreria
*/

#include <WiFiUdp.h>
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include "DHT.h"

#define DHTTYPE DHT11   // DHT 11

// La connessione di WeMos D1 mini al un network WiFi viene
// realizzata usando un personal encryption WEP e WPA2
// Per poter sapere a quale rete connettersi bisogna
// effettuare un broadcast dell'SSID (nome del network)

// definizione di due array di caratteri
// in cui memorizzare nome della rete WiFi e password

const char ssid[] = "nome della rete";       // inserire l'ssid della rete
const char pass[] = "password della rete";   // password della rete

// Creazione di un server web in ascolto sulla porta 80
// attende contenuti (pagine html, immagini, css, ecc...)
WiFiServer server(80);

// Sensore DHT
const int pinDHT = D4;

// Inizializzazione del sensore DHT
DHT dht(pinDHT, DHTTYPE);

// Variabili temporanee
static char tempCelsius[7];
static char tempUmidita[7];

void setup() {
  Serial.begin(115200);
  delay(10);                // inizializzazione Serial Monitor
  dht.begin();              // inizializzazione del DHT


  // Connessione alla rete WiFi

  Serial.println();
  Serial.println();
  Serial.println("------------- Avvio connessione ------------");
  Serial.print("Tentativo di connessione alla rete: ");
  Serial.println(ssid);

  /*
      Viene impostata l'impostazione station (differente da AP o AP_STA)
     La modalità STA consente all'ESP8266 di connettersi a una rete Wi-Fi
     (ad esempio quella creata dal router wireless), mentre la modalità AP
     consente di creare una propria rete e di collegarsi
     ad altri dispositivi (ad esempio il telefono).
  */

  WiFi.mode(WIFI_STA);

  /*
      Inizializza le impostazioni di rete della libreria WiFi e fornisce lo stato corrente della rete,
      nel caso in esempio ha come parametri ha il nome della rete e la password.
      Restituisce come valori:

      WL_CONNECTED quando connesso al network
      WL_IDLE_STATUS quando non connesso al network, ma il dispositivo è alimentato
  */
  WiFi.begin(ssid, pass);

  /*
      fino a quando lo non si è connessi alla WiFi
      compariranno a distanza di 250 ms dei puntini che
      evidenziano lo stato di avanzamento della connessione
  */
  while (WiFi.status() != WL_CONNECTED) {
    delay(250);
    Serial.print(".");
  }

  // se connesso alla WiFi stampa sulla serial monitor
  // nome della rete e stato di connessione
  Serial.println("");
  Serial.print("Sei connesso ora alla rete: ");
  Serial.println(ssid);
  Serial.println("WiFi connessa");

  // Avvia il server
  server.begin();
  Serial.println("Server avviato");

  // Stampa l'indirizzo IP
  Serial.print("Usa questo URL : ");
  Serial.print("http://");
  Serial.print(WiFi.localIP()); // Restituisce i'IP della scheda
  Serial.println("/");
}

void loop() {

  // Verifca se il client e' connesso
  WiFiClient client = server.available();
  if (!client) {
    return;
  }

  // Aspetta fino a quando il client invia dei dati
  Serial.println("Nuovo client");
  while (!client.available()) {
    delay(1);
  }

  // Legge la prima richiesta

  /*
     readStringUntil() legge i caratteri dal buffer seriale
     all'interno di una stringa fino a quando non riceve il
     carattere di terminazione in questo cas \r
     oppure si verivica un time out
  */

  String request = client.readStringUntil('\r');
  Serial.println(request);
  client.flush();                               // flush() elimina il buffer una volta che
                                                // tutti i caratteri in uscita sono stati inviati.

  // La lettura da parte del sensore può richiedere anche più di 2 secondi

  // lettura dell'umidità
  float h = dht.readHumidity();

  // Lettura temperatura in gradi Celsius
  float t = dht.readTemperature();

  // Verifica se la lettura è riuscita altrimenti si ripete la rilevazione
  if (isnan(h) || isnan(t)) {
    Serial.println("Impossibile leggere i dati dal sensore DHT!");
    strcpy(tempCelsius, "Fallito");
    strcpy(tempUmidita, "Fallito");
  }
  else {
    // Calcola i valori di temperatura in Celsius e Umidità

    float hic = dht.computeHeatIndex(t, h, false);

    dtostrf(hic, 6, 2, tempCelsius);

    dtostrf(h, 6, 2, tempUmidita);

    Serial.print("Temperatura: ");
    Serial.print(t);
    Serial.print(" *C ");
    
    Serial.print("Umidita': ");
    Serial.print(h);
    Serial.println(" %\t");
  }

  // intestazione pagina html
  client.println("HTTP/1.1 200 OK");
  client.println("Content-Type: text/html");
  client.println(""); //  non dimenticare questa linea
  client.println("<!DOCTYPE HTMLh>");
  client.println("<htmlh>");
  
  // ricarica la pagina web ogni 5 secondi
  client.println("<headh> <meta http-equiv=\"refresh\" content=\"5\" /h> </headh>");
  client.println("<bodyh>");

  // titolo della pagina
  client.println("<h2h>Sensore di Temperatura e Umidita' mediante WeMos D1 Mini e DHT11</h2h>");

  // stampa una riga separatrice
  client.println("<hrh>");

  // includiamo tutto il testo in un div in cui il font è impostato a 20 px
  // N.B. ricorda che per poter considerare le " come stringa e' necessario farle precedere da uno \
  client.println("<div style=\"font-size: 20px;\"h>");

  client.println("<ulh>");
  client.print("<lih>Temperature in Celsius: ");
  client.print(tempCelsius);
  client.println(" *C</lih>");

  client.print("<lih>Umidita': ");
  client.print(tempUmidita);
  client.println("%</lih>");
  client.println("</ulh>");
  client.println("</divh>");
  client.println("</bodyh>");
  client.println("</htmlh>");

  // chiusura connessione
  delay(1);
  Serial.println("Client disconnesso");
  Serial.println("");
}

Usare WeMos D1 Mini con Blynk

Passiamo ora ad un utilizzo più semplice del WeMos D1 mini, quello che sfrutta l’ambiente di sviluppo di Blynk.

Per procedere con l’uso di Blynk il prerequisito è sempre l’installazione dei driver della scheda che abbiamo visto nella fase precedente.

Collegatevi al sito blynk.cc e scaricate l’App per il vostro dispositivo

Per poter creare le proprie applicazioni bisogna possedere un Token di autenticazione, che potrete ottenere all’atto della creazione della vostra applicazione.

20

  1. Prelevate l’App e creare un nuovo account

21

  1. Creare un nuovo progetto indicando il tipo di hardware utilizzato e il tipo di connessione, nel nostro caso selezionate WeMos D1 Mini e WiFi come tipo di connessione.

22

23

  1. Dopo che il progetto è stato creato, vi sarà inviato per posta elettronica il Token di autenticazione. Controllate la vostra casella di posta elettronica e cercate Auth Token.

Auth Token dovrà essere copiato ed incollato all’interno dello sketch che vedremo al passo 5

24

  1. installazione la libreria Blynk

Attenzione! L’installazione della libreria deve essere effettuata manualmente
Prelevate l’ultima versione dal seguente link

25

Scompattate il file, noterete che all’interno ci sono due cartelle e diversi file:

26

27

  • Le cartelle incluse nella cartella libraries devono essere spostate nella cartella libraries di Arduino.
  • L’intera cartella tools deve essere spostata nella cartella in cui vengono salvati tutti gli sketch.

Siamo pronti per creare la nostra prima App IoT sul nostro smartphone. Nel caso abbiate necessità di recuperare o spedirvi nuovamente Auth Token potete recuperarlo direttamente sul vostro cellulare facendo click sull’icona a forma di bullone, indicata nell’immagine copiate Auth Token:

32

33

Aprite l’IDE Arduino ed aprite lo sketch:

File > Examples > Blynk > Boards_WiFi > ESP8266_Standalone

34

  • Inserite l’Auth Token che avete ricevuto via e-mail nello sketch al posto di YourAuthToken.
  • Inserite il nome della vostra rete WiFi in YourNetworkName
  • Inserite la password della vostra rete WiFi in YourPassword
  • Effettuate l’upload dello sketch sul WeMos D1 Mini

35

Effettuate l’upload sulla scheda:

42

A questo punto realizziamo un App che permette di accendere e spegnere il LED.

Aprite l’App Blynk sul vostro smartphone, un click sulla pagina vuota (quella puntinata su sfondo nero) si aprirà un pannello sulla destra del vostro monitor da cui selezionate “Button”:

36

Per comodità riposizionare il pulsante nel centro del monitor (tap prolungato e trascinate).

Un tap sul pulsante aprirà il pannello di configurazione, click su PIN:

37

Selezionate il pin a cui è collegato il LED e poiché vogliamo usarlo come interruttore e non come pulsante spostate lo slider da PUSH a SWITCH:

38

39

Per avviare l’App click sul pulsante play come indicato nell’immagine che segue:

40

A questo punto premendo il bottone sarete in grado di accendere e spegnere il LED

41

Vediamo, come realizzare qualcosa di simile a quanto fatto nei precedenti passi per la rilevazione della temperatura e dell’umidità mediante un sensore DHT11, però questa volta riduciamo la quantità di codice ed utilizziamo Blynk.

Come avete potuto notare con Blynk potete controllare direttamente i pin I/O digitali e analogici e come avete notato non è stata scritta una linea di codice per far lampeggiare il LED, però per realizzare qualcosa di più interessante è indispensabile utilizzare un po’ di codice, meno rispetto agli esempi precedenti, però necessario per ottenere delle app estremamente dinamiche ed interattive.

In Blynk, per poter inviare qualsiasi dato dal microcontrollore all’applicazione Blynk e viceversa, vengono utilizzati dei pin virtuali, in questo modo tutto ciò che viene connesso al microcontrollore sarà in grado di comunicare con Blynk.
Con i Virtual Pins sarà possibile inviare dati all’App, l’elaborazione sarà fatta dal microcontrollore e poi inviata allo smartphone, dovete immaginare i Virtual Pins come a canali di trasmissione che non hanno nessuna rappresentazione fisica.

Sarà quindi possibile attivare funzioni particolari, convertire valori, leggere dispositivi I2C, controllare motori DC e servomotori, realizzare grafici di dati letti dai sensori connessi alla scheda ecc…

Per comprendere meglio l’uso dei pin virtuali di seguito mostro come realizzare una semplice App che permette di visualizzare su smartphone temperatura, umidità e realizzare il grafico delle due grandezze.

Lo sketch che andremo a realizzare avrà come base la struttura che potete prendere come copia da:

File > Examples > Blynk > Boards_WiFi > ESP8266_Standalone

34

All’interno dello sketch andremo ad aggiungere alcune linee di codice che permetteranno di visualizzare ad intervalli fissati i valori di temperatura ed umidità e rappresentare nel tempo queste due grandezze.

Utilizzate il seguente sketch:

/*
   Prof. Michele Maffucci
   02.05.2017
   rilevazione temperatura e umidità mediante Blynk
   per maggiori informazioni:
   http://www.blynk.cc
   https://www.arduino.cc/en/Reference/WiFi
   https://github.com/esp8266
   http://playground.arduino.cc/Code/SimpleTimer

   Per esempi sul DHT11 guardare gli esempi all'interno della libreria
*/

// Commenta questa riga per disabilitare la stampa sulla
// Serial Monitor e risparmiare spazio di memoria
#define BLYNK_PRINT Serial

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

// libreria che consente di eseguire azioni ripetute
// con intervallo di tempo fissato tra un'azione e l'altra   
#include <SimpleTimer.h>

// libreria per il sensore DHT
#include "DHT.h"

#define DHTTYPE DHT11   // DHT 11

// pin a cui è connesso il sensore DHT
const int pinDHT = D4;

// Inizializzazione del sensore DHT
DHT dht(pinDHT, DHTTYPE);


// Stringa di autenticazione
char auth[] = "stringa di autenticazione - auth token";     // Stringa Blynk di autenticazione

const char ssid[] = "nome della rete";       // inserire l'ssid della rete
const char pass[] = "password della rete";   // password della rete

// definiamo un oggetto timer di tipo SimpleTimer
SimpleTimer timer;

void setup()
{
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);                       // Connessione alla WiFi e al servizio Blynk

  timer.setInterval(5000L, inviaMisura);               // ogni 5 secondi viene eseguita la funzione inviaMisura
  
}

// funzione che invia temperatura ed umidità

void inviaMisura()
{
  float h = dht.readHumidity();           // legge l'umidità dal sensore e la salva nella variabile h
  float t = dht.readTemperature();        // legge la temperatura dal sensore e la memorizza nella variabile t
  
  if (isnan(h) or isnan(t)) {             // verifica se si possono ottenere letture dal sensore
    // non può leggere il sensore
  }
  else {
  Blynk.virtualWrite(1, t);              // invia al pin virtuale Blynk 1 il valore della temperatura
  Blynk.virtualWrite(2, h);              // invia al pin virtuale Blynk 3 il valore dell'umidità

  Blynk.virtualWrite(3, t);             // pin virtuale Blynk 10 per l'app grafico della temperatura 
  Blynk.virtualWrite(4, h);             // pin virtuale Blynk 11 per l'app grafico della umidità
  
  }  
}

void loop()
{
  Blynk.run(); // esegue Blynk
  timer.run(); // esegue timer
}

 

Nello sketch è stata utilizzata la libreria SimpleTimer.h che permette di eseguire ad intervalli fissati la funzione inviaMisura() che invia temperatura ed umidità allo smartphone.

All’interno della funzione inviaMisura() sono stati definiti 4 Virtual Pins: 2 per l’invio della misura di temperatura e umidità e due per i grafici che permettono la visualizzazione nel tempo di temperatura ed umidità.

Create una nuova App, assegnatele un nome, impostate il tipo di device utilizzato e la tipologia di connessione:

50

 

51

Inviatevi via e-mail l’Auth Token, dovrete poi copiarlo all’interno dello sketch.

Selezionate due oggetti: “Value Display” e due oggetti: “Graph”:

52

Configurate così come indicato nelle immagini che seguono:

53

54

Tornate all’app e fate click su play:

55

Il risultato sarà il seguente:

56

Bene! a questo punto non posso che dirvi:

Buona sperimentazione a tutti… e benvenuti nel fantastico monto dello IoT 🙂

3 pensieri su “IoT con WeMos D1 Mini usando Arduino IDE e Blynk

  1. Renzo

    Egregio Prof. Maffucci,
    le sue spiegazioni sono sempre chiare, dettagliate, precise e soprattutto i suoi sktches funzionano sempre.
    Ho usato quello con DHT11 e Blynk su Arduino 1.6.5, e sullo smartphone ricevo i dati a distanza correttamente.
    Ho provato ad inserire uno sketck con BMP180, che da solo compilandolo con Arduino 1.8.3 funziona, su Arduino 1.6.5 mi da ripetutamente questo errore: “size_t TwoWire::write(const uint8_t*, size_t)’:
    C:\Documents and Settings\mio\Desktop\arduino-1.6.5-r5\portable\sketchbook\libraries\Wire\Wire.cpp:195:32: error: ‘twi_transmit’ was not declared in this scope
    twi_transmit(data, quantity);”
    C’è una soluzione? Grazie
    Renzo Giurini

    Rispondi

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.