Centralina humidity temperatura suolo – lo sketch

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.

centralina umidità e temperatura montata

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

Permanent link to this article: https://www.mauroalfieri.it/elettronica/centralina-humidity-temperatura-suolo-lo-sketch.html

11 pings

Skip to comment form

  1. […] « Centalina humidity temperatura suolo – lo sketch […]

  2. […] « Centralina humidity temperatura suolo – lo sketch […]

  3. […] centralina humidity temperatura suolo – lo sketch […]

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.