15 dicembre 2012

Orologio con Arduino e il DS1307

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

Lo schema: