Arduino ENC28J60 DHT22 dati online su file json

Oggi leggeremo i dati dal DHT22 ed invieremo tutto online in un file JSON tramite Enc28j60 con tanto di pagina PHP per consultare successivamente i dati caricati.

Mentre in un articolo precedente, cioè questo abbiamo visto come collegare la Enc28j60 alla nostra scheda Arduino per creare un ambiente server in modo da poter accendere e spegnere un led da internet o da rete lan.

arduino_enc28j60_dht22_json
Differentemente dall’articolo precedente questa volta la nostra scheda Arduino fungerà da client tramite la Enc28j60 , tutto quello che dovrà fare è inviare tramite il metodo GET una query string contenente le variabili con i valori recuperati dai sensori collegati ad essa ed in fine gestire la risposta del server con una semplice stampa a video.

Per salvare i dati inviati al nostro sito web tramite Arduino, useremo un file Json senza scomodare per il momento i database.
JSON e acronimo di JavaScript Object Notation si tratta di un formato abbastanza semplice per lo scambio di dati tra client-server.

Vediamo subito un esempio di file Json:

[
{
"sensor":"temperature",
"value":"23.5",
"date":"26 Feb 2014",
"time":"14:33:23"
},
 
{ 
"sensor":"humidity",
"value":"43.0",
"date":"26 Feb 2014",
"time":"14:33:23"
}
]

tutto questo sarà gestito in PHP tramite apposite funzioni:

json_encode() e json_decode()

Il tutto sarà composto da 3 pagine più lo sketch per Arduino:

– data.json:
In questo file non dobbiamo fare assolutamente niente, basta creare un semplice file di testo vuoto e rinominarlo appunto data.json.

– write_json.php:
In questo file ci occuperemo di andare a prelevare il contenuto del file Json decodificarlo con la funzione json_decode() ottenere così l’array dei dati prelevati, ed aggiungere in coda i dati ricevuti da Arduino, successivamente daremo in pasto l’array alla funzione json_encode(), a questo punto non ci rimane altro che salvare i dati all’interno del nostro file data.json.

– read_json.php
In quest’ultimo file invece dobbiamo prelevare il contenuto del file data.json decodificarlo con la funzione json_decode() e stamparlo a video.

e qui abbiamo i file:
ricordo che il file data.json è solo un file vuoto con estension .json

enc_dht.ino

#include <EtherCard.h>
#include "DHT.h"

DHT dht;
static byte mac[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06};
static byte ip[] = {192, 168, 1, 7};
byte Ethernet::buffer[700];
#define ENC28J60_CS 10
char website[] PROGMEM = ""; // www.TUO_SITO_WEB.it
char buffer[70];
unsigned long time_last = 0;
boolean flag;
byte interval = 30; // seconds - intervello di tempo tra un invio di dati ed il successivo verso il server

static void response_callback (byte status, word off, word len)
{
  Serial.println();
  Serial.println( (char *) Ethernet::buffer + off);
  Serial.println();
}

void setup ()
{
  Serial.begin(9600);

  Serial.print("Verifica Enc28j60 ... ");

  if ( ether.begin( sizeof Ethernet::buffer, mac, ENC28J60_CS) )Serial.println("\tsuccess");
  else Serial.println("\tfailed");

  Serial.print("Setting IP ... ");

  if ( ether.dhcpSetup() ) {
    Serial.println("\t\tsuccess");
  }
  else {
    if ( ether.staticSetup(ip) ) Serial.println("\t\tsuccess");
    else Serial.println("\t\tfailed");
  }

  Serial.print("Verifica sito web ... ");

  if ( ether.dnsLookup( website ) ) Serial.println("\tsuccess");
  else Serial.println("\tfailed");

  dht.setup(3); // pin 3

  Serial.println();
  Serial.print("Setup eseguito in :");
  Serial.print(millis() / 1000);
  Serial.println("s");
  Serial.println();
  Serial.println();
}


void loop()
{
  ether.packetLoop(ether.packetReceive());

  if (millis() / 1000 > time_last) {
    if ( (time_last = millis() / 1000) % interval == 0 ) {
      flag = true;
    }
  }

  if (flag) {
    flag = false;
    float temperature = dht.getTemperature();
    char s_temperature[5]; // 5 caratteri (5 char) perché il nostro numero decimale (float) è formato da: [ un intero a due cifre, un punto, un decimale, ed in fine si aggiungerà il terminatore di stringa (cioè \0) ]
    dtostrf(temperature, 4, 1, s_temperature);
    float humidity = dht.getHumidity();
    char s_humidity[5]; // 5 caratteri (5 char) perché il nostro numero decimale (float) è formato da: [ un intero a due cifre, un punto, un decimale, ed in fine si aggiungerà il terminatore di stringa (cioè \0) ]
    dtostrf(humidity, 4, 1, s_humidity);

    sprintf(buffer, "sensor[]=temperature&value[]=%s&sensor[]=humidity&value[]=%s", s_temperature, s_humidity);
    ether.browseUrl(PSTR("/_TUO_PERCORSO_/write_json.php?"), buffer, website, response_callback);
  }
}

write_json.php

<?php

( empty($_REQUEST) || empty($_REQUEST) ) ? exit("Non posso procedere al salvataggio, mancano i dati!") : true ;

$file = "data.json";
$json = file_get_contents($file);
$array = json_decode($json, true);

if (is_array($_REQUEST)) {
  for ($i=0; $i < count($_REQUEST); $i++) {
    $array[] = array(
      'sensor'=> $_REQUEST[$i],
      'value'=> $_REQUEST[$i],
      'date'=> date('d M Y', time()),
      'time'=> date('H:i:s', time())
    );
  }
} 
else {
  $array[] = array(
    'sensor'=> $_REQUEST,
    'value'=> $_REQUEST,
    'date'=> date('d M Y', time()),
    'time'=> date('H:i:s', time())
  );
}

$json = json_encode($array);

file_put_contents($file, $json, LOCK_EX) ? print "- Salvataggio dati riuscito! " : print "- Salvataggio dati fallito!";

?>

read_json.php

<?php

$file = "data.json"; 
$json = file_get_contents($file);
$json = utf8_encode($json);
$array = json_decode($json, true);

?>

<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>Arduino - Enc28j60 - DHT22 | PHP -Json</title>
  
  <style type="text/css"> 
  @import url(http://fonts.googleapis.com/css?family=Quattrocento+Sans:700,400);
  @import url(http://fonts.googleapis.com/css?family=Dosis:400,700);
  
  * { margin: 0 auto; padding: 0; }
  body { margin: 0; padding: 0; text-align: center; }
  h1 { font-family: "Quattrocento Sans"; font-size: 30pt; margin: 35px 0 }
  table { border-collapse: separate; }
  
  th {
    background: #ffc000;
    color: #444;
    padding: 5px;
    text-align: center;
    font-size: 15pt;
    font-family: "Quattrocento Sans";
    padding: 5px 25px;
  }
  
  tr:nth-child(even) { background: #C0C0C0; }
  tr:nth-child(odd) { background: #D0D0D0; }
  
  td {
    padding:3px;
    text-align: center;
    color: #000;
    font-size: 12pt;
    font-family: "Dosis", "Quattrocento Sans";
  }
  </style>
</head>
<body>
  
  <h1>Arduino - Enc28j60 - DHT22 & PHP - Json</h1>
  
  <?php
  
  if ( empty($array) ) { 
    print "
    <h2>Il file è vuoto, in attesa di ricevere i primi dati ... </h2>
    </body>
    </html>";
    
    exit(); 
  }
  
  ?>
  
  <table> 
    <tr>
      <th>Sensor</th><th>Value</th><th>Date</th><th>Time</th>
    </tr>
    
    <?php
    
    foreach ($array as $vett) { 
      print "<tr>";
      foreach ($vett as $key => $value) {
        print "<td>" . $value . "</td>";
      }
      
      print "</tr>";
      
    }
    
    ?>
    
  </table> 
</body>
</html>

e qui un video del codice in funzione: