Nekecal's, je to tak. Tlačítka do Vcc s PullDown.
Hrál jsem si s tvým programem, faktem je, že bez displeje a časovače to není nic moc. Ale aspoň ty knihovny mě dovolily základní kontrolu kompilací.
Domnívám se, že třeba definice speciálních znaku není třeba dělat neustále dokola ve smyčce loop(), tedy za předpokladu, že funkce lcd.clear() nemaže i definované znaky. Taky si myslím, že by bylo škoda se ochudit o možnost nechat se vzbudit o půlnoci, například pro Lovce duchů je to denní chleba. Úpravy programu, které tady navrhuji, jsem neměl možnost nijak ověřit, to je na tobě.
Trošku se změnili role tlačítek.
SET - 1. stiskem přejdou hodiny do nastavení hodin
2. stiskem přejdou z nastavení hodin do nastavení budíku
3. přejdou do nastaveni data
4. se vrátí do normálního režimu - režimu hodin
EXIT - tlačítko v režimu hodin vypíná nebo zapíná zvonění
v režimu nastavování zatím nic nedělá, ale já bych ho použil jako tlačítko pro nastavení roku/Year
Nastavování data si musíš dopsat, já jsem tam pro něj jen připravil smyčku. Bez hardware si opravdu nic neodzkouším, tak je to plně na tobě, včetně případných dalších vychytávek.
Kód: Vybrat vše
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DS1302.h>
#define pset 22 // definice portu pro tlacitko SET
#define phour 23 // definice portu pro tlacitko HOUR
#define pmin 24 // definice portu pro tlacitko MIN
#define pexit 25 // definice portu pro tlacitko EXIT
#define buzzer 8 // definice portu pro zvonek
#define SPEED 400 // perioda inkrementace hodin a minut [ms]
#define SWITCH 50 // zpozdeni pro osetreni zakmitu tlacitka [ms]
/* definice ceskych znaku a zvonku */
byte c_hacek[8] = {
0b01010,
0b00100,
0b01110,
0b10000,
0b10000,
0b10000,
0b01110,
0b00000
};
byte y_carka[8] = {
0b00010,
0b00100,
0b10001,
0b10001,
0b01111,
0b00001,
0b01110,
0b00000
};
byte i_carka[8] = {
0b00010,
0b00100,
0b00000,
0b00100,
0b01100,
0b00100,
0b01110,
0b00000
};
byte zvonek_znak[8] = {
0b00100,
0b01110,
0b01110,
0b01110,
0b01110,
0b11111,
0b00000,
0b00100
};
byte Hour; // promenna hodin
byte Min; // promenna minut
byte Sec; // promenna sekund
byte OldSec = 0; // pomocna promenna pro obnoveni displeje pri zmene casu
unsigned int Year = 2019;
byte Month = 6;
byte Day = 15;
byte h = 05; // nastaveni budiku - hodiny
byte m = 00; // nastaveni budiku - minuty
bool budik = false; // priznak povoleni zvoneni budiku
Time t; // strukturovany cas
LiquidCrystal_I2C lcd(0x27, 20, 4);
DS1302 rtc(7, 6, 5);
void setup()
{
pinMode(pset, INPUT);
pinMode(phour, INPUT);
pinMode(pmin, INPUT);
pinMode(pexit, INPUT);
rtc.halt(false);
rtc.writeProtect(false);
lcd.begin();
lcd.createChar(0, c_hacek); // definice znaku
lcd.createChar(1, y_carka); // definice znaku
lcd.createChar(2, i_carka); // definice znaku
lcd.createChar(3, zvonek_znak);// definice znaku
}
void loop() {
// pokud se zmenil cas, tak prepis displej
t = rtc.getTime();
Hour = t.hour;
Min = t.min;
Sec = t.sec;
if (OldSec != Sec) {
OldSec = Sec;
DisplayPrepis(); // zobrazeni
}
// pokud nastal cas zvoneni tak zazvon
if (budik && Hour == h && Min == m && Sec < 2 ) tone(buzzer, 400);
// zde je stiskem tlacitka EXIT mozne zapinat a vypinat buzeni
if (digitalRead(pexit)) {
budik = !budik; // prepina budik On/Off
if (budik) {
lcd.setCursor(19, 0);// budik ON - zapis znak zvonku
lcd.write(byte(3));
} else {
lcd.setCursor(19, 0);// budik OFF - zrus znak zvonku
lcd.write(" ");
noTone(buzzer); // vypni zvonek i kdyz treba nezvoni
}
while (digitalRead(pexit)) {} // ceka na uvolneni tlacitka EXIT
delay(SWITCH); // osetruje zakmity tlacitka
}
/* pri opakovanem stisku tlacitka SET je mozne nastavovat cas, budik a datum
nebo prejit zpatky do normalniho modu */
if (digitalRead(pset))Nastaveni();
}
void DisplayPrepis(void) {
/* bezne zobrazeni vypsani popisku a udaju */
lcd.setCursor(0, 0);
lcd.write(byte(0));
lcd.print("as: ");
lcd.setCursor(0, 2);
lcd.setCursor(5, 0);
lcd.print(rtc.getTimeStr());
lcd.print("Den v t");
lcd.setCursor(7, 2);
lcd.write(byte(1));
lcd.setCursor(8, 2);
lcd.print("dnu: ");
lcd.setCursor(13, 2);
lcd.print(rtc.getDOWStr(FORMAT_SHORT));
lcd.setCursor(0, 1);
lcd.print("Datum: ");
lcd.setCursor(7, 1);
lcd.print(rtc.getDateStr());
}
void Nastaveni(void) {
/* zobrazeni nastaveni hodin */
lcd.clear();
t = rtc.getTime();
Hour = t.hour;
Min = t.min;
lcd.setCursor(0, 1);
lcd.write(byte(0));
lcd.setCursor(1, 1);
lcd.print("as:");
lcd.setCursor(4, 1);
lcd.print("Hod= ");
lcd.setCursor(9, 1);
lcd.print(Hour);
lcd.setCursor(10, 1);
lcd.print("Min= ");
lcd.setCursor(15, 1);
lcd.print(Min);
while (pset) {} // ceka na uvolneni tlacitka SET
delay(SWITCH); // osetruje zakmity
// smycka nastaveni hodin trva, dokud neni znovu stisknuto tlacitko SET
while (!pset) {
/* hodiny */
if (digitalRead(phour)) {
Hour++;
lcd.setCursor(9, 1);
lcd.print(Hour);
if (Hour > 23) {
Hour = 0;
lcd.setCursor(9, 1);
lcd.print("0 ");
}
delay(SPEED);
}
/* minuty */
if (digitalRead(pmin)) {
Min++;
lcd.setCursor(15, 1);
lcd.print(Min);
if (Min > 59) {
Min = 0;
lcd.setCursor(15, 1);
lcd.print("0 ");
}
delay(SPEED);
}
}
rtc.setTime(Hour, Min, 00);// ulozi nastavene hodnoty
// zobrazeni nastaveni budiku
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Bud");
lcd.setCursor(3, 0);
lcd.write(byte(2));
lcd.setCursor(4, 0);
lcd.print("k:");
lcd.setCursor(6, 0);
lcd.print("Hod= ");
lcd.setCursor(11, 0);
lcd.print(h);
lcd.setCursor(12, 0);
lcd.print("Min= ");
lcd.setCursor(16, 0);
lcd.print(m);
while (pset) {} // ceka na uvolneni tlacitka SET
delay(SWITCH); // osetruje zakmity
// smycka nastaveni budiku trva, dokud neni znovu stisknuto tlacitko SET
if (!pset) {
/* budik nastaveni hodiny */
if (digitalRead(phour)) {
h++;
lcd.setCursor(11, 0);
lcd.print(h);
if (h > 23) {
h = 0;
lcd.setCursor(11, 0);
lcd.print("0 ");
}
delay(SPEED);
}
/* budik nastaveni minuty */
if (digitalRead(pmin)) {
m++;
lcd.setCursor(16, 0);
lcd.print(m);
if (m > 59) {
m = 0;
lcd.setCursor(16, 0);
lcd.print("0 ");
}
delay(SPEED);
}
}
while (pset) {} // ceka na uvolneni tlacitka SET
delay(SWITCH); // osetruje zakmity tlacitka
//**************************************************************************
// smycka nastaveni datumu trva, dokud neni znovu stisknuto tlacitko SET
while (!pset) {
if (Year < 2019)Year = 2019;
// ... proste podobne jako predchozi
// ...
// ...
}
//**************************************************************************
rtc.setDate(Day, Month, Year);// ulozeni datumu
while (pset) {} // ceka na uvolneni tlacitka SET
delay(SWITCH); // osetruje zakmity tlacitka
lcd.clear();
DisplayPrepis();
}