[030] Budzik

[030] Budzik

Projekty programistyczne mają do siebie to, że po przerwie, nawet kilkudniowej, wymagają ponownego wdrożenia się. Zatem jeśli ktoś teraz będzie się nieco gubił, polecam zajrzeć do poprzednich artykułów. Czas zatem ponowne przyjrzeć się szkicowi. Ponieważ elementów ustawiania minut i godzin będziemy używać dwukrotnie – do ustawiania czasu bieżącego oraz czasu budzenia, zaczniemy od wydzielenia tego bloku i zrobienia z niego funkcji.


void regulujCzas() {                       // Funkcja ta analizuje pstryczki i zmienia wartości godzin i minut.
  if (digitalRead(pstryczekPlus) == LOW) { // Jeśli pstryczekPlus jest wciśnięty...
    zwiekszCzas();                         // Zwiększ wartość czasu.
    lcd.home();                            // Ustaw kursor na początku.
    wyswietlCzas();                        // Wyświetl go na ekranie.
    delay(opoznienieDlugie);               // Wprowadź opóźnienie.
  }
  while (digitalRead(pstryczekPlus) == LOW) { // I powtarzaj tę procedurę, tylko szybciej.
    zwiekszCzas();
    lcd.home();
    wyswietlCzas();
    delay(opoznienieKrotkie);
  }
  if (digitalRead(pstryczekMinus) == LOW) { // Jeśli pstryczekMinus jest wciśnięty...
    zmniejszCzas();                         // Zmniejsz wartość czasu.
    lcd.home();                             // Ustaw kursor na początku.
    wyswietlCzas();                         // Wyświetl go na ekranie.
    delay(opoznienieDlugie);                // Wprowadź opóźnienie.
  }
  while (digitalRead(pstryczekMinus) == LOW) { // I powtarzaj tę procedurę, tylko szybciej.
    zmniejszCzas();
    lcd.home();
    wyswietlCzas();
    delay(opoznienieKrotkie);
  }
}

Dlaczego nie zrobiliśmy tego od razu? Dobrym zwyczajem informatycznym jest minimalizm. Jeśli czegoś używa się raz, niechaj będzie to siedzieć w treści programu. Tworzenie funkcji tylko po to, by uzyskać lepszą czytelność programu, ma jak najbardziej sens w przypadku dużych projektów. Ale tutaj byłoby sztuką dla sztuki. Zatem blok odpowiedzialny za ustawianie czasu, który wcześniej znajdował się w pętli głównej, przenosimy do nowo utworzonej funkcji o nazwie regulujCzas. Oczywiście w oryginalnym miejscu tworzymy teraz odwołanie do tej funkcji. Po każdej tak dużej modyfikacji programu należy obowiązkowo skompilować go, załadować do Arduino i sprawdzić czy całość zachowuje się tak samo jak przed zmianami.

Teraz czas przyjąć pewne założenia co do interfejsu, czyli sposobu regulacji czasu oraz budzika. Metod jest wiele, ja proponuję nieco kontrowersyjną, lecz zastosowałem ją pierwszy raz jeszcze 30 lat temu, na podobnym urządzeniu zbudowanym na Z80 i okazała się być użyteczna. Otóż czas będziemy mogli ustawić tylko raz, zaraz po resecie. Potem już nie będzie to możliwe, będzie można tylko ustawiać czas budzenia. Oczywiście to jest tylko propozycja.

No dobrze, a jak się zegar będzie spieszył albo spóźniał? Temu da się zaradzić programowo i z pewnością o tym kiedyś powiem. A jak będzie zmiana czasu z zimowego na letni albo odwrotnie? Ależ to nie problem, wystarczy na chwilę odłączyć zasilanie albo zresetować system.

Zatem do roboty. Wobec powyższych założeń ustawianie czasu bieżącego przesuniemy do pętli setup, bo tam z założenia wykonują się rzeczy jednorazowo. Należy tylko pamiętać, żeby ten kod wstawić dopiero po wszelkich deklaracjach, które tam sobie dotąd siedziały.

void setup() {
  
  while (digitalRead(pstryczekZmien) == HIGH) { // Tu zaczyna się pętla ustawiania czasu.
    regulujCzas();                              // Idź do funkcji ustawiającej czas pstryczkami.
  }
  setTime(godzina, minuta, 00, 01, 01, 2000); // Ustaw bieżący czas zgodnie z ustawionym,
  budzikWylaczony();                          // Rysuj komunikat wyłączonego budzika.
  delay(opoznienieDlugie);                    // Wprowadź opóźnienie.
}

Kompilujemy kod i… nic nie widać. Jednak gdy naciśniemy któryś z przycisków, zegar ożywa. Zatem problem polega na tym, że zaraz po resecie wyświetlacz jest pusty i czeka na nasze działania, gdy wcześniej zaczynał od wyświetlenia czasu. Naprawmy to, ale z głową. Moglibyśmy po prostu uzupełnić brakujące elementy wyświetlające czas, jeszcze nieustawiony, lecz ładniej będzie wykorzystać możliwości wyświetlacza i wyświetlić stosowny komunikat. Napis Ustaw czas będzie akurat tą informacją, której tu potrzeba i instrukcję, która za niego odpowiada należy umieścić jeszcze przed pętlą while.

lcd.print(F(" 0:00 Ustaw czas")); // Rysuj stosowny komunikat.

Po zatwierdzeniu czasu należy zastąpić napis Ustaw czas jakimś sensownym, bo inaczej resztki napisu będą widoczne na prawo od wyświetlanego czasu. Wyprzedzając fakty, stworzymy funkcję, która narysuje grafikę, oznaczającą, że budzik nie jest aktywny. Nazwiemy ją budzikWylaczony.

void budzikWylaczony() {       // Rysuj komunikat wyłączonego budzika.
  lcd.setCursor(5, 0);         // Ustawy kursor na pozycji ósmej.
  lcd.print(F("      --:--")); // Rysuj stosowny komunikat.
}

Jak widać, rysowanie zaczniemy od pozycji piątej (lcd.setCursor(5, 0), ponieważ na wcześniejszych będą się znajdować godziny, dwukropek i minuty. Grafika oznaczająca „wyłączony budzik” będzie się składać z poziomych kresek przedzielonych dwukropkiem (--:--) Wróćmy teraz do miejsca, w którym dawniej ustawialiśmy czas bieżący, nastąpi tutaj dużo zmian. Ale zanim cokolwiek tam wymajstrujemy, powołamy do życia dwie kolejne zmienne globalne. Wszak pojawi się teraz pojęcie budzika, czyli godzina i minuta, w której ów budzik powinien zadziałać. Nazwiemy je godzinaBudzika i minutaBudzika.

W miejscu, w którym wcześniej ustawialiśmy czas bieżący, teraz zbędziemy ustawiać czas budzika. Zatem najpierw musimy załadować do naszych zmiennych godzina i minuta już nie bieżący czas, a ostatnio ustawiony czas budzika.

godzina = godzinaBudzika;    // Ładuj do zmiennej godzin minutę budzenia.
minuta = minutaBudzika;      // Ładuj do zmiennej minut godzinę budzenia.
lcd.home();                  // Ustaw kursor na początku.
wyswietlCzas();              // Wyświetl czas budzenia.
lcd.print(F(" Ust.budzik")); // Rysuj stosowny komunikat.

Możemy go teraz już wyświetlić wraz ze stosownym komunikatem (Ust.budzik). Pojemność wyświetlacza zmusi nas tutaj do użycia skrótu. Jeśli ktoś woli język angielski, Set Alarm zmieści się w całości.

delay(opoznienieDlugie);                      // Wprowadź opóźnienie dla stabilnych odczytów pstryczka.
while (digitalRead(pstryczekZmien) == LOW) {} // Czekaj, aż zostanie puszczony.
while (digitalRead(pstryczekZmien) == HIGH) { // Tu zaczyna się pętla ustawiania czasu budzenia.
  regulujCzas();                              // Idź do funkcji ustawiającej czas pstryczkami.
}
godzinaBudzika = godzina;    // Ładuj do zmiennej godzin budzenia ustawioną godzinę.
minutaBudzika = minuta;      // Ładuj do zmiennej minut budzenia ustawioną minutę.
lcd.home();                  // Ustaw kursor na początku.
lcd.print(F("Wlaczony o ")); // Rysuj stosowny komunikat.
wyswietlCzas();              // Wyświetl czas budzenia.

Regulacja pozostaje jaką była, ale po wyjściu z tej procedury nie będziemy już ustawiać czasu bieżącego, a czas budzenia. Na końcu pozostaje wyświetlić komunikat o ustawieniu budzika (Wlaczony o ) i wyświetlić czas budzenia. I tu mamy mały problem. Funkcja wyswietlCzas zawierała polecenie ustawiania kursora na początku (lcd.home). Jak już uważny czytelnik zauważył, tę linię usunąłem z funkcji wyswietlCzas, a następnie wstawiłem ją tuż przed odwołaniem się do niej, w każdym miejscu programu. Troszkę od tego przybędzie kodu, ale tak będzie najprościej.

Na tym etapie program działa jak powinien. Zegar po ustawieniu chodzi sobie swoim tempem, a budzik wyświetla się na końcu i można go w każdej chwili ustawić. Ale nie można go deaktywować. Musimy jeszcze dopisać kod, który obsłuży wyłączanie budzenia. Poznamy teraz nowy typ zmiennych, najskromniejszy ze wszystkich. Może bowiem przybierać tylko dwie wartości: fałsz albo prawda, jak również mogą być reprezentowane cyframi 0 i 1. Pozostańmy zatem przy nomenklaturze Arduino i będziemy używać tych pierwszych określeń. Typ zmiennej nazywa się bool i zwykle służy jako przełącznik. U nas będzie przełączać aktywność budzika, dlatego tak właśnie ją nazwałem: budzik. Od razu na początek ustawmy ją w pozycji fałszu, co będzie oznaczać, że budzik jest wyłączony.

bool budzik = false; // Stan budzika: false - nieaktywny, true - aktywny.

Musimy teraz pogmerać we fragmencie, który dotąd zawsze umożliwiał regulacje budzika. Wprowadzimy teraz funkcję if, która w zależności od naszej nowo wprowadzonej zmiennej – przełącznika budzik, będzie wykonywać jeden z dwóch fragmentów kodu. I tak jeśli przełącznik miał wartość true, czyli budzik był aktywny, deaktywujemy go, ustawiając przełącznik w pozycji false. Następnie narysujemy kreseczki oraz komunikat Wylaczony.

if (budzik == true) {          // Jeśli budzik był aktywny...
  budzik = false;              // To go deaktywuj.
  budzikWylaczony();           // Narysuj komunikat wyłączonego budzika.
  lcd.home();                  // Ustaw kursor na początku.
  lcd.print(F("Wylaczony")); } // Rysuj stosowny komunikat.

Natomiast gdy budzik był nieaktywny, aktywujemy go, a następnie wykonujemy nasz stary kod ustawiania godzin i minut budzika. Na końcu wyświetlamy komunikat Wlaczony o i ustawioną godzinę budzenia.

else {                                        // A jeśli budzik był nieaktywny...
budzik = true;                                // To go aktywuj.
godzina = godzinaBudzika;                     // Ładuj do zmiennej godzin minutę budzenia.
minuta = minutaBudzika;                       // Ładuj do zmiennej minut godzinę budzenia.
lcd.home();                                   // Ustaw kursor na początku.
wyswietlCzas();                               // Wyświetl czas budzenia.
lcd.print(F(" Ust.budzik"));                  // Rysuj stosowny komunikat.
delay(opoznienieDlugie);                      // Wprowadź opóźnienie dla stabilnych odczytów pstryczka.
while (digitalRead(pstryczekZmien) == LOW) {} // Czekaj, aż zostanie puszczony.
while (digitalRead(pstryczekZmien) == HIGH) { // Tu zaczyna się pętla ustawiania czasu budzenia.
  regulujCzas();                              // Idź do funkcji ustawiającej czas pstryczkami.
}
godzinaBudzika = godzina;    // Ładuj do zmiennej godzin budzenia ustawioną godzinę.
minutaBudzika = minuta;      // Ładuj do zmiennej minut budzenia ustawioną minutę.
lcd.home();                  // Ustaw kursor na początku.
lcd.print(F("Wlaczony o ")); // Rysuj stosowny komunikat.
wyswietlCzas(); }            // Wyświetl czas budzenia.

Po wyjściu z obu fragmentów kodu należy jeszcze zaczekać, by wyświetlony komunikat chwilę się utrzymał. Zastosowałem tutaj pewien nowy sposób na zwiększenie pauzy, mianowicie opóźnienie stosowane dotąd pomnożyłem trzykrotnie. Akurat na tak długo, by przeczytać komunikat. Dzięki temu jeśli ktoś ustawi sobie współczynniki opóźnień na nieco większą ociężałość interfejsu, dostanie proporcjonalne wydłużenie także tego czasu.

delay(opoznienieDlugie * 3);                  // Wprowadź dłuższe opóźnienie.
while (digitalRead(pstryczekZmien) == LOW) {} // Czekaj aż przycisk zostanie puszczony.

Trzeba jeszcze wyczyścić fragmenty wyświetlacza i można powrócić do głównej pętli.

lcd.setCursor(8, 0); // Ustaw kursor na pozycji ósmej.
lcd.print(F("  "));  // Wyczyść wyświetlacz ze śmieci.

Pozostało nam tylko napisać kod, który w chwili ustawionej przez nas włączy alarm. Ale co będzie nas alarmować? Poznamy nowe urządzenie: buzzer albo brzęczyk.

To okrągła najczęściej blaszka z naklejonym piezzokryształem, na którym napylono metal. Gdy przyłączyć napięcie między blaszkę, a metalową okładzinę, piezzokryszał lekko się odchyli. Gdy podłączymy napięcie zmienne, kryształ będzie się odchylał w takt tych zmian. Podłączmy sobie zatem nasz brzęczyk między masę, a pin jedenasty. Poznamy teraz kolejną możliwość Arduino. W tym celu zadeklarujemy sobie port 11 jako buzzer. W sekcji setup trzeba także określić port. Do tej pory pracowaliśmy z wejściami. Brzęczyk jest urządzeniem wyjścia, zatem wpisujemy tutaj:

pinMode(buzzer, OUTPUT); // Deklaruj port buzzera jako wyjście.

Pozostał ostatni krok. Decydujemy, że sygnał budzenia będzie słychać przez minutę, wtedy gdy zrównają się zarówno godziny zegara i budzika oraz minuty, a także budzik będzie aktywny. Stąd tak rozbudowany warunek.

if (godzinaBudzika == godzina && minutaBudzika == minuta && budzik == true) {
  analogWrite (buzzer, 128); // Jeśli zrównał się czas bieżący z czasem budzenia, włącz pisk...
  delay(opoznienieKrotkie);  // zaczekaj chwilę...
  analogWrite (buzzer, 0);   // wyłącz pisk...
  delay(opoznienieKrotkie);  // i ponownie zaczekaj chwilę.
}

Podwójny znak && łączy warunki w logiczną koniunkcję, czyli w zdanie prawdziwe tylko wtedy, gdy zachodzi każdy z warunków. Do wygenerowania alarmu użyjemy nowej funkcji. Otóż kilka z portów Arduino może generować przebiegi przemienne poza świadomością programu, po aktywacji bloków, które się tym zajmują. Częstotliwość tego przebiegu może być zmieniana, ale domyślna wartość około 500 Hz będzie nas satysfakcjonować, więc pozostawimy ją w spokoju. Możliwość ta służy to ciekawszym rzeczom niż proste piszczenie, jednak w tym artykule poprzestańmy na tym. Funkcja analogWrite (buzzer, 128) aktywuje generację przebiegu, a liczba 128 oznacza, że będzie on symetryczny, czyli najgłośniejszy. Po chwili należy nasz pisk wyłączyć, deklarując przebieg o wypełnieniu zerowym (analogWrite (buzzer, 0), czyli ciszę. Dzięki funkcjom opóźniającym, nie będziemy słyszeć długiego pisku, lecz przerywany, który w funkcji budzika sprawdza się lepiej. Aby wyłączyć sygnał budzenia, należy wcisnąć środkowy przycisk.

I to już wszystko. Mamy gotowe urządzenie: zegar z budzikiem. I choć pracuje poprawnie, a do kodu trudno się przyczepić, nie satysfakcjonuje mnie on do końca z jednego powodu. Mianowicie program ten powstał w idei „pączkowania”. Polega to na tym, że najpierw napisaliśmy sam zegar, potem przekonstruowaliśmy kod i dopisaliśmy część odpowiedzialną za budzenie. Tak oczywiście można, lecz to nie jest droga optymalna. Programy doskonałe mają swój algorytm dopracowany zanim powstanie choćby jedna linia kodu. I tak należałoby tu zacząć, ale celem nie było tu samo urządzenie, a przyglądnięcie się procesowi jego powstawania i modyfikacji. Poza tym wypadałoby także zmienić wyświetlacz na jednowierszowy albo dopisać kod zarządzający dolną jego częścią, gdyż na razie połowa się marnuje. Tak więc do zegara powrócimy, ale za jakiś czas. Na koniec już prezentuję kompletny i ostateczny kod programu, do którego odwoływałem się w trzech częściach artykułu o zegarze i budziku.

#include<LiquidCrystal.h>            // To jest biblioteka obsługi wyświetlacza.
#include<TimeLib.h>                  // To jest biblioteka obsługi zegara.
LiquidCrystal lcd(2, 3, 4, 5, 6, 7); // Tutaj dostarcza się bibliotece obsługi wyświetlacza wiedzy, gdzie co jest podłączone.
const byte pstryczekMinus = 8;       // Adres pstryczka zmniejszającego wartości.
const byte pstryczekZmien = 9;       // Adres pstryczka ustawień.
const byte pstryczekPlus = 10;       // Adres pstryczka zwiększającego wartości.
byte godzina;                        // Zmienna godzin - dla ustawień i wyświetlania.
byte minuta;                         // Zmienna minut - jak wyżej.
byte sekunda;                        // Zmienna sekund - jak wyżej.
const byte opoznienieDlugie = 250;   // Czas opóźnienia klawiatury.
const byte opoznienieKrotkie = 25;   // Czas autorepetycji klawiatury.
const byte buzzer = 11;              // Adres buzzera.
byte godzinaBudzika;                 // Zmienna godziny budzika - dla ustawień i wyświelania.
byte minutaBudzika;                  // Jak wyżej, tylko dla minut.
bool budzik = false;                 // Stan budzika: false - nieaktywny, true - aktywny.
void setup() {
  lcd.begin(16, 2);                      // Inicjujemy wyświetlacz, powiadamiając go o ilości kolumn i wierszy.
  pinMode(pstryczekMinus, INPUT_PULLUP); // Deklarujemy linie pstryczków jako wejścia podciągnięte wewnętrznie do wysokiego stanu.
  pinMode(pstryczekZmien, INPUT_PULLUP);
  pinMode(pstryczekPlus, INPUT_PULLUP);
  pinMode(buzzer, OUTPUT);                      // Deklaruj port buzzera jako wyjście.
  lcd.print(F(" 0:00 Ustaw czas"));             // Rysuj stosowny komunikat.
  while (digitalRead(pstryczekZmien) == HIGH) { // Tu zaczyna się pętla ustawiania czasu.
    regulujCzas();                              // Idź do funkcji ustawiającej czas pstryczkami.
  }
  setTime(godzina, minuta, 00, 01, 01, 2000); // Ustaw bieżący czas zgodnie z ustawionym,
  budzikWylaczony();                          // Rysuj komunikat wyłączonego budzika.
  delay(opoznienieDlugie);                    // Wprowadź opóźnienie.
}
void loop() {
  while (digitalRead(pstryczekZmien) == HIGH) { // Powtarzamy poniższe działania, dopóki nie zostanie wciśnięty pstryczekZmien.
    time_t czasOdczytany = now();               // Zapisz bieżący czas do zmiennej czasOdczytany.
    godzina = hour(czasOdczytany);              // Nadajemy zmiennej godzina wartość godzin.
    minuta = minute(czasOdczytany);             // Jak wyżej, tylko dla minut.
    sekunda = second(czasOdczytany);            // Jak wyżej, tylko dla sekund.
    lcd.home();                                 // Ustaw kursor na początku.
    wyswietlCzas();                             // Wyświetlamy godziny, dwukropek i minuty...
    wyswietlSekundy();                          // oraz dwukropek i sekundy.
    if (godzinaBudzika == godzina && minutaBudzika == minuta && budzik == true) {
      analogWrite (buzzer, 128); // Jeśli zrównał się czas bieżący z czasem budzenia, włącz pisk...
      delay(opoznienieKrotkie);  // zaczekaj chwilę...
      analogWrite (buzzer, 0);   // wyłącz pisk...
      delay(opoznienieKrotkie);  // i ponownie zaczekaj chwilę.
    }
  }
  lcd.clear();                                    // Wciśnięto przycisk ustawień więc czyścimy wyświetlacz i ustawiamy kursor na początku.
  if (budzik == true) {                           // Jeśli budzik był aktywny...
    budzik = false;                               // To go deaktywuj.
    budzikWylaczony();                            // Narysuj komunikat wyłączonego budzika.
    lcd.home();                                   // Ustaw kursor na początku.
    lcd.print(F("Wylaczony"));                    // Rysuj stosowny komunikat.
  } else {                                        // A jeśli budzik był nieaktywny...
    budzik = true;                                // To go aktywuj.
    godzina = godzinaBudzika;                     // Ładuj do zmiennej godzin minutę budzenia.
    minuta = minutaBudzika;                       // Ładuj do zmiennej minut godzinę budzenia.
    lcd.home();                                   // Ustaw kursor na początku.
    wyswietlCzas();                               // Wyświetl czas budzenia.
    lcd.print(F(" Ust.budzik"));                  // Rysuj stosowny komunikat.
    delay(opoznienieDlugie);                      // Wprowadź opóźnienie dla stabilnych odczytów pstryczka.
    while (digitalRead(pstryczekZmien) == LOW) {} // Czekaj, aż zostanie puszczony.
    while (digitalRead(pstryczekZmien) == HIGH) { // Tu zaczyna się pętla ustawiania czasu budzenia.
      regulujCzas();                              // Idź do funkcji ustawiającej czas pstryczkami.
    }
    godzinaBudzika = godzina;    // Ładuj do zmiennej godzin budzenia ustawioną godzinę.
    minutaBudzika = minuta;      // Ładuj do zmiennej minut budzenia ustawioną minutę.
    lcd.home();                  // Ustaw kursor na początku.
    lcd.print(F("Wlaczony o ")); // Rysuj stosowny komunikat.
    wyswietlCzas();              // Wyświetl czas budzenia.
  }
  delay(opoznienieDlugie * 3);                  // Wprowadź dłuższe opóźnienie.
  while (digitalRead(pstryczekZmien) == LOW) {} // Czekaj aż przycisk zostanie puszczony.
  lcd.setCursor(8, 0);                          // Ustaw kursor na pozycji ósmej.
  lcd.print(F("  "));                           // Wyczyść wyświetlacz ze śmieci.
}
void budzikWylaczony() {       // Rysuj komunikat wyłączonego budzika.
  lcd.setCursor(5, 0);         // Ustawy kursor na pozycji ósmej.
  lcd.print(F("      --:--")); // Rysuj stosowny komunikat.
}
void regulujCzas() {                       // Funkcja ta analizuje pstryczki i zmienia wartości godzin i minut.
  if (digitalRead(pstryczekPlus) == LOW) { // Jeśli pstryczekPlus jest wciśnięty...
    zwiekszCzas();                         // Zwiększ wartość czasu.
    lcd.home();                            // Ustaw kursor na początku.
    wyswietlCzas();                        // Wyświetl go na ekranie.
    delay(opoznienieDlugie);               // Wprowadź opóźnienie.
  }
  while (digitalRead(pstryczekPlus) == LOW) { // I powtarzaj tę procedurę, tylko szybciej.
    zwiekszCzas();
    lcd.home();
    wyswietlCzas();
    delay(opoznienieKrotkie);
  }
  if (digitalRead(pstryczekMinus) == LOW) { // Jeśli pstryczekMinus jest wciśnięty...
    zmniejszCzas();                         // Zmniejsz wartość czasu.
    lcd.home();                             // Ustaw kursor na początku.
    wyswietlCzas();                         // Wyświetl go na ekranie.
    delay(opoznienieDlugie);                // Wprowadź opóźnienie.
  }
  while (digitalRead(pstryczekMinus) == LOW) { // I powtarzaj tę procedurę, tylko szybciej.
    zmniejszCzas();
    lcd.home();
    wyswietlCzas();
    delay(opoznienieKrotkie);
  }
}
void zwiekszCzas() {     // Funkcja ta zwiększa czas o minutę.
  minuta++;              // Zwiększ liczbę minut.
  if (minuta == 60) {    // Jeśli osiągnięto wartość minut równą 60 to...
    minuta = 0;          // zeruj liczbę minut,
    godzina++;           // zwiększ liczbę godzin.
    if (godzina == 24) { // Jeśli osiągnięto wartość godzin równą 24 to...
      godzina = 0;       // zeruj liczbę godzin.
    }
  }
}
void zmniejszCzas() {     // Funkcja ta zmniejsza czas o minutę.
  minuta--;               // Zmniejsz liczbę minut.
  if (minuta == 255) {    // Jeśli osiągnięto wartość minut równą 255 to...
    minuta = 59;          // ustaw liczbę minut równą 59,
    godzina--;            // zmniejsz liczbę godzin.
    if (godzina == 255) { // Jeśli osiągnięto wartość godzin równą 255 to...
      godzina = 23;       // Ustaw liczbę godzin równą 23
    }
  }
}
void wyswietlCzas() {  // Podprogram wyświetla godziny, dwukropek i minuty.
  if (godzina < 10) {  // Jeśli liczba godzin jest niższa od 10 to...
    lcd.print(F(" ")); // Rysuj dodatkową spację.
  }
  lcd.print(godzina);  // Rysuj liczbę godzin.
  lcd.print(F(":"));   // Rysuj dwukropek.
  if (minuta < 10) {   // Jeśli liczba minut jest niższa od 10 to...
    lcd.print(F("0")); // Rysuj dodatkowe zero.
  }
  lcd.print(minuta); // Rysuj liczbę minut.
}
void wyswietlSekundy() { // Podprogram wyświetla dwukropek i sekundy.
  lcd.print(F(":"));     // Rysuj dwukropek.
  if (sekunda < 10) {    // Jeśli liczba sekund jest niższa od 10 to...
    lcd.print(F("0"));   // Rysuj dodatkowe zero.
  }
  lcd.print(sekunda); // Rysuj liczbę sekund.
}

Powiązane tematy

Płytka edukacyjna TME-EDU-ARD-2Płytka edukacyjna TME-EDU-ARD-2Sprawdź tutaj

Przeczytaj również

Nasi partnerzy

TMETech Master EventTME EducationPoweredby
Copyright © 2025 arduino.pl