Se hai letto il precedente articolo sulla centralina meteo arduino yùn sarai curioso di conoscere lo sketch per realizzare la tua centralina.
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 !!!
6 commenti
Vai al modulo dei commenti
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?
Autore
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.
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?
Autore
Giusto Samuele.
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?
Autore
Ciao Samuele,
per chiarirti ogni dubbio ti consiglio di leggerti come Linino gestisce i filesystem in lettura e troverai molte risposte.