Probabilmente hai già letto il primo articolo sulla Centralina humidity temperatura suolo è un progetto complesso che ho deciso di descrivere in più articoli per dedicare il giusto tempo ad ognuno.
Nella prima parte hai letto come è nata la centalina humidity temperatura suolo, quali sensori puoi utilizzare e come montarli sulla datalogger shield.
In questo articolo inizierai a comprendere lo sketch e la descrizione linea per linea per capire come modificarlo.
Lo sketch della centralina humidity temperatura suolo
/* * centralina humidity temperatura suolo con Arduino * * @author: Alfieri Mauro * Tw: @mauroalfieri * Web: www.mauroalfieri.it */ #include <Wire.h> #include "RTClib.h" #include <SdFat.h> #include <dht11.h> #include <SHT1x.h> #include <Adafruit_Sensor.h> #include <Adafruit_BMP085_U.h> #include <LiquidCrystal.h> #define CS 10 #define DHT11_PIN 15 #define SHT_dataPin 2 #define SHT_clockPin 3 #define BLAKLIGHT 16 #define BUTTON A0 int setModeTime=2000; int setViewTime=2000; unsigned long time=0; unsigned long timeSet=0; int SELECT[] = {720,760}; int LEFT[] = {480,520}; int RIGTH[] = {0,20}; int UP[] = {120,160}; int DOWN[] = {300,350}; RTC_DS1307 RTC; dht11 DHT; SHT1x sht1x(SHT_dataPin, SHT_clockPin); LiquidCrystal lcd(8,9,4,5,6,7); char buffer[50]; char lcdBuffer[16]; int DHT_h; int DHT_t; char BMP_p[10]; char SHT_t[10]; char SHT_h[10]; int current; //File myFile; SdFat sd; SdFile myFile; Adafruit_BMP085_Unified bmp = Adafruit_BMP085_Unified(10085); void setup () { Serial.begin(9600); // Serial.print("Initializing SD card..."); pinMode( CS,OUTPUT ); pinMode( BUTTON,INPUT ); pinMode( BLAKLIGHT,OUTPUT ); blacklightOn(); lcd.begin(16, 2); lcd.setCursor(0,0); lcd.print("Mandorleto v1.0"); lcd.setCursor(0,1); lcd.print("mauroalfieri.it"); delay( 3000 ); lcd.clear(); lcd.setCursor(0,0); lcd.print("Init SD Card..."); lcd.setCursor(0,1); //if (!SD.begin(CS)) { if (!sd.begin(CS, SPI_HALF_SPEED)) { sd.initErrorHalt(); // Serial.println("initialization failed!"); lcd.print("... Failed "); while(1); } // Serial.println("initialization done."); lcd.print("... Ready "); delay( 2000 ); lcd.clear(); Wire.begin(); RTC.begin(); RTC.sqw(0); //0 Led off - 1 Freq 1Hz - 2 Freq 4096kHz - 3 Freq 8192kHz - 4 Freq 32768kHz lcd.setCursor(0,0); lcd.print("Init BMP085 ..."); lcd.setCursor(0,1); delay( 200 ); if(!bmp.begin()) { Serial.print("BMP085 Failed"); lcd.print("... Failed "); while(1); } lcd.print("... Ready "); delay( 2000 ); lcd.clear(); blacklightOff(); } void loop () { if ( ctrlButton( analogRead( BUTTON ) ) == 0 || ctrlButton( analogRead( BUTTON ) ) > 1 ) { time = millis(); } DateTime now = RTC.now(); if (time > 0 && setModeTime < (millis() - time) ) { blacklightOn(); now = setMode( now ); lcd.clear(); } if (( now.minute() == 00 || now.minute() == 15 || now.minute() == 30 || now.minute() == 45 ) && (now.minute() != current)) { blacklightOn(); current=now.minute(); saveData( now ); lcd.clear(); } if ( ctrlButton( analogRead( BUTTON ) ) > 1 ) { blacklightOn(); viewSensor(); lcd.clear(); } sprintf(lcdBuffer, "%02d/%02d/%04d", now.day(), now.month(), now.year() ); lcd.setCursor(0,0); lcd.print(lcdBuffer); sprintf(lcdBuffer, "%02d:%02d:%02d", now.hour(), now.minute(), now.second() ); lcd.setCursor(0,1); lcd.print(lcdBuffer); delay( 1000 ); blacklightOff(); } void blacklightOn() { digitalWrite( BLAKLIGHT,HIGH ); } void blacklightOff() { digitalWrite( BLAKLIGHT,LOW ); } DateTime setMode( DateTime now ) { boolean setModeVal = true; int setModeLevel = 0; int _day = now.day(); int _month = now.month(); int _year = now.year(); int _hour = now.hour(); int _min = now.minute(); int _sec = now.second(); lcd.clear(); lcd.setCursor(0,0); sprintf(lcdBuffer, "%s: %02d", "Giorno", _day); delay( 1000 ); timeSet = millis(); while ( setModeVal ) { //if ( ctrlButton( analogRead( BUTTON ) ) == 1 || ctrlButton( analogRead( BUTTON ) ) == 2 || ctrlButton( analogRead( BUTTON ) ) == 3 ) { timeSet = millis(); } if ( ctrlButton( analogRead( BUTTON ) ) >= 1 ) { timeSet = millis(); } lcd.setCursor(0,0); // Set Day if ( setModeLevel == 0 ) { if ( ctrlButton( analogRead( BUTTON ) ) == 3 && _day < 31) { _day++; } if ( ctrlButton( analogRead( BUTTON ) ) == 2 && _day > 1) { _day--; } sprintf(buffer, "%s: %02d", "Giorno", _day); } // Set Month if ( setModeLevel == 1 ) { if ( ctrlButton( analogRead( BUTTON ) ) == 3 && _month < 12) { _month++; } if ( ctrlButton( analogRead( BUTTON ) ) == 2 && _month > 1) { _month--; } sprintf(buffer, "%s: %02d", "Mese", _month); } // Set Year if ( setModeLevel == 2 ) { if ( ctrlButton( analogRead( BUTTON ) ) == 3 && _year < 9999) { _year++; } if ( ctrlButton( analogRead( BUTTON ) ) == 2 && _year > 1900) { _year--; } sprintf(buffer, "%s: %02d", "Anno", _year); } // Set Hour if ( setModeLevel == 3 ) { if ( ctrlButton( analogRead( BUTTON ) ) == 3 && _hour < 24) { _hour++; } if ( ctrlButton( analogRead( BUTTON ) ) == 2 && _hour > 1) { _hour--; } sprintf(buffer, "%s: %02d", "Ora", _hour); } // Set Minute if ( setModeLevel == 4 ) { if ( ctrlButton( analogRead( BUTTON ) ) == 3 && _min < 60) { _min++; } if ( ctrlButton( analogRead( BUTTON ) ) == 2 && _min > 1) { _min--; } sprintf(buffer, "%s: %02d", "Minuti", _min); } // Set Second if ( setModeLevel == 5 ) { if ( ctrlButton( analogRead( BUTTON ) ) == 3 && _sec < 60) { _sec++; } if ( ctrlButton( analogRead( BUTTON ) ) == 2 && _sec > 0) { _sec--; } sprintf(buffer, "%s: %02d", "Secondi", _sec); } lcd.print( buffer ); if ( ctrlButton( analogRead( BUTTON ) ) == 4 && setModeLevel > 0) { lcd.clear(); setModeLevel--; } if ( ctrlButton( analogRead( BUTTON ) ) == 5 && setModeLevel < 5 ) { lcd.clear(); setModeLevel++; } // if ( setModeLevel > 5 ) { setModeLevel=0; } if ((timeSet > 0 && (setModeTime*2) < (millis() - timeSet)) || ( ctrlButton( analogRead( BUTTON ) ) == 1) ) { RTC.adjust(DateTime(_year, _month, _day, _hour, _min, _sec)); setModeVal = false; } delay(200); } return RTC.now(); } void readSensor() { int chk = DHT.read(DHT11_PIN); if ( chk != DHTLIB_OK ) { lcd.clear(); lcd.setCursor(0,0); lcd.print("DHT11 (Aria)"); lcd.setCursor(0,1); switch (chk){ case DHTLIB_OK: lcd.print("SUCCESS"); break; case DHTLIB_ERROR_CHECKSUM: lcd.print("Checksum error"); break; case DHTLIB_ERROR_TIMEOUT: lcd.print("Time out error"); break; default: lcd.print("Unknown error"); break; } delay( setViewTime ); } DHT_h=DHT.humidity; DHT_t=DHT.temperature; // ----------------------------------------------------------------------- sensors_event_t event; bmp.getEvent(&event); if (event.pressure) { dtostrf(event.pressure, 5, 2, BMP_p); } // ----------------------------------------------------------------------- dtostrf(sht1x.readHumidity(), 5, 2, SHT_h); dtostrf(sht1x.readTemperatureC(), 5, 2, SHT_t); } void viewSensor() { lcd.clear(); readSensor(); lcd.clear(); lcd.setCursor(0,0); lcd.print("DHT11 (Aria)"); lcd.setCursor(0,1); sprintf(lcdBuffer, "%s %02d", "Humidty", DHT_h); lcd.print(lcdBuffer); delay( setViewTime ); lcd.clear(); lcd.setCursor(0,0); lcd.print("DHT11 (Aria)"); lcd.setCursor(0,1); sprintf(lcdBuffer, "%s %02d", "Temp.", DHT_t); lcd.print(lcdBuffer); delay( setViewTime ); lcd.clear(); lcd.setCursor(0,0); lcd.print("BMP085 Pressione"); lcd.setCursor(0,1); sprintf(lcdBuffer, "%s %s", "Pressione", BMP_p); lcd.print(lcdBuffer); delay( setViewTime ); lcd.clear(); lcd.setCursor(0,0); lcd.print("SHT (Suolo)"); lcd.setCursor(0,1); sprintf(lcdBuffer, "%s %s", "Humidity", SHT_h); lcd.print(lcdBuffer); delay( setViewTime ); lcd.clear(); lcd.setCursor(0,0); lcd.print("SHT (Suolo)"); lcd.setCursor(0,1); sprintf(lcdBuffer, "%s %s", "Temp.", SHT_t); lcd.print(lcdBuffer); delay( setViewTime ); lcd.clear(); } void saveData( DateTime now ) { readSensor(); sprintf(buffer, "%02d/%02d/%d %02d:%02d:%02d %02d %02d %s %s %s", now.day(), now.month(), now.year(), now.hour(), now.minute(), now.second(), DHT_h, DHT_t, BMP_p, SHT_h, SHT_t ); lcd.clear(); lcd.setCursor(0,0); lcd.print("Salvataggio dati"); if (myFile.open("dati.log", O_RDWR | O_CREAT | O_AT_END)) { myFile.println(buffer); myFile.close(); lcd.setCursor(0,1); lcd.print("SD Write Success"); } else { sd.errorHalt("opening dati.log for write failed"); lcd.setCursor(0,1); lcd.print("SD Write Error"); } delay(1000); } int ctrlButton( int button ) { if ( SELECT[0] <= button && button <= SELECT[1] ) { return 1; } if ( LEFT[0] <= button && button <= LEFT[1] ) { return 2; } if ( RIGTH[0] <= button && button <= RIGTH[1] ) { return 3; } if ( UP[0] <= button && button <= UP[1] ) { return 4; } if ( DOWN[0] <= button && button <= DOWN[1] ) { return 5; } return 0; }
come vedi lo sketch non è semplicissimo, iniziamo dalle prime linee:
linee 009-016: includi tutte le librerie necessarie alla lettura dei dati dai sensori ed a scrivere sulla SD card;
linee 018-022: definisci le costanti dei pin a cui sono collegati i sensori;
linea 024: definisci la costante a cui sono collegati i pulsanti della Keypad LCD;
linee 026-027: definisci le variabili in cui imposti i tempi per la modalità di impostazioni della data e dell’ora ( setModeTime ) e il tempo di attesa della visualizzazione ( setViewTime );
linee 028-029: definisci le variabili in cui memorizzerai i valori di tempo trascorsi, vedrai nelle linee successive a cosa servono;
linee 031-035: definisci 5 array di due valori ciascuno, ogni coppia rappresenta un range, primo=valore minimo, secondo=valore massimo, da confrontare con il valore letto sul pin A0 per capire quale pulsante è stato premuto;
linee 037-040: inizializza la classe RTC, DHT, SHT1x e Lcd;
linee 041-042: definisci due buffer in cui memorizzerai messaggi da visualizzare sul display LCD o la linea da scrivere sulla SD Card;
linee 044-048: definisci le variabili di tipo integer e char in cui memorizzerai i valori letti sui 3 sensori;
linea 50: definisci una variabile di tipo integer in cui memorizzerai il valore del minuto corrente, vedrai nelle righe successive il suo utilizzo;
linee 053-055: inizializza l’oggetto sd per scrivere sulla card e l’oggetto bmp per leggere il sensore BMP085;
nella funzione setup() trovi molte parti dedicate all’inizializzazione dei pin ed alla gestione del display LCD per cui ti invito a leggere gli articoli specifici, le parti importanti per questo progetto sono:
if (!sd.begin(CS, SPI_HALF_SPEED)) { sd.initErrorHalt(); // Serial.println("initialization failed!"); lcd.print("... Failed "); while(1); }
linea 80: controlla che sia possibile inizializzare la SD card, se fallisce l’inizializzazione della SD Card esegui le istruzioni successive;
linea 81: leggi eventuali errori;
linea 83: scrivi sul display LCD della centralina humidity temperatura suolo la frase: “… Failed “;
linea 84: inizia un ciclo infinito, in quanto 1 non permette al while di fermarsi, che non fa nulla, serve solo a fermare il programma a questa linea;
if(!bmp.begin()) { Serial.print("BMP085 Failed"); lcd.print("... Failed "); while(1); }
linea 103: tenta di inizializzare la comunicazione con il sensore BMP085 della centalina humidity temperatura suolo ;
linea 104: in caso di fallimento ottenuto alla linea 103 scrive sul monitor Seriale la frase “BMP085 Failed”;
linea 105: scrivi sul display LCD la frase “… Failed ”
linea 106: inizia un ciclo infinito come descritto alla linea 84;
blacklightOff();
linea 112: spegni la retro illuminazione del display LCD per risparmiare la batteria con cui alimenti la centralina humidity temperatura suolo;
In un prossimo articolo descriverò la funzione loop() e a seguire tutte le funzioni che sono definite nel progetto.
Buona sperimentazione !!!
Prima di inserire un commento, per favore, leggi il regolamento
11 pings
Skip to comment form
[…] « Centalina humidity temperatura suolo – lo sketch […]
[…] « Centralina humidity temperatura suolo – lo sketch […]
[…] centralina humidity temperatura suolo – lo sketch […]