Centralina meteo arduino yùn – lo sketch

Se hai letto il precedente articolo sulla centralina meteo arduino yùn sarai curioso di conoscere lo sketch per realizzare la tua centralina.

centralina meteo arduino yun core

La realizzazione della centralina meteo arduino necessita sia dello sketch sia del codice che interpreta i dati e crea i grafici.

Queste due parti non sono legate direttamente ma passano per un file “DATI.LOG” scritto dallo sketch sulla SD Card e letto dal webserver.

Io per l’interpretazione dei dati e la loro manipolazione al fine di realizzare i grafici ho deciso di usare il linguaggio php, a me noto e facile da usare, non escludo che tu possa usare un altro linguaggio, supportato dall’arduino yùn, per il tuo progetto.

Lo sketch della centralina meteo arduino yùn

#include <FileIO.h>
#include <Wire.h>
#include <dht11.h>
#include <SHT1x.h>

#define DHT11_PIN 10
#define SHT_dataPin 12
#define SHT_clockPin 11

dht11 DHT;
SHT1x sht1x(SHT_dataPin, SHT_clockPin);

int  DHT_h;
int  DHT_t;
char SHT_t[10];
char SHT_h[10];

String cur = "";
String old = "";

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

  Serial.print("BMP085 Init");
  Serial.println("Filesystem datalogger\n");
}

void loop () {
  readSensor();
  int chk = DHT.read(DHT11_PIN);

  String dataString;
  dataString += getTimeStamp();
  dataString += " ";
  dataString += String( DHT_h );
  dataString += " ";
  dataString += String( DHT_t );
  dataString += " ";
  dataString += String( SHT_h );
  dataString += " ";
  dataString += String( SHT_t );

  cur = getInterval("+%M");
  Serial.print("Old: ");
  Serial.print(old);
  Serial.print(" New: ");
  Serial.println(cur);

  if ( cur != old ) {
    old = cur;
    File dataFile = FileSystem.open("/mnt/sd/arduino/www/dati.log", FILE_APPEND);
    if (dataFile) {
      dataFile.println(dataString);
      dataFile.close();
      Serial.println(dataString);
    } else {
      Serial.println("error opening dati.log");
    }
  } 
  delay(30000);
}

String getTimeStamp() {
  String result;
  Process time;
  time.begin("date");
  time.addParameter("+%d/%m/%Y %T");
  time.run();
  while(time.available()>0) {
    char c = time.read();
    if(c != '\n') result += c;
  }

  return result;
}

String getInterval( char* string ) {
  String result;
  Process time;
  time.begin("date");
  time.addParameter(string);
  time.run();
  while(time.available()>0) {
    char c = time.read();
    if(c != '\n') result += c;
  }

  return result;
}

void readSensor() {
   int chk = DHT.read(DHT11_PIN);
   if ( chk != DHTLIB_OK ) {
     switch (chk){
         case DHTLIB_OK:
           DHT_h=0;
           DHT_t=0;
           break;
         case DHTLIB_ERROR_CHECKSUM: 
           DHT_h=997;
           DHT_t=997;
           break;
         case DHTLIB_ERROR_TIMEOUT: 
           DHT_h=998;
           DHT_t=998;
           break;
         default: 
           DHT_h=999;
           DHT_t=999;
           break;
      }
    }
    DHT_h=DHT.humidity;
    DHT_t=DHT.temperature;
    dtostrf(sht1x.readHumidity(), 5, 2, SHT_h);
    dtostrf(sht1x.readTemperatureC(), 5, 2, SHT_t);
}

lo sketch non è molto differente dalla centralina meteo pubblicata qualche settimana fa ( leggi articolo ), per cui mi limito a descrivere le parti differenti lasciandoti il gusto di leggere tutto lo sketch .

#include <FileIO.h>
#include <Wire.h>
#include <dht11.h>
#include <SHT1x.h>

#define DHT11_PIN 10
#define SHT_dataPin 12
#define SHT_clockPin 11

La linea 001: trovi la prima differenza in quanto per la centralina meteo arduino yùn devi includere la libreria FileIO.h che similmente alla libreria SDFat.h ti permette di scrivere sulla SD card, in questo caso la SD è quella letta anche dal sistema Linino;

linee 006-008: definisci i pin a cui hai collegato il sensore DHT11 e il sensore SHT1x, avrai notato che non ho inserito le righe relative all’inizializzione del sensore BMP085 come nell’altra centralina, voglio concentrarmi sulla raccolta e visualizzazione dei soli dati di temperatura ed umidità;

void setup() {
  Bridge.begin();
  Serial.begin(9600);
  FileSystem.begin();
   
  Serial.print("BMP085 Init");
  Serial.println("Filesystem datalogger\n");
}

la linea 022: inizializza l’oggetto Bridge che permetterà allo sketch presente sull’arduino yùn di comunicare con la parte di sistema operativo;

linea 024: inizializza l’oggetto FileSystem che permette di scrivere sulla SD Card.

void loop () {
  readSensor();
  int chk = DHT.read(DHT11_PIN);
   
  String dataString;
  dataString += getTimeStamp();
  dataString += " ";
  dataString += String( DHT_h );
  dataString += " ";
  dataString += String( DHT_t );
  dataString += " ";
  dataString += String( SHT_h );
  dataString += " ";
  dataString += String( SHT_t );
 
  cur = getInterval("+%M");
  Serial.print("Old: ");
  Serial.print(old);
  Serial.print(" New: ");
  Serial.println(cur);
   
  if ( cur != old ) {
    old = cur;
    File dataFile = FileSystem.open("/mnt/sd/arduino/www/dati.log", FILE_APPEND);
    if (dataFile) {
      dataFile.println(dataString);
      dataFile.close();
      Serial.println(dataString);
    } else {
      Serial.println("error opening dati.log");
    }
  } 
  delay(30000);
}

la linea 031: richiama la funzione readSensor() che è identica all’omonima funzione definita nello sketch della  centralina humidity temperatura suolo e riportata in questo sketch per la centralina meteo arduino yùn senza la parte relativa al sensore BMP085 che ho deciso di omettere in questo progetto.

linea 034: definisci una variabile dataString di tipo String che userai per costruire la stringa con i dati letti dai sensori.

linee 035-043: costruisci la stringa da memorizzare sulla SD Card della centralina meteo arduino yùn contenente i valori letti dai sensori e prima di tutti la data e l’ora in cui ha eseguito la lettura. Per recuperare la data e l’ora dal webserver puoi usare la funzione getTimeStamp() definita alle linee 066-078;

linea 045: usando la funzione getInterval(“+%M”) memorizzi il valore restituito nella variabile cur che ti servirà per un confronto alla linea 051;

linea 051: confronta il valore di cur con il valore di old e se sono differenti esegui quanto indicato nella righe successive. In pratica la funzione getInterval(“+%M”) recupera il minuto corrente in modo da evitare la memorizzazione di dati troppo frequente, in questo modo scandisci che sulla SD Card i valori devono essere scritti ogni minuto;

linea 052: memorizza nella variabile old il valore di cur ossia il minuto corrente;

linee 053-058: scrivi sulla SD Card il valore di dataString;

linea 063: aspetta un tempo di 30 secondi tra un ciclo fi loop() ed il successivo, in questo modo sai che la scrittura del valore letto dai sensori avverrà ogni minuto attendendo al massimo una pausa di 30 secondi tra un loop ed il successivo.

String getTimeStamp() {
  String result;
  Process time;
  time.begin("date");
  time.addParameter("+%d/%m/%Y %T");
  time.run();
  while(time.available()>0) {
    char c = time.read();
    if(c != '\n') result += c;
  }
 
  return result;
}

la linea 066: definisci la funzione getTimeStamp() il cui scopo è parlare con la parte di sistema operativo per recuperare i dati relativi alla data e all’orario e restituirli in forma String alla loop();

linee 067-068: definisci la variabile result e l’oggetto  time che userai per recuperare informazioni da Linino e restituirle alla loop();

linea 069: inizializza la chiamata dell’oggetto time indicando che intendi usare il comando di sistema date che in Linux, e quindi in Linino, restituisce la data corrente;

linea 070: aggiungi i parametri da passare al comando date per ottenere esattamente i valori formattati come ti servono per la memorizzazione sulla centralina meteo arduino yùn;

linea 071: lancia il comando usando il metodo run dell’oggetto time;

linee 072-075: leggendo i valori ritornati dalla chiamata eseguita alla linea 071 concatena nella variabile result il risultato;

linea 077: restituisci il valore result alla funzione che ha invocato la getTimeStamp();

String getInterval( char* string ) {
  String result;
  Process time;
  time.begin("date");
  time.addParameter(string);
  time.run();
  while(time.available()>0) {
    char c = time.read();
    if(c != '\n') result += c;
  }
 
  return result;
}

linee 080-092: la funzione getInterval() è identica alla funzione getTimeStamp() a meno del fatto che accetta come parametro la stringa dei valori che vuoi passare alla funzione date;

Nel prossimo articolo analizzerai il codice php caricato sulla centralina meteo arduino yùn per interpretare il file dati.log e relizzare i grafici sul web.

Buona costruzione !!!

Prima di inserire un commento, per favore, leggi il regolamento

Permanent link to this article: http://www.mauroalfieri.it/elettronica/centralina-meteo-arduino-yun-lo-sketch.html

6 comments

Skip to comment form

    • Samuele on 11 Febbraio 2015 at 12:10
    • Reply

    Ciao, bellissimo progetto! Sto progettando anch’io un sistema simile. Pensavo di collegare una sonda di temperatura ad arduino yun, e scrivere uno sketch che acquisisca i dati della temperatura ogni 5 secondi e li inserisca all’interno di un file data.log contenuto nella schedina SD. Poi con una pagina in Php gestita da arduino yun sempre all’interno della schedina SD mi creo i grafici. Mi sorge però un dubbio. Supponiamo che la pagina Php stia leggendo o elaborando i dati contenuti nel file data.log e proprio in quel momento lo sketch debba caricare il dato della temperatura all’interno dello stesso file data.log, che cosa succede? Va in conflitto o crea qualche errore? Non mi è molto chiaro questo aspetto, mentre uso arduino yun per visualizzare la pagina php lo sketch continua a funzionare regolarmente?

    1. Ciao Samuele,
      praticamente stai realizzando lo stesso progetto con un solo sensore, giusto?
      La coerenza del dato è data dal tipo di accesso al file.
      Solo lo sketch scrive il file, la pagina php si limita a leggerlo senza modificarlo.
      Lo sketch sulla Yun è indipendente dalla componente Linux.

        • Samuele on 11 Febbraio 2015 at 16:03
        • Reply

        Grazie, esatto è lo stesso progetto ma con un solo sensore di temperatura. Quindi io posso tranquillamente far si che lo sketch scriva i dati raccolti dal sensore di temperatura nel file data.log e in contemporanea avere la pagina php che legge i dati contenuti file data.log per fare i grafici senza temere alcun conflitto giusto?

        1. Giusto Samuele.

        • Samuele on 11 Febbraio 2015 at 17:29
        • Reply

        Per spiegarmi meglio: supponiamo che io avvio lo script php il quale inizia a leggere i dati contenuti nel file data.log per poter tracciare i grafici. Proprio in quel momento, mentre lo script php mi sta ancora leggendo i valori contenuti in data.log, dallo sketch in esecuzione sulla yun parte la scrittura di un nuovo valore sullo stesso file (data.log) che in quel momento è ancora in fase di lettura dal php. In questo caso limite cosa succede? La scheda riesce a gestire la contemporanea lettura/scrittura del file data.log?

        1. Ciao Samuele,
          per chiarirti ogni dubbio ti consiglio di leggerti come Linino gestisce i filesystem in lettura e troverai molte risposte.

Lascia un commento

Your email address will not be published.

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