Digitálne hodiny Arduino pomocou modulu RTC

Vyskúšajte Náš Nástroj Na Odstránenie Problémov





V tomto príspevku zostrojíme digitálne hodiny pomocou modulu RTC alebo hodín v reálnom čase. Pochopíme, čo je to modul „RTC“, ako komunikovať s Arduinom a čo robí.

Autor:



RTC modul je obvod, ktorý presne sleduje aktuálny čas. Robí dve funkcie, komunikuje s mikrokontrolérmi a mikroprocesormi, aby poskytoval aktuálny čas, a slúži ako záložný obvod na udržanie času v prípade výpadku napájania, pretože má zabudovaný záložný systém batérie.

RTC nájdeme v akýchkoľvek elektronických zariadeniach, kde je čas dôležitou funkciou modulu gadget.



Napríklad náš počítač alebo notebook si udržuje svoj čas aj po odpojení napájania alebo vybratí batérie. Na základnej doske ľubovoľného počítača nájdeme batériu CMOS, ktorá napája obvod RTC.

Podobný druh obvodu použijeme v tomto projekte.

RTC modul je lacné zariadenie, ktoré nájdete na všetkých stránkach elektronického obchodu a miestnych obchodoch s elektronickými projektmi.

Ilustrácia typického RTC modulu DS1307:

Väčšina modulov RTC je v čase zakúpenia vybavená batériou (CR2032). Existujú rôzne veľkosti a modely, vyššie uvedené obrázky nemusia byť pre vás rovnaké. Uistite sa však, že číslo modelu je DS1307. Kód napísaný v tomto príspevku je kompatibilný iba s DS1307.

Teraz viete niečo o RTC. Teraz prejdime k dizajnu digitálnych hodín. Pred pokračovaním v tomto projekte si musíte stiahnuť knižnicu z nasledujúcich odkazov a nainštalovať do svojho IDE:

• DS1307RTC.h

Odkaz: github.com/PaulStoffregen/DS1307RTC

• TimeLib.h

Odkaz: github.com/PaulStoffregen/Time

Ak máte najnovšiu verziu, na Arduino IDE by boli predinštalované ďalšie dve knižnice.

• LiquidCrystal.h

• Wire.h

Okruh:

Obvodové spojenie medzi arduino a LCD displejom je štandardné, podobné pripojenie môžeme nájsť aj na iných projektoch založených na LCD. Jediným ďalším komponentom je RTC.

Aby sa znížilo preťaženie drôtu počas prototypu, môže byť RTC vložený do analógových kolíkov priamo na arduino. Spájkujte SCl, SDA, Vcc a GND s mužskými kolíkmi zástrčky a vložte ich do kolíkov A2 až A5, ako je to znázornené na prototype.

Autorský prototyp:

Ako správne vložiť RTC na Arduino:

Ak má váš RTC rôzne umiestnenia pinov a nemohol sa replikovať, ako je to znázornené vyššie, na pripojenie môžete vždy použiť vodiče. Teraz je vaše nastavenie hardvéru dokončené, poďme k softvérovej časti projektu.

Ako nastaviť čas:

Len čo je modul RTC naprogramovaný, udržuje čas aj po jeho odstránení z arduina. Batéria by mala vydržať najmenej pár rokov.

Neexistuje žiadne tlačidlo na nastavenie času, nasledujúci program nastaví čas v RTC. Počas kompilácie kódu sa čas automaticky synchronizuje s časom vášho počítača. Pred nahrávaním programov sa preto uistite, že je váš počítač nastavený na správny čas.
Nahrajte tento kód „SetTime“ a nastavte čas s pripojeným RTC:

#include  #include  #include  int P=A3 //Assign power pins for RTC int N=A2 const char *monthName[12] = { 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' } tmElements_t tm void setup() { pinMode(P,OUTPUT) pinMode(N,OUTPUT) digitalWrite(P,HIGH) digitalWrite(N,LOW) bool parse=false bool config=false // get the date and time the compiler was run if (getDate(__DATE__) && getTime(__TIME__)) { parse = true // and configure the RTC with this info if (RTC.write(tm)) { config = true } } Serial.begin(9600) while (!Serial)  // wait for Arduino Serial Monitor delay(200) if (parse && config) { Serial.print('DS1307 configured Time=') Serial.print(__TIME__) Serial.print(', Date=') Serial.println(__DATE__) } else if (parse) { Serial.println('DS1307 Communication Error :-{') Serial.println('Please check your circuitry') } else { Serial.print('Could not parse info from the compiler, Time='') Serial.print(__TIME__) Serial.print('', Date='') Serial.print(__DATE__) Serial.println(''') } } void loop() { } bool getTime(const char *str) { int Hour, Min, Sec if (sscanf(str, '%d:%d:%d', &Hour, &Min, &Sec) != 3) return false tm.Hour = Hour tm.Minute = Min tm.Second = Sec return true } bool getDate(const char *str) { char Month[12] int Day, Year uint8_t monthIndex if (sscanf(str, '%s %d %d', Month, &Day, &Year) != 3) return false for (monthIndex = 0 monthIndex < 12 monthIndex++) { if (strcmp(Month, monthName[monthIndex]) == 0) break } if (monthIndex >= 12) return false tm.Day = Day tm.Month = monthIndex + 1 tm.Year = CalendarYrToTm(Year) return true } 

Po načítaní tohto kódu otvorte sériový monitor a mala by sa zobraziť správa o úspechu s oznámením, že je nastavený čas.

To znamená, že vaše spojenie medzi RTC a arduino je správne a čas je nastavený.

Teraz nahrajte nasledujúci kód na zobrazenie času na LCD displeji.

//------------Program Developed by R.Girish-------// #include  #include  #include  #include  LiquidCrystal lcd(12, 11, 5, 4, 3, 2) int P=A3 int N=A2 void setup() { lcd.begin(16,2) pinMode(P,OUTPUT) pinMode(N,OUTPUT) digitalWrite(P,HIGH) digitalWrite(N,LOW) } void loop() { tmElements_t tm lcd.clear() if (RTC.read(tm)) { if(tm.Hour>=12) { lcd.setCursor(14,0) lcd.print('PM') } if(tm.Hour<12) { lcd.setCursor(14,0) lcd.print('AM') } lcd.setCursor(0,0) lcd.print('TIME:') if(tm.Hour>12) //24Hrs to 12 Hrs conversion// { if(tm.Hour==13) lcd.print('01') if(tm.Hour==14) lcd.print('02') if(tm.Hour==15) lcd.print('03') if(tm.Hour==16) lcd.print('04') if(tm.Hour==17) lcd.print('05') if(tm.Hour==18) lcd.print('06') if(tm.Hour==19) lcd.print('07') if(tm.Hour==20) lcd.print('08') if(tm.Hour==21) lcd.print('09') if(tm.Hour==22) lcd.print('10') if(tm.Hour==23) lcd.print('11') } else { lcd.print(tm.Hour) } lcd.print(':') lcd.print(tm.Minute) lcd.print(':') lcd.print(tm.Second) lcd.setCursor(0,1) lcd.print('DATE:') lcd.print(tm.Day) lcd.print('/') lcd.print(tm.Month) lcd.print('/') lcd.print(tmYearToCalendar(tm.Year)) } else { if (RTC.chipPresent()) { lcd.setCursor(0,0) lcd.print('RTC stopped!!!') lcd.setCursor(0,1) lcd.print('Run SetTime code') } else { lcd.clear() lcd.setCursor(0,0) lcd.print('Read error!') lcd.setCursor(0,1) lcd.print('Check circuitry!') } delay(500) } delay(500) } //------------Program Developed by R.Girish-------// 

Akonáhle je to hotové, mali by ste vidieť čas a dátum, ktorý sa zobrazuje na LCD a beží.

Poznámka: Kód „SetTime“ je upravený z ukážkového kódu DS1307RTC s cieľom optimalizovať drôtové pripojenia pre modul RTC. Nahraním pôvodného kódu nebude nastavený čas.

Digitálny budík pomocou Arduina

V tomto vyššie sme sa naučili, ako zostaviť základné hodiny Arduino pomocou modulu RTC, v nasledujúcej časti preskúmame, ako je možné ich upgradovať na obvod digitálneho budíka pomocou Arduina.

Sú ľudia, ktorí budík nepotrebujú, budia sa prirodzene a sú ľudia, ktorí sa zobudia po niekoľkonásobnom zvonení budíka a sú ľudia, ktorí mnohokrát stlačia tlačidlo odloženia a idú neskoro na univerzitu nejaké výhovorky.

Navrhovaný zábavný projekt malého budíka môže čeliť problému s lenivosťou počas ranného prebúdzania. Väčšina budíkov má tlačidlo odloženia budenia a vopred stanovený čas prerušenia budíka, ak používateľ nereaguje.

Tento budík sme navrhli bez lenivého tlačidla (tlačidlo odloženia spánku) a budík sa nevypne, kým používateľ nestlačí tlačidlo.

Tieto hodiny môžu ukazovať čas v 12-hodinovom formáte a dátum vo formáte DD / MM / RRRR.

Čas a dátum sa zobrazia na LCD displeji 16 x 2. O sledovanie času sa postará modul času RTC alebo čas v reálnom čase a dokáže si udržať správny čas aj po dlhom výpadku napájania.

K dispozícii je 5 tlačidiel, ktorých funkcia bude čoskoro vysvetlená. Mozog projektu Arduino môže mať ľubovoľný model podľa vášho výberu, odporúčame mu Arduino pro mini alebo Arduino nano kvôli jeho kompaktným rozmerom.

Poďme sa teraz venovať schémam.

Vyššie uvedené je schéma, ktorá zobrazuje pripojenie Arduina, upravte kontrast displeja otočením potenciometra 10K.

Nižšie je uvedený zvyšok obvodu:

Obvod je možné napájať na nástenný adaptér 9V 500mA.

Funkcie 5 tlačidiel:

S1 - Používa sa na zastavenie alarmu (je tiež resetovacím tlačidlom).
S2 - Používa sa na nastavenie alarmu. Dlhým stlačením S2 sa dostanete do menu nastavenia budíka.
S3 - slúži na zvýšenie hodín.
S4 - slúži na prírastok minút.
S5 - Používa sa na prepínanie stavu alarmu. Ak na LCD displeji v pravom dolnom rohu existuje „*“, alarm je ZAPNUTÝ, ak „*“ neexistuje, štatistika alarmu je VYPNUTÁ.

Viac podrobností o tom, ako nastaviť budík, je vysvetlené v dolnej časti článku.

Stiahnite si súbory knižnice nižšie:

Link1: github.com/PaulStoffregen/DS1307RTC
Link2: github.com/PaulStoffregen/Time

Teraz musíme nastaviť čas na RTC modul, čas bude synchronizovaný z vášho PC do RTC modulu.

Nahrajte nasledujúci kód, aby ste nastavili čas a otvorili Sériový monitor:

//------------------------------------------------// #include  #include  #include  const char *monthName[12] = { 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' } tmElements_t tm void setup() { bool parse=false bool config=false // get the date and time the compiler was run if (getDate(__DATE__) && getTime(__TIME__)) { parse = true // and configure the RTC with this info if (RTC.write(tm)) { config = true } } Serial.begin(9600) while (!Serial)  // wait for Arduino Serial Monitor delay(200) if (parse && config) { Serial.print('DS1307 configured Time=') Serial.print(__TIME__) Serial.print(', Date=') Serial.println(__DATE__) } else if (parse) { Serial.println('DS1307 Communication Error :-{') Serial.println('Please check your circuitry') } else { Serial.print('Could not parse info from the compiler, Time='') Serial.print(__TIME__) Serial.print('', Date='') Serial.print(__DATE__) Serial.println(''') } } void loop() { } bool getTime(const char *str) { int Hour, Min, Sec if (sscanf(str, '%d:%d:%d', &Hour, &Min, &Sec) != 3) return false tm.Hour = Hour tm.Minute = Min tm.Second = Sec return true } bool getDate(const char *str) { char Month[12] int Day, Year uint8_t monthIndex if (sscanf(str, '%s %d %d', Month, &Day, &Year) != 3) return false for (monthIndex = 0 monthIndex < 12 monthIndex++) { if (strcmp(Month, monthName[monthIndex]) == 0) break } if (monthIndex >= 12) return false tm.Day = Day tm.Month = monthIndex + 1 tm.Year = CalendarYrToTm(Year) return true } //----------------------------------------// 

Teraz ste úspešne nastavili čas na RTC
Ďalej musíte nahrať nasledujúci hlavný kód:

//------------Program Developed by R.Girish-------// #include  #include  #include  #include  #include  const int rs = 7 const int en = 6 const int d4 = 5 const int d5 = 4 const int d6 = 3 const int d7 = 2 const int buzzer = 8 boolean alarm = false boolean outloop = true const int setAlarm = A0 const int Hrs = A1 const int Min = A2 const int ok = A3 const int HrsADD = 0 const int MinADD = 1 const int ALsave = 2 int HrsVal = 0 int MinVal = 0 int H = 0 int M = 0 int S = 0 int i = 0 int j = 0 int k = 0 LiquidCrystal lcd(rs, en, d4, d5, d6, d7) void setup() { Serial.begin(9600) lcd.begin(16, 2) pinMode(buzzer, OUTPUT) pinMode(setAlarm, INPUT) pinMode(Hrs, INPUT) pinMode(Min, INPUT) pinMode(ok, INPUT) digitalWrite(setAlarm, HIGH) digitalWrite(Hrs, HIGH) digitalWrite(Min, HIGH) digitalWrite(ok, HIGH) } void loop() { tmElements_t tm lcd.clear() if (EEPROM.read(ALsave) == false) { lcd.setCursor(15, 1) lcd.print('') } if (EEPROM.read(ALsave) == true) { lcd.setCursor(15, 1) lcd.print(F('*')) } if (RTC.read(tm)) { if (tm.Hour >= 12) { lcd.setCursor(14, 0) lcd.print('PM') } if (tm.Hour < 12) { lcd.setCursor(14, 0) lcd.print('AM') } lcd.setCursor(0, 0) lcd.print('TIME:') H = tm.Hour if (tm.Hour > 12) { if (tm.Hour == 13) { lcd.print('01') } if (tm.Hour == 14) { lcd.print('02') } if (tm.Hour == 15) { lcd.print('03') } if (tm.Hour == 16) { lcd.print('04') } if (tm.Hour == 17) { lcd.print('05') } if (tm.Hour == 18) { lcd.print('06') } if (tm.Hour == 19) { lcd.print('07') } if (tm.Hour == 20) { lcd.print('08') } if (tm.Hour == 21) { lcd.print('09') } if (tm.Hour == 22) { lcd.print('10') } if (tm.Hour == 23) { lcd.print('11') } } else { lcd.print(tm.Hour) } M = tm.Minute S = tm.Second lcd.print(':') lcd.print(tm.Minute) lcd.print(':') lcd.print(tm.Second) lcd.setCursor(0, 1) lcd.print('DATE:') lcd.print(tm.Day) lcd.print('/') lcd.print(tm.Month) lcd.print('/') lcd.print(tmYearToCalendar(tm.Year)) } else { if (RTC.chipPresent()) { lcd.setCursor(0, 0) lcd.print('RTC stopped!!!') lcd.setCursor(0, 1) lcd.print('Run SetTime code') } else { lcd.clear() lcd.setCursor(0, 0) lcd.print('Read error!') lcd.setCursor(0, 1) lcd.print('Check circuitry!') } } if (digitalRead(setAlarm) == LOW) { setALARM() } if (H == EEPROM.read(HrsADD) && M == EEPROM.read(MinADD) && S == 0) { if (EEPROM.read(ALsave) == true) { sound() } } if (digitalRead(ok) == LOW) { if (EEPROM.read(ALsave) == true) { EEPROM.write(ALsave, 0) alarm = false delay(1000) return } if (EEPROM.read(ALsave) == false) { EEPROM.write(ALsave, 1) alarm = true delay(1000) return } } delay(1000) } void setALARM() { HrsVal = EEPROM.read(HrsADD) MinVal = EEPROM.read(MinADD) lcd.clear() lcd.setCursor(0, 0) lcd.print(F('>>>>SET ALARM<<<')) lcd.setCursor(0, 1) lcd.print(F('Hrs:')) lcd.print(EEPROM.read(HrsADD)) lcd.print(F(' Min:')) lcd.print(EEPROM.read(MinADD)) delay(600) while (outloop) { if (HrsVal > 23) { HrsVal = 0 lcd.clear() lcd.setCursor(0, 0) lcd.print(F('>>>>SET ALARM<<<')) lcd.setCursor(0, 1) lcd.print(F('Hrs:')) lcd.print(HrsVal) lcd.print(F(' Min:')) lcd.print(MinVal) } if (MinVal > 59) { MinVal = 0 lcd.clear() lcd.setCursor(0, 0) lcd.print(F('>>>>SET ALARM<<<')) lcd.setCursor(0, 1) lcd.print(F('Hrs:')) lcd.print(HrsVal) lcd.print(F(' Min:')) lcd.print(MinVal) } if (digitalRead(Hrs) == LOW) { HrsVal = HrsVal + 1 lcd.clear() lcd.setCursor(0, 0) lcd.print(F('>>>>SET ALARM<<<')) lcd.setCursor(0, 1) lcd.print(F('Hrs:')) lcd.print(HrsVal) lcd.print(F(' Min:')) lcd.print(MinVal) delay(250) } if (digitalRead(Min) == LOW) { MinVal = MinVal + 1 lcd.clear() lcd.setCursor(0, 0) lcd.print(F('>>>>SET ALARM<<<')) lcd.setCursor(0, 1) lcd.print(F('Hrs:')) lcd.print(HrsVal) lcd.print(F(' Min:')) lcd.print(MinVal) delay(250) } if (digitalRead(setAlarm) == LOW) { EEPROM.write(HrsADD, HrsVal) EEPROM.write(MinADD, MinVal) lcd.clear() lcd.setCursor(0, 0) lcd.print(F('Alarm is Set for')) lcd.setCursor(0, 1) lcd.print(EEPROM.read(HrsADD)) lcd.print(F(':')) lcd.print(EEPROM.read(MinADD)) lcd.print(F(' Hrs')) delay(1000) outloop = false } } outloop = true } void sound() { lcd.clear() lcd.setCursor(0, 0) lcd.print('Wakey Wakey !!!') lcd.setCursor(0, 1) lcd.print('Its Time now.....') for (j = 0 j < 10 j++) { for (i = 0 i < 2  i++) { digitalWrite(buzzer, HIGH) delay(150) digitalWrite(buzzer, LOW) delay(150) } delay(400) } for (k = 0 k < 10 k++) { for (i = 0 i < 4  i++) { digitalWrite(buzzer, HIGH) delay(150) digitalWrite(buzzer, LOW) delay(150) } delay(250) } while (true) { digitalWrite(buzzer, HIGH) delay(150) digitalWrite(buzzer, LOW) delay(150) } } //------------Program Developed by R.Girish-------// 

Po nahraní vyššie uvedeného kódu musíte na displeji vidieť správny čas a dátum.

Teraz sa pozrime, ako nastaviť budík:
• Dlho stlačte S2, kým sa nezobrazí ponuka Alarm.
• Stlačením tlačidiel S3 a S4 upravte hodiny a minúty.
• Po nastavenom požadovanom čase stlačte ešte raz S2. Zobrazí sa hlásenie „Budík je nastavený na xx: xx hodín“.
• Ak je alarm ZAPNUTÝ, na displeji sa zobrazí symbol „*“, ak je alarm VYPNUTÝ, nebude sa zobrazovať žiadny symbol „*“.
• Budík môžete zapnúť / vypnúť stlačením S5 na pol sekundy. Nestláčajte dlho, kým „*“ nezmizne (znova sa vráti), stačí stlačiť pol sekundy a prepnúť tak stav alarmu.

DÔLEŽITÁ POZNÁMKA:

Najbežnejšou chybou pri nastavovaní budíka na ľubovoľných hodinách je neúmyselné prepínanie AM / PM, čo má za následok nezvonenie budíka v čase našej túžby.

Aby sa tento problém zvrátil, navrhované nastavenie budíka je navrhnuté vo formáte 24 hodín.

Čas zobrazený na LCD displeji bude 12 hodín vo formáte AM / PM, ale pri nastavovaní budíka pomocou tohto projektu musíte nastaviť 24-hodinový formát od 0 do 23 hodín.

Napríklad: ak chcete nastaviť budík na 21:00, musíte nastaviť 21 hodín a 0 minút. Na 5:00: 5 hodín a 0 minút a tak ďalej.

Autorský prototyp:

Páči sa vám tento projekt? Máte akékoľvek otázky týkajúce sa tohto projektu, neváhajte ich vyjadriť v komentári, môžete dostať rýchlu odpoveď.

Videoklip:




Dvojica: Obvod indikátora úrovne majáka pre nádrže na zrno kombajnu Ďalej: 3 vysoko výkonné invertorové obvody SG3525 Pure Sinewave