Orologio con DS1307
Questo progetto prevede la realizzazione di un orologio/datario, con la possibilità di impostare data e ora tramite 3 pulsanti (SET, +, -).
Il materiale occorrente per questo progetto è:
- Modulo DS1307 (RTC Real time Clock)
- Display LCD 16X2 tipo Displaytech 162B
- 3 pulsanti
- 3 resistenze da 10Kohm 1/4w
- 1 potenziometro da 10Kohm lineare
- Arduino UNO
Descrizione dell'esperimento:
Vogliamo che Arduino mostri data e ora, ma dobbiamo avere anche la possibilità di impostarle correttamente, perché riprogrammare ogni volta Arduino non è proprio il massimo della comodità.
Quindi è stato previsto che normalmente Arduino visualizzi sul display la data sulla prima riga e l'ora sulla seconda riga del display. Alla pressione del tasto SET entrerà nella fase di settaggio della data e ora.
Più precisamente:
Con la pressione del tasto SET entreremo nell'impostazione dell'ora, con i tasti + e - incrementeremo o decrementeremo l'ora attuale. Con una nuova pressione del tasto SET andremo ad impostare i minuti, un'altra pressione per l'anno, poi il mese e il giorno.
Alla fine si effettuerà il salvataggio delle impostazioni.
Per realizzare lo sketch, è necessario scaricare e installare nella cartella delle librerie di arduino, la libreria RTClib che potete trovare a questo indirizzo:
Nota: Per il momento esistono alcuni "bug" per quanto riguarda il settaggio dei giorni del mese (di default il programma pensa che siano di 31 giorni anche se è febbraio....)
Lo sketch:
#include <Wire.h>
#include <RTClib.h>
#include <LiquidCrystal.h>
// inizializza la libreria con i Pin LCD
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
RTC_DS1307 RTC;
int P1=6;
int P2=7;
int P3=8;
int oraagg;
int minagg;
int annoagg;
int meseagg;
int dayagg;
int menu =0;
void setup()
{
// Quante colonne e righe ha il display:
lcd.begin(16, 2);
lcd.clear();
// Inizializzazione dei pulsanti
pinMode(P1,INPUT);
pinMode(P2,INPUT);
pinMode(P3,INPUT);
//inizializzo la libreria
Serial.begin(9600);
Wire.begin();
RTC.begin();
//RTC.sqw(1);
if (! RTC.isrunning()) {
Serial.println("RTC is NOT running!");
// settiamo la data e l'ora al momento della compilazione
RTC.adjust(DateTime(__DATE__, __TIME__));
}
// di default il display visualizzerà data e ora
int menu=0;
}
void loop()
{
// verifichiamo se viene premuto il pulsante SET e incrementiamo l'indice del menu
if(digitalRead(P1))
{
menu=menu+1;
}
// a quale subroutine dobbiamo andare?
if (menu==0)
{
DisplayDateTime();
delay (1000);
}
if (menu==1)
{
DisplaySetHour();
}
if (menu==2)
{
DisplaySetMinute();
}
if (menu==3)
{
DisplaySetYear();
}
if (menu==4)
{
DisplaySetMonth();
}
if (menu==5)
{
DisplaySetDay();
}
if (menu==6)
{
StoreAgg();
delay(500);
menu=0;
}
delay(100);
}
void DisplayDateTime ()
{
// mostriamo la data e l'ora correnti
DateTime now = RTC.now();
lcd.clear();
lcd.setCursor(0, 1);
lcd.print("Ora:");
if (now.hour()<=9)
{
lcd.print("0");
}
lcd.print(now.hour(), DEC);
oraagg=now.hour();
lcd.print(":");
if (now.minute()<=9)
{
lcd.print("0");
}
lcd.print(now.minute(), DEC);
minagg=now.minute();
lcd.print(":");
if (now.second()<=9)
{
lcd.print("0");
}
lcd.print(now.second(), DEC);
lcd.setCursor(0, 0);
lcd.print("Data: ");
if (now.day()<=9)
{
lcd.print("0");
}
lcd.print(now.day(), DEC);
dayagg=now.day();
lcd.print("/");
if (now.month()<=9)
{
lcd.print("0");
}
lcd.print(now.month(), DEC);
meseagg=now.month();
lcd.print("/");
lcd.print(now.year(), DEC);
annoagg=now.year();
}
void DisplaySetHour()
{
// Impostazione dell'ora
lcd.clear();
DateTime now = RTC.now();
int ora=now.hour();
if(digitalRead(P2)==HIGH)
{
if(oraagg==23)
{
oraagg=0;
}
else
{
oraagg=oraagg+1;
}
}
if(digitalRead(P3)==HIGH)
{
if(oraagg==0)
{
oraagg=23;
}
else
{
oraagg=oraagg-1;
}
}
lcd.setCursor(0,0);
lcd.print("Imposta Ora:");
lcd.setCursor(0,1);
lcd.print(oraagg,DEC);
delay(200);
}
void DisplaySetMinute()
{
// Impostazione dei minuti
lcd.clear();
if(digitalRead(P2)==HIGH)
{
if (minagg==59)
{
minagg=0;
}
else
{
minagg=minagg+1;
}
}
if(digitalRead(P3)==HIGH)
{
if (minagg==0)
{
minagg=59;
}
else
{
minagg=minagg-1;
}
}
lcd.setCursor(0,0);
lcd.print("Imposta Minuti:");
lcd.setCursor(0,1);
lcd.print(minagg,DEC);
delay(200);
}
void DisplaySetYear()
{
// Impostazione dell'anno
lcd.clear();
if(digitalRead(P2)==HIGH)
{
annoagg=annoagg+1;
}
if(digitalRead(P3)==HIGH)
{
annoagg=annoagg-1;
}
lcd.setCursor(0,0);
lcd.print("Imposta Anno:");
lcd.setCursor(0,1);
lcd.print(annoagg,DEC);
delay(200);
}
void DisplaySetMonth()
{
// Impostazione del mese
lcd.clear();
if(digitalRead(P2)==HIGH)
{
if (meseagg==12)
{
meseagg=1;
}
else
{
meseagg=meseagg+1;
}
}
if(digitalRead(P3)==HIGH)
{
if (meseagg==12)
{
meseagg=12;
}
else
{
meseagg=meseagg-1;
}
}
lcd.setCursor(0,0);
lcd.print("Imposta Mese:");
lcd.setCursor(0,1);
lcd.print(meseagg,DEC);
delay(200);
}
void DisplaySetDay()
{
// Impostazione del giorno
lcd.clear();
if(digitalRead(P2)==HIGH)
{
if (dayagg==31)
{
dayagg=1;
}
else
{
dayagg=dayagg+1;
}
}
if(digitalRead(P3)==HIGH)
{
if (dayagg==1)
{
dayagg=31;
}
else
{
dayagg=dayagg-1;
}
}
lcd.setCursor(0,0);
lcd.print("Imposta Giorno:");
lcd.setCursor(0,1);
lcd.print(dayagg,DEC);
delay(200);
}
void StoreAgg()
{
// Salvataggio delle variabili
lcd.clear();
lcd.setCursor(0,0);
lcd.print("SALVATAGGIO IN");
lcd.setCursor(0,1);
lcd.print("CORSO");
RTC.adjust(DateTime(annoagg,meseagg,dayagg,oraagg,minagg,0));
delay(200);
}
tanto di cappello al realizzatore dello sketch.
RispondiEliminaho apportato una mia modifica da neofita per il corretto aggiornamento dei giorni nei vari mesi, di seguito la parte di codice da modificare:
void DisplaySetDay()
{
lcd.clear();
if (digitalRead(P2) == HIGH)
{
if (meseagg == 2 && dayagg == 28)
{
dayagg = 1;
}
if ((meseagg == 4 && dayagg == 30)|| (meseagg == 6 && dayagg == 30) || (meseagg == 9 && dayagg == 30) || (meseagg == 11 && dayagg == 30))
{
dayagg = 1;
}
if ((meseagg == 1 && dayagg == 31) || (meseagg == 3 && dayagg == 31) || (meseagg == 5 && dayagg == 31) || (meseagg == 7 && dayagg == 31) || (meseagg == 8 && dayagg == 31) || (meseagg == 10 && dayagg == 31) || (meseagg == 12 && dayagg == 31))
{
dayagg = 1;
}
else
{ tone (pinbip, freq), delay(150), noTone(12),
dayagg = dayagg + 1;
}
}
if (digitalRead(P3) == HIGH)
{
if (meseagg == 2 && dayagg == 1)
{
dayagg = 28;
}
if ((meseagg == 4 && dayagg == 1)|| (meseagg == 6 && dayagg == 1) || (meseagg == 9 && dayagg == 1) || (meseagg == 11 && dayagg == 1))
{
dayagg = 30;
}
if ((meseagg == 1 && dayagg == 1) || (meseagg == 3 && dayagg == 1) || (meseagg == 5 && dayagg == 1) || (meseagg == 7 && dayagg == 1) || (meseagg == 8 && dayagg == 1) || (meseagg == 10 && dayagg == 1) || (meseagg == 12 && dayagg == 1))
{
dayagg = 31;
}
else
{ tone (pinbip, freq), delay(150), noTone(12),
dayagg = dayagg - 1;
}
}
lcd.setCursor(0, 0);
lcd.print("Imposta Giorno:");
lcd.setCursor(0, 1);
lcd.print(dayagg, DEC);
delay(200);
}
chiedo scusa, ho visto solo ora che avevo implementato il bip nel mio sketch, a seguire la parte di codice ricorretta senza bip:
Eliminavoid DisplaySetDay()
{
lcd.clear();
if (digitalRead(P2) == HIGH)
{
if (meseagg == 2 && dayagg == 28)
{
dayagg = 1;
}
if ((meseagg == 4 && dayagg == 30)|| (meseagg == 6 && dayagg == 30) || (meseagg == 9 && dayagg == 30) || (meseagg == 11 && dayagg == 30))
{
dayagg = 1;
}
if ((meseagg == 1 && dayagg == 31) || (meseagg == 3 && dayagg == 31) || (meseagg == 5 && dayagg == 31) || (meseagg == 7 && dayagg == 31) || (meseagg == 8 && dayagg == 31) || (meseagg == 10 && dayagg == 31) || (meseagg == 12 && dayagg == 31))
{
dayagg = 1;
}
else
{
dayagg = dayagg + 1;
}
}
if (digitalRead(P3) == HIGH)
{
if (meseagg == 2 && dayagg == 1)
{
dayagg = 28;
}
if ((meseagg == 4 && dayagg == 1)|| (meseagg == 6 && dayagg == 1) || (meseagg == 9 && dayagg == 1) || (meseagg == 11 && dayagg == 1))
{
dayagg = 30;
}
if ((meseagg == 1 && dayagg == 1) || (meseagg == 3 && dayagg == 1) || (meseagg == 5 && dayagg == 1) || (meseagg == 7 && dayagg == 1) || (meseagg == 8 && dayagg == 1) || (meseagg == 10 && dayagg == 1) || (meseagg == 12 && dayagg == 1))
{
dayagg = 31;
}
else
{
dayagg = dayagg - 1;
}
}
lcd.setCursor(0, 0);
lcd.print("Imposta Giorno:");
lcd.setCursor(0, 1);
lcd.print(dayagg, DEC);
delay(200);
}
Grazie mille giorgio giorgio.
EliminaCosa e come migliorarlo per funzionare con DS3231
EliminaQuesto commento è stato eliminato dall'autore.
RispondiEliminaCiao, scusa ma ho visto solo ora il tuo messaggio.
RispondiEliminaper funzionare con il DS3231? sinceramente non so se esiste una libreria apposita. Eventualmente è da vedere di cambiare le funzioni proprie del DS1307 con quelle nuove del DS3231. Non avendolo a disposizione questo integrato, non so come aiutarti, ma se qualcuno che legge questo (ormai vetusto) post, e ha soluzioni o proposte da postare, ben venga!
Ciao e buone feste.
Flavio
Un grande peccato. O forse aiuterai a cambiare in modo da poter cambiare tutti i dati a turno. Significa anno e cambia anno e non come ora che solo alla fine delle impostazioni. Saluti. Krzysztof
EliminaNon so come cambiarlo "RTC_DS1307 RTC;" con DS3231 in modo che l'errore non compaia. E se riesco, allora ho un errore qui "RTC.begin (); e se (! RTC.isrunning (....."
EliminaMi vergogno, ma a 2 anni di distanza cerco di darti una mano... per quanto posso... guarda qui https://github.com/NorthernWidget/DS3231.
RispondiEliminaPerdona il ritardo e spero possa essere utile per il tuo problema...
Ciao