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);
}