RTC shield DS1307: impostare data e ora

In un articolo di alcuni mesi fa hai letto come impostare la data e l’ora son l’RTC shield ds1307 ed arduino dall’IDE di arduino e visualizzarla su un display LCD 16×2

rtc shield ds1307 imposta ora

In questi mesi alcuni appassionati mi hanno contattato per chiedermi consigli su come far evolvere quel progetto potendo, ad esempio, impostare l’ora con dei pulsanti.

Nei commenti dell’articolo Tutorial rtc shield con ds1307 stesso puoi leggere alcune delle richieste di aiuto.

Avevo promesso di mettermici nuovamente a lavoro ed ecco il risultato.

In questo articolo troverai i collegamenti e lo sketch per gestire l’RTC shield ds1307 con arduino per impostare l’ora senza dover ricaricare lo sketch ogni volta.

I collegamenti dei pulsanti all’rtc shield ds1307

Mi soffermo sui collegamenti dei soli pulsanti in quanto tutti gli altri collegamenti restano invariati rispetto al precedente articolo, vedi link sopra.

rtc shield ds1307 button setting date and time

Usi solo 3 pulsanti:

  • il primo, connesso ad A0, come SET ossia per tutte le operazioni di impostazione: entrare in modalità setting e avanzare tra i menu del settaggio;
  • il secondo, connesso ad A2, come MENO per decrementare i valori da impostare;
  • il terzo, connesso ad A1, come PIU per incrementare i valori da impostare;

ciascun pulsante ha il terminale connesso ad arduino collegato ad una resistenza da 330ohm verso massa ( GND ) e l’altro terminale del pulsante al positivo ( +5v ) di arduino.

Questo tipo di collegamento lo hai già visto in tanti altri tutorial su questo blog, e ti consente di essere certo che senza la pressione del pulsante il valore letto sull’ingresso analogico di arduino sia inferiore a 1000 ed alla pressione del pulsante il valore letto sia superiore a 1000 ( sarà 1023 )

Lo sketch per settare data e ora con l’rtc shield ds1307

Lo sketch necessario ad impostare la data e l’ora con i pulsanti ha una base comune a quello mostrato nell’articolo precedente sull’RTC shield ds1307 che non ti racconterò per soffermarmi sulle sole linee nuove:

/*
 * RTC & LCD
 *
 * Autore: Mauro Alfieri
 * Tw: @mauroalfieri
 *
 * Web: https://www.mauroalfieri.it
 */

#include <Wire.h>
#include <RTClib.h>
#include <LiquidCrystal.h>

#define BACKLIGHT 2
#define CONTRAST  3

#define SET       A0
#define PIU       A1
#define MENO      A2

char buffer[10];
unsigned long time=0;
unsigned long timeSet=0;
int  setModeTime=2000;

RTC_DS1307 RTC;
LiquidCrystal lcd(12, 11, 7, 6, 5, 4);

void setup () {
    pinMode( BACKLIGHT, OUTPUT );
    pinMode( CONTRAST, OUTPUT );
    digitalWrite( BACKLIGHT, HIGH );
    analogWrite( CONTRAST, 40 );

    Wire.begin();
    RTC.begin();
    lcd.begin(16, 2);

    if (! RTC.isrunning()) {
      Serial.println("RTC is NOT running!");
      RTC.adjust(DateTime(__DATE__, __TIME__));
    }

    pinMode( SET, INPUT );
    pinMode( PIU, INPUT );
    pinMode( MENO, INPUT );
}

void loop () {

    if ( analogRead( SET ) < 1000) { time = millis(); }

    DateTime now = RTC.now();
    lcd.clear();

    sprintf(buffer,  "%02d/%02d/%d", now.day(), now.month(), now.year());
    lcd.setCursor(0,0);
    lcd.print( buffer );

    char buffer[10] = "";

    sprintf(buffer,  "%02d:%02d:%02d", now.hour(), now.minute(), now.second());
    lcd.setCursor(0,1);
    lcd.print( buffer );

    if (time > 0 && setModeTime < (millis() - time) ) { setMode( now ); }

    delay(1000);
}

void setMode( DateTime now ) {
    boolean setMode = 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(buffer,  "%s: %02d", "Giorno", _day);
    delay( 1000 );
    timeSet = millis();

    while ( setMode ) {
      if ( analogRead(SET) > 1000 || analogRead(PIU) > 1000 || analogRead(MENO) > 1000 ) { timeSet = millis(); }

      lcd.setCursor(0,0);

      // Set Day
      if ( setModeLevel == 0 ) {
        if ( analogRead(PIU) > 1000 && _day < 31) { _day++; }
        if ( analogRead(MENO) > 1000 && _day > 1) { _day--; }

        sprintf(buffer,  "%s: %02d", "Giorno", _day);
      }
      // Set Month
      if ( setModeLevel == 1 ) {
        if ( analogRead(PIU) > 1000 && _month < 12) { _month++; }
        if ( analogRead(MENO) > 1000 && _month > 1) { _month--; }

        sprintf(buffer,  "%s: %02d", "Mese", _month);
      }
      // Set Year
      if ( setModeLevel == 2 ) {
        if ( analogRead(PIU) > 1000 && _year < 9999) { _year++; }
        if ( analogRead(MENO) > 1000 && _year > 1900) { _year--; }

        sprintf(buffer,  "%s: %02d", "Anno", _year);
      }
      // Set Hour
      if ( setModeLevel == 3 ) {
        if ( analogRead(PIU) > 1000 && _hour < 24) { _hour++; }
        if ( analogRead(MENO) > 1000 && _hour > 1) { _hour--; }

        sprintf(buffer,  "%s: %02d", "Ora", _hour);
      }
      // Set Minute
      if ( setModeLevel == 4 ) {
        if ( analogRead(PIU) > 1000 && _min < 60) { _min++; }
        if ( analogRead(MENO) > 1000 && _min > 1) { _min--; }

        sprintf(buffer,  "%s: %02d", "Minuti", _min);
      }
      // Set Second
      if ( setModeLevel == 5 ) {
        if ( analogRead(PIU) > 1000 && _sec < 60) { _sec++; }
        if ( analogRead(MENO) > 1000 && _sec > 0) { _sec--; }

        sprintf(buffer,  "%s: %02d", "Secondi", _sec);
      }

      lcd.print( buffer );
      if ( analogRead(SET) > 1000 ) { lcd.clear(); setModeLevel++;  }
      if ( setModeLevel > 5 ) { setModeLevel=0; }

      if (timeSet > 0 && (setModeTime*2) < (millis() - timeSet) ) {
         RTC.adjust(DateTime(_year, _month, _day, _hour, _min, _sec));
         setMode = false;
      }
      delay(200);
    }
}

avrai subito individuato una nuova funzione: setMode, ma andiamo con ordine, alle linee 17-19: definisci i tre pulsanti e i relativi pin analogici a cui sono connessi;

linee 22-23: definisci due variabili di tipo unsigned long in cui memorizzerai dei tempi che in seguito ti serviranno;

linea 24: definisci la variabile setModeTime il cui valore indica il tempo di attesa per entrare o uscire dalla modalità di impostazione della data e dell’ora;

linee 44-46: definisci la modalità in cui utilizzerai i pin A0-A2 nello sketch;

linea 51: controlla che NON sia stato premuto ilpulsante SET se questo avviene imposta time uguale a millis() a cosa server? il valore di millis() si incrementa ad ogni ciclo di loop() dal momanto in cui lo sketch viene caricato o arduino viene resettato, in pratica stai comunicando di aggiornare il valore di time fino a che non venga premuto il pulsante SET;

linea 66: valuta se time sia maggiore di 0 e allo stesso tempo confronta il valore dell’operazione ( millis() – time ) con setModeTime in pratica siccome time si aggiorna ad ogni ciclo di loop a meno che non sia stato premuto il pulsante SET la differenza tra millis() e time restituisce sempre un valore prossimo allo 0 e quindi sempre maggiore di setModeTime; quando premi e mantieni premuto SET il valore di time non si aggiorna e la differenza cresce fino a superare il valore di confronto ( setModeTime ) in questo momento lo sketch comprende che vuoi impostare la data e l’ora e richiama la funzione setMode( now ) passandole l’oggetto di tipo DateTime chiamato now.

linea 72: imposta una variabile di tipo booleano che utilizzerai per rimanere in modalità di impostazione data e ora;

linea 73: imposta una variabile di tipo integer in cui memorizzerai a quale menu di impostazione sei arrivato;

linee 75-80: definisci delle variabili di tipo integer in ciascuna delle quali memorizzi il relativo valore attuale per giorno, mese, anno, ora, minuti e secondi;

linee 82-83: cancella ogni messaggio sul display e posiziona il cursore al punto 0,0 ( prima riga e prima colonna );

linea 84: definisci il contenuto della variabile buffer componendolo con il testo “Giorno:” e valore del giorno;

linee 85-86: attendi un secondo e imposta il valore del secondo temporizzatore timeSet identico a millis(), ti servirà per capire quanto tempo trascorre tra un’operazione e la successiva e poter uscire dalla modalità di impostazione data e ora;

linea 88: inizia un ciclo di tipo while fino a che il valore do setMode non passa da true a false;

linea 89: alla pressione di uno qualsiasi dei 3 pulsanti resetta il valore di setTime di fatto rimanendo nella modalità di impostazione, questo significa che se non premi alcun pulsante per un tempo definito, vedrai dopo come, esci dalla modalità di impostazione data ed ora;

linee 94-99: sei nel menu che imposta il giorno, il valore di setModeLevel è 0 e ad ogni pressione del pulsante PIU incrementi la variabile _day fino a 31, mentre alla pressione del pulsante MENO decrementi la medesima variabile fino a 1. La linea 98 prepara il buffer per scrivere sul display il valore impostato;

linee 101-134: esegui le stesse operazioni appena viste per ciascuno dei valori di cui è composta la data e l’ora;

linea 136: scrivi sul display il valore del buffer ad ogni ciclo di while;

linea 137: è qui che fai la magia di spostamento tra i menu, ad ogni pressione del pulsante SET incrementi il valore di setModeLevel dopo aver ripulito il display per prepararlo alla visualizzazione del menu successivo;

linea 138: controlla che il valore di setModeLevel non superi il 5, menu massimo, in tal caso lo reimposti a 0 per ricominciare dal primo menu;

linea 140: con questa condizione verifichi che il tempo trascorso dalla pressione di uno dei pulsanti sia superiore al doppio di quello impostato per entrare nella modalità di impostazione, infatti alla linea 89 hai visto che appena premi un pulsante il valore di timeSet si reimposta uguale a millis() e quindi la loro differenza non supererà mai il valore di setModeTime*2 se smetti di premere i pulsanti il valore di timeSet non si resetta e la differenza cresce fino a superare il valore di confronto, in questo caso lo sketch esegue le linee sottostanti;

linea 141: imposta i valori di data ed ora correnti e li salva sul rtc shield ds1307;

linea 142: assegna false a setMode indicando allo sketch che vuoi uscire dalla modalità di impostazione data e ora sull’rtc shield ds1307.

Per chiarirti il funzionamento ti ho preparato anche un video mentre testavo lo sketch:

Buon impostazione della data e dell’ora !!!

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

Permanent link to this article: https://www.mauroalfieri.it/elettronica/rtc-shield-ds1307-impostare-data-e-ora.html

159 pings

Skip to comment form

  1. […] RTC shield DS1307: impostare data e ora […]

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.