Grafico della temperatura con Arduino e PHP

Come potete leggere dal titolo oggi vedremo come realizzare una piccola “Stazione Meteo“, misurando la temperatura di una stanza, memorizzando i dati sul DB e visualizzando il tutto su un grafico accessibile da remoto.
Per comprendere meglio il funzionamento di questo sistema ho realizzato uno schema (Fig.1) dove si possono distinguere fondamentalmente due fasi:

  1. Salvataggio dei dati
  2. Recupero dei dati
Fig1. Schema del progetto “grafico della temperatura con Arduino e PHP”

Nella prima fase Arduino ogni 5 minuti legge il valore della temperatura, grazie al sensore DHT22, e invia una richiesta HTTP GET alla pagina addTemperature.php (presente sul server Altervista), che si occupa del salvataggio della temperatura sul db MySQL.
Nella seconda fase per il recupero dei dati ci basta aprire la pagina grafico.php, questa si occuperà di richiamare getTemperature.php la quale preleverà i dati dal db e li restituirà permettendo così di visualizzare il grafico della temperatura.

Per realizzare questo progetto ci occorre:

  • Arduino UNO o simili
  • Arduino Ethernet Shield
  • Servizio di hosting dove caricare la pagina web (es: http://it.altervista.org/)
  • Sensore di temperatura DHT22
  • Libreria del sensore DHT22 (DHTlib)
  • Libreria Chart per realizzare il grafico (Chart.js)

DHT22 – Sensore di temperatura

Prima di iniziare a parlare del codice di arduino vediamo come collegare il sensore di temperatura alla scheda e alcune sue caratteristiche.

Il DHT22 si presenta con 4 pin dei quali uno non è usato (NC-Not Connected) come si vede in Fig.2, inoltre questo sensore presenta al suo interno un chip che fa la conversione del segnale da analogico a digitale ottenendo così un treno di impulsi (bit), che sono poi correttamente letti dalla libreria DHTlib scaricabile qui.

Fig.2 DHT22-PinOut

Un corretto collegamento del DHT22 ad Arduino è visibile in Fig.3 dove si nota la presenza di una resistenza di pull-up da 10KΩ necessaria per stabilizzare l’uscita del sensore.

Fig.3 Collegamento DHT22 ad Arduino

Ora che sappiamo come collegarlo ad Arduino possiamo dare un breve sguardo alle sue caratteristiche:

  • Sensore digitale di umidità e temperatura DHT22 (AM2302)
  • Range misura umidità: 0-99,9 %RH
  • Accuratezza: ±2 %RH
  • Range misura temperatura: -40 +80°C
  • Accuratezza: ±0,5°C

Dalle caratteristiche si evince che questo sensore permette la lettura sia della temperatura che dell’umidità,in questo caso per rendere il progetto più semplice si utilizzerà solo il valore della temperatura.
Il datasheet del sensore lo potere scaricare qui.

Sketch Arduino

#include <SPI.h>
#include <Ethernet.h>
#include <dht.h>

// Create an array of bytes to specify the mac address
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
// ip address "http://it.altervista.org/"
//byte server[] = { 136, 243, 88, 137};
String server = "tuodominio.altervista.org";
// Create an array of bytes to specify the IP address Arduino
IPAddress ip(192, 168, 1, 100);
// Create a client object
EthernetClient client;
// Create a dht object
dht DHT;
// Define pin 9 for sensor DHT22
#define DHT22_PIN 9
// strURL contains the request HTTP GET
String strURL = "";
// query string GET
String data = "";
// save temperature value
double temperature = 0;

void setup()
{
  // Initialize the shield with the mac and ip
  Ethernet.begin(mac, ip);
  Serial.begin(115200);
  Serial.println("connecting...");
  Serial.println("DHT TEST PROGRAM ");
  Serial.print("LIBRARY VERSION: ");
  Serial.println(DHT_LIB_VERSION);
}

void loop()
{
  // Read Data and manage errors 
  Serial.print("DHT11, \t");
  int chk = DHT.read22(DHT22_PIN);
  switch (chk)
  {
    case DHTLIB_OK:
      Serial.print("OK,\t");
      break;
    case DHTLIB_ERROR_CHECKSUM:
      Serial.print("Checksum error,\t");
      break;
    case DHTLIB_ERROR_TIMEOUT:
      Serial.print("Time out error,\t");
      break;
    case DHTLIB_ERROR_CONNECT:
      Serial.print("Connect error,\t");
      break;
    case DHTLIB_ERROR_ACK_L:
      Serial.print("Ack Low error,\t");
      break;
    case DHTLIB_ERROR_ACK_H:
      Serial.print("Ack High error,\t");
      break;
    default:
      Serial.print("Unknown error,\t");
      break;
  }
  // Display Data
  temperature = DHT.temperature;
  Serial.println(temperature, 1);
  // Create the query string GET
  data = "temperature=";
  data += temperature;

  // if you get a connection, report back via serial:
  if (client.connect(server, 80)) {
    Serial.println("connected");
    // Make a HTTP GET request:
    strURL = "GET /ArduinoTemperature/controller/addTemperature.php?";
    strURL += data;
    strURL += " HTTP/1.1";
    client.println(strURL);
    client.println("Host: tuodominio.altervista.org");
    client.println("User-Agent: Arduino/1.0");
    client.println("Connection: close");
    client.println();
    // Wait 1 ms so that the response arrivals the browser of the client
    delay(1);
    while (client.connected()) {
    // Check if there are bytes available for reading
    if (client.available()) {
      char c = client.read();
      Serial.print(c);
      }
    }
    // Close connection
    client.stop();
  }
  else {
    // if you didn't get a connection to the server:
    Serial.println("connection failed");
  }
  // Wait 5 min for new measure
  delay(300000);
}

Il codice da caricare su arduino si compone principalmente da due parti:

  1. Lettura dei dati del sensore DHT22
  2. Invio della richiesta HTTP GET

La prima parte può essere ridotta a due semplici comandi:

int chk = DHT.read22(DHT22_PIN);

temperature = DHT.temperature;

Il primo utilizzato per leggere i dati del sensore e verificare eventuali errori della lettura: OK, Checksum error, Time out error, Connect error, Ack Low error, Ack High error, Unknown error.
Il secondo necessario per salvare il valore della temperatura e poterlo così utilizzare per costruire la richiesta HTTP GET.

La seconda parte invece si occupa di costruire la richiesta ed inviarla al server, da notare però che Altervista come la maggior parte degli host gratuiti utilizzano Virtual Server ossia non esiste un rapporto 1:1 tra il sito web  e l’indirizzo ip.
Altervista infatti per capire a quale pagina vogliamo accedere utilizza il fqdn (Fully Qualified Domain Name) presente nella chiamata, indirizzando cosi la richiesta al server virtuale corretto.
Tutto questo si traduce nel utilizzare come indirizzo ip del server quello di Altervista (136.243.88.137) e specificare nella richiesta il nome dell’host.

// ip address "http://it.altervista.org/"
byte server[] = { 136, 243, 88, 137};

client.println("Host: tuodominio.altervista.org");

Codice PHP

Per realizzare il codice PHP si è utilizzata la programmazione ad oggetti, e per la connessione al DB si è sfruttata la potenzialità delle PDO.
PDO (PHP Data Object) non è altro che una classe contenente diversi metodi e proprietà che permettono di garantire un accesso sicuro ad un database. Uno dei punti di forza di questa classe è la portabilità, infatti è possibile cambiare tipologia di database (es: da MySQL a PostgreSQL) cambiando semplicemente qualche keyword, senza riscrivere completamente lo script.
Per maggiori info http://phpro.org/tutorials/Introduction-to-PHP-PDO.html.

Iniziamo con il vedere come sono strutturate le cartelle del progetto (Fig.4).

Fig.4 Struttura cartelle del progetto PHP

Senza entrare nel dettaglio di tutti i file, trovate comunque i commenti all’interno, notiamo che il progetto è strutturato secondo il pattern MVC (Model-View-Controller):

  • View: visualizza i dati contenuti nel “model” e si occupa dell’interazione con gli utenti.
  • Controller: riceve i comandi dell’utente (in genere attraverso il view) e li attua inviando le richieste al model.
  • Model: fornisce i metodi per accedere ai dati utili all’applicazione, ossia in questo progetto esegue le query di insert e select sul db.

A queste cartelle si aggiungono anche shared e js, la prima contenente le classi utilizzate da DBManager:

  • Logger.php: utilizzata per salvare su file log.csv eventuali errori.
  • PDO_Connector.php: utilizzata per la connessione al db.
  • Temperature_Config.php: usata per definire host, name, username e password del db.

 mentre nella seconda è presente la libreria javascript Chart.js utilizzata per creare il grafico.

I file principali del progetto sono quelli presenti in controller, che sfruttando la classe DBManager permettono il salvataggio (addTemperature.php) e la lettura (getTemperature.php) dei valori della temperatura, e la pagina grafico.php che si occupa di realizzare il grafico.

Il grafico è realizzato grazie la libreria Chart.js che vuole come input due array uno per identificare i valori dell’asse x (labels) e uno per i valori dell’asse y (datasets).
Per maggiori informazioni su come utilizzare questa libreria potete controllare il link diretto http://www.chartjs.org/ oppure utilizzare questa guida http://www.html.it/articoli/chart-js-creare-grafici-interattivi/.

Il risultato finale della pagina grafico.php è visibile nella Fig.5.

Fig.5 Grafico della temperatura

Tutto il progetto lo potete scaricare cliccando sull’icona qui sotto.

Download
Download