Digitální hodiny Arduino pomocí modulu RTC

Vyzkoušejte Náš Nástroj Pro Odstranění Problémů





V tomto příspěvku budeme konstruovat digitální hodiny pomocí modulu RTC nebo hodin reálného času. Pochopíme, co je to modul „RTC“, jak komunikovat s Arduinem a co dělá.

Podle:



RTC modul je obvod, který přesně sleduje aktuální čas. Dělá dvě funkce, komunikuje s mikrokontroléry a mikroprocesory, aby poskytoval aktuální čas a fungoval jako záložní obvod pro udržení času v případě výpadku napájení, protože má zabudovaný záložní systém baterie.

RTC najdeme v jakýchkoli elektronických zařízeních, kde je čas důležitou funkcí gadgetu.



Náš počítač nebo notebook si například udržuje svůj čas i po odpojení napájení nebo vyjmutí baterie. Na základní desce jakéhokoli počítače najdeme baterii CMOS, která napájí obvod RTC.

Podobný druh obvodu použijeme v tomto projektu.

RTC modul je levné zařízení, které najdete na jakýchkoli stránkách elektronického obchodování a místních obchodech s elektronickými projekty.

Ilustrace typického modulu RTC DS1307:

Většina modulů RTC je v době zakoupení dodávána s baterií (CR2032). Existují různé velikosti a modely, výše uvedené obrázky nemusí být pro vás stejné. Ujistěte se však, že číslo modelu je DS1307. Kód napsaný v tomto příspěvku je kompatibilní pouze s DS1307.

Nyní víte něco o RTC. Nyní přejdeme k designu digitálních hodin. Než budete pokračovat v tomto projektu, musíte si stáhnout knihovnu z následujících odkazů a nainstalovat do svého IDE:

• DS1307RTC.h

Odkaz: github.com/PaulStoffregen/DS1307RTC

• TimeLib.h

Odkaz: github.com/PaulStoffregen/Time

Další dvě knihovny by byly předinstalovány na Arduino IDE, pokud používáte nejnovější verzi.

• LiquidCrystal.h

• Wire.h

Okruh:

Okruhové spojení mezi Arduino a LCD displejem je standardní, což můžeme najít u jiných projektů založených na LCD. Jedinou doplňkovou součástí je RTC.

Aby se snížilo přetížení vodičů během prototypu, lze RTC vložit do analogových kolíků přímo arduina. Pájejte SCl, SDA, Vcc a GND pomocí samčích kolíků zástrčky a vložte je do kolíků A2 až A5, jak je znázorněno v prototypu.

Autorův prototyp:

Jak správně vložit RTC na Arduino:

Pokud má váš RTC různá umístění pinů a nemohl se replikovat, jak je znázorněno výše, pro připojení můžete vždy použít vodiče. Nyní je vaše nastavení hardwaru dokončeno, přejdeme k softwarové části projektu.

Jak nastavit čas:

Jakmile je modul RTC naprogramován, udržuje čas i po jeho odebrání z arduina. Baterie by měla vydržet alespoň pár let.

Neexistuje žádné tlačítko pro nastavení času, následující program nastaví čas v RTC. Při kompilaci kódu se čas automaticky synchronizuje s časem vašeho počítače, proto se před nahráním programů ujistěte, že je váš počítač nastaven na správný čas.
Nahrajte tento kód „SetTime“ a nastavte čas s připojený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 } 

Jakmile je tento kód nahrán, otevřete sériový monitor a měla by se zobrazit zpráva o úspěchu, která říká, že byl nastaven čas.

To znamená, že vaše spojení mezi RTC a arduino je správné a je nastaven čas.

Nyní nahrajte následující kód pro zobrazení času na LCD.

//------------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-------// 

Jakmile to uděláte, měli byste vidět čas a datum, které se zobrazí na LCD a běží.

Poznámka: Kód „SetTime“ je upraven z ukázkového kódu DS1307RTC za účelem optimalizace drátových připojení pro modul RTC, nahrání původního kódu nezastaví čas.

Digitální budík pomocí Arduina

V tomto výše jsme se naučili, jak sestavit základní hodiny Arduino pomocí modulu RTC, v následující části zkoumáme, jak je lze pomocí Arduina upgradovat na obvod digitálního budíku.

Existují lidé, kteří nepotřebují budík, budí se přirozeně a jsou lidé, kteří se budí poté, co budík několikrát zazvoní, a jsou lidé, kteří několikrát stisknou tlačítko odložení a jdou na vysokou školu / pracují pozdě s nějaké výmluvy.

Navrhovaný zábavný projekt malého budíku může čelit problému s lenivostí během ranního probuzení. Většina budíků má tlačítko odložení a předem stanovenou mezní dobu pro budík, pokud uživatel nereaguje.

Tento budík jsme navrhli bez líného tlačítka (tlačítko odložení) a budík se nevypne, dokud uživatel nestiskne tlačítko.

Tyto hodiny mohou ukazovat čas ve 12hodinovém formátu a datum ve formátu DD / MM / RRRR.

Čas a datum se zobrazí na LCD displeji 16 x 2. Časový modul RTC nebo hodiny reálného času se postará o sledování času a může si zachovat správný čas i po dlouhém výpadku napájení.

K dispozici je 5 tlačítek, jejichž funkce bude brzy vysvětlena. Mozkem projektu Arduino může jakýkoli model podle vašeho výběru, doporučujeme Arduino pro mini nebo Arduino nano kvůli jeho kompaktní velikosti.

Nyní se ponořme do schémat.

Výše uvedené je schéma, které má Arduino zobrazit připojení, upravit kontrast displeje otočením potenciometru 10K.

Níže je zbytek okruhu:

Obvod může být napájen 9V 500mA nástěnným adaptérem.

Funkce 5 tlačítek:

S1 - Slouží k zastavení alarmu (je také resetovacím tlačítkem).
S2 - Slouží k nastavení alarmu. Dlouhým stisknutím S2 se dostanete do nabídky nastavení budíku.
S3 - Používá se ke zvýšení hodin.
S4 - slouží k přírůstku minut.
S5 - Slouží k přepínání stavu alarmu. Pokud na LCD displeji v pravém dolním rohu existuje „*“, alarm je ZAPNUTÝ, pokud „*“ neexistuje, jsou statistiky alarmu VYPNUTY.

Více podrobností o nastavení budíku je vysvětleno ve spodní části článku.

Stáhněte si níže uvedené soubory knihovny:

Odkaz 1: github.com/PaulStoffregen/DS1307RTC
Link2: github.com/PaulStoffregen/Time

Nyní musíme nastavit čas na RTC modul, čas bude synchronizován z vašeho PC do RTC modulu.

Nahrajte níže uvedený kód pro nastavení času a otevření sériového monitoru:

//------------------------------------------------// #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 } //----------------------------------------// 

Nyní jste úspěšně nastavili čas na RTC
Dále musíte nahrát následující 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 nahrání výše uvedeného kódu musíte na displeji vidět správný čas a datum.

Nyní se podívejme, jak nastavit budík:
• Dlouze stiskněte tlačítko S2, dokud neuvidíte nabídku Alarm.
• Stisknutím S3 a S4 upravte hodiny a minuty.
• Po nastaveném požadovaném čase stiskněte znovu S2. Říká „Budík je nastaven na xx: xx hodin“.
• Pokud je alarm ZAPNUTÝ, na displeji se zobrazí symbol „*“, pokud je alarm VYPNUTÝ, nezobrazí se žádný symbol „*“.
• Budík můžete zapnout / vypnout stisknutím S5 na půl sekundy. Netlačte dlouho, dokud „*“ nezmizí (znovu se vrátí), stačí stisknout půl vteřiny pro přepnutí stavu alarmu.

DŮLEŽITÁ POZNÁMKA:

Nejběžnější chybou při nastavování budíku na jakýchkoli hodinách je neúmyslné přepínání AM / PM, což má za následek nezvonění budíku v naší době přání.

Abychom tomuto problému čelili, navrhované nastavení budíku je navrženo ve formátu 24hodinových hodin.

Čas zobrazený na LCD bude 12 hodin ve formátu AM / PM, ale když nastavíte budík u tohoto projektu, musíte nastavit 24hodinový formát od 0 do 23 hodin.

Například: chcete-li nastavit budík na 21:00, musíte nastavit 21 hodin a 0 minut. Pro 5:00: 5 hodin a 0 minut atd.

Autorův prototyp:

Líbí se vám tento projekt? Máte jakékoli dotazy týkající se tohoto projektu, neváhejte vyjádřit v komentáři, můžete obdržet rychlou odpověď.

Videoklip:




Předchozí: Obvod indikátoru úrovně majáku pro nádrže na obilí kombajnu Další: 3 vysoce výkonné invertorové obvody SG3525 Pure Sinewave