RTC DS1302 (Real Time Clock), prikaz ure, datuma na LCD, vklop alarma

RTC DS1302 vsebuje podatke o času in koledarju in ima 31 bajtov statičnega RAM pomnilnika. Čas podaja v sekundah, minutah in urah, koledar pa v dnevih v tednu, dan v mesecu, mesec v letu in leto. Vsebije podatke o prestopnem letu, prehoda iz letni v zimski čas (in obratno) pa ne. Uro lahko prikazuje v 24-urni ali 12-urni obliki z indikatorjem AM/PM.

Za komunikacijo z razvojno ploščo Arduino, mi bomo uporabili Arduino Uno, ali drugim mikrokontrolerjem uporablja enostavno sinhrono serijsko komunikacijo, za kar potrebuje tri povezovalne linije: DAT (data line), CLK (serijski takt, uro) in RST. Podatke lahko prenašamo v RTC in iz RTC modula.

Modul vsebuje ohišje za baterijo 3 V. Baterija služi za ohranjanje nastavljenih podatkov o času in koledarju. Za komunikacijo z Arduino potrebuje napetost 5 V. Če modul nima napetostnega napajanja od Arduina (5 V) in je baterija (3 V) prazna, izgubimo podatke o času in koledarju.

Slika 1: RTC DS1302 modul (vir: http://www.hobbytronics.co.uk/real-time-clock-module-ds1302)

Potrebovali bomo tri knjižnice (najdemo jih spodaj v prilogi): DS1302RTC.h, Streaming.h in Time.h. Ko navedene knjižnice dodamo v Arduino libraries in zažemeno Okolje Arduino, odpremo primer SetSerial (menijska vrstica Datoteka > Primeri > DS1302RTC > SetSerial). S pomočjo tega programa bomo prek serijskega monitorja v modul RTC DS1302 vpisali čas in datum. Najprej pa priključimo modul RTC DS1302 na Arduino Uno:

V programu SetSerial, ki smo ga izbrali izmed primerov, spremenimo priključitev pinov, kamor priključimo RTC DS1302 modul:

Slika 2: Sprememba priključnih pinov priključitve modula RTC DS1302 na Arduino Uno v primeru SetSerial

Nato program zapišemo v razvojno ploščo Arduino Uno, odpremo serijski monitor in izberemo hitrost komunikacije 115200 bit/s (baud). Kot je opisano v primeru, čas in datim nastavimo tako, da najprej vpišemo leto, presledek, mesec, presledek, dan v mesecu, presledek, ura, presledek, minuta, presledek, sekunda, presledek, F in pritisnemo na tipko enter ali na gumb Pošlji.

Primer:

Slika 3: Nastavitev na 13. avgust 2015, ura 8, 44 min in 0 sekund

Ko pritisnemo na tipko enter ali na gumb Pošlji, se v modul RTC DS1302 zapiše čas in datum, ki smo ga izbrali, čas in datum pa se začneta izpisovati na serijskem monitorju:

Slika 4: Izpisovanje datuma in časa na serijskem monitorju

Če imamo v modulu RTC DS1302 vstavljeno baterijo 3 V, se bo nastavljen datum in čas ohranil tudi po tem, ko izklopimo napajanje razvojne plošče Arduino Uno.

Na LCD displayu želimo prikazovati tekoči čas in datum ter vklopiti alarm (LED diodo) ob programsko določenem času.

Na razvojno ploščo Arduino Uno priključimo LCD display (16x2) in LED diodo. LED dioda nam bo služila kot indikator alarma in jo preko upora 470 ohm priključimo na pin 13, dvovrstični LCD display pa na pine, kot prikazuje spodnja tabela:

*Odvisno od tipa LCD displaya.

Program:

/*

  RTC modul DS1303, Arduino Uno, LCD 16X2, Alarm => LED dioda.

  Milan Ivič

  avgust 2015.

  Priključitev na Arduino Uno:

  RTC DS1302:

     RST pin   => Arduino Uno pin 6

     DAT pin   => Arduino Uno pin 5

     CLK pin   => Arduino Uno pin 4

     GND pin  => Arduino Uno pin 3

     Vcc pin   => Arduino Uno pin 2

 LCD:

     D7 => Arduino Uno pin 12

     D6 => Arduino Uno pin 11

     D5 => Arduino Uno pin 10

     D4 => Arduino Uno pin 9

     E   => Arduino Uno pin 8

     RS => Arduino Uno pin 7

 LED dioda:

    LED => Arduino Uno pin 13

 */

 //Knjižnice:

 #include <LiquidCrystal.h>

 #include <DS1302RTC.h>

 #include <Time.h>

 //Inicializacija RTC DS1202 (RST => pin 6, DAT => pin 5, CLK => pin 4):

 DS1302RTC RTC(6, 5, 4);

 #define DS1302_GND_pin 3

 #define DS1302_Vcc_pin 2

 #define LED_pin 13

 //Inicializacija LCD displaya 16x2:

 //lcd (RS, E, D4, D5, D6, D7)

 LiquidCrystal lcd(7,   8,  9,  10,  11,  12);

 void setup()

 {

   pinMode(13, OUTPUT);

   //Dvovrstični LCD, vsaka vrstica 16 znakov:

   lcd.begin(16, 2);

   //Aktiviranje RTC DS1302 modula:

   digitalWrite(DS1302_GND_pin, LOW);

   pinMode(DS1302_GND_pin, OUTPUT);

   digitalWrite(DS1302_Vcc_pin, HIGH);

   pinMode(DS1302_Vcc_pin, OUTPUT);

   lcd.print("RTC aktiviran.");

   delay(1000);

   //Preverjanje oscilatorja RTC modula:  

   lcd.clear();

   if (RTC.haltRTC())

   {

     lcd.print("Ura ustavljena!");

   }

   else

   {

     lcd.print("Ura deluje.");

   }   

   delay(1000);

   //Nastavitev Time library:

   lcd.clear();

   lcd.print("RTC sinhron.");

   delay(600);

   setSyncProvider(RTC.get);       //S funkcijo prevzamemo čas, nastavljen v RTC modulu.

   if(timeStatus() == timeSet)

   {

     lcd.print(" Ok!");

   }

  else

   {

     lcd.print(" Napaka!");

   }

  delay (2000);

  lcd.clear();

 }

 void loop()

 {

   //Nastavitev prikaza na LCD displayu:

   lcd.setCursor(3, 0);

   Print2znaka(hour());      //Klicanje funkcije Print2znaka za prikaz ure na LCD.

   lcd.print(" ");

   Print2znaka(minute());  //Klicanje funkcije Print2znaka za prikaz minute na LCD.

   lcd.print(" ");

   Print2znaka(second());  //Klicanje funkcije Print2znaka za prikaz sekunde na LCD.

   //Nastavitev prikaza dneva v tednu na LCD-ju:

   lcd.setCursor(0, 1);

   lcd.print(dayShortStr(weekday()));     //Izpis dneva v tednu na LCD (dan naj bo označen s črkami, kratke oznake).

   //Nastavitev prikaza datuma na LCD-ju:

   lcd.setCursor(5, 1);   //Začni izpisovati na 6-tem znaku v drugi vrstici LCD-ja.

   lcd.print(" ");

   Print2znaka(day());      //Dan.

   lcd.print("/");

   Print2znaka(month());  //Mesec v letu.

   lcd.print("/");

   lcd.print(year());           //Leto.

 

   //Nastavitev alarma (Vklop LED diode, priključene na pin 13) ob nastavljenem času:

   if(now, hour() == 10 && minute() == 26 && weekday() == 5)        //Nedelja je dan 1, četrtek je dan 5.

   {

     digitalWrite(13, HIGH);      //Vklopi alarm => LED diodo. Alarm se bo vklopil vsak četrtek ob 10 uri in 26 minut.

   }

   if(now, hour() == 10 && minute() == 27 && weekday() == 5)

   {

     digitalWrite(13, LOW);       //Izklopi alarm => LED diodo.

   }

   delay (1000);

 }

 void Print2znaka(int stevilo)    

           //Funkcija za prikaz dvomestnega števila. Če je število manjše od 10, je na prvem mestu (desno) številka 0.

 {  

   if (stevilo >= 0 && stevilo < 10)

   {

     lcd.write('0');              //Če so sekunde, minute itd manjše od 10, se prikaže npr. 08, in ne 8.

   }

   lcd.print(stevilo);

 }

Razlaga programa je v komentarjih. Za vklop alarma si lahko izberemo poljubni čas, datum in dan v tednu. V našem primeru smo si izbrali dan v tednu, uro in minuto. Vsi trije pogoji morajo biti izpolnjeni, da se izvede if blok (vklopi oziroma izklopi LED dioda, ki predstavlja alarm). V našem primeru bo LED dioda izklopila po eni minuti.