Przekaźnik czasowy
Na początku nie sądziłem, że temat Arduino i zegara aż tak się rozwinie, że materiału będzie na dwie notki i parę projektów 😮 W tej części chciałem Wam przedstawić programy, które napisałem do sterowania wyjściem dwustanowym, czyli np. przekaźnikiem z wykorzystaniem zegara czasu rzeczywistego. Taki projekt przyda się przy kontroli oświetlenia, pompy, ogrzewania lub przy budowie automatycznego podajnika jedzenia dla kota (z tym ostatnim Jeremek chętnie się zapozna, możecie podsyłać swoje propozycje).
Zacznę oczywiście od małego wstępu teoretycznego zanim przejdę do szczegółów projektu 😉 Po co w ogóle jest ten RTC (Real Time Clock)? Niedawno pokazywałem sterownik nawilżacza oraz lampki do roślin zależnie od wschodu i zachodu słońca. Nie używałem tam żadnego RTC. Zastosowałem ESP8266, które było podłączone do sieci. Relacje czasowe były zaprogramowane poziom wyżej, na Home Assistant, więc sterownik tak naprawdę nie wiedział, która jest godzina. Mikrokontroler podłączony do sieci mógłby ściągać godzinę z serwera NTP, czyli takiego służącego tylko do pobierania czasu. Co w przypadku gdy nie mamy zasięgu sieci lub obawiamy się chwilowej utraty połączenia dla krytycznie ważnego sprzętu (np. wspomnianego podajnika jedzenia dla kota)? Niestety, mikrokontrolery są taktowane w specyficzny sposób – częstotliwości są tak przeliczane, że pomimo polecenia zliczania milisekund po jakimś czasie można zauważyć, że coś się nie zgadza. W dużym uproszczeniu, gdybyśmy zbudowali zegarek i oparli o te polecenia zliczanie czasu, zacząłby się spóźniać, a spóźnianie się to zły nawyk. Stąd konieczne jest podłączenie zegara czasu rzeczywistego, aby otrzymać dokładny odczyt. Dodatkowo dzięki temu, że RTC podtrzymujemy na zasilaniu bateryjnym nie musimy przy każdym włączeniu urządzenia ustawiać godziny.
Z pomysłów, które mi nadsyłacie, wybrałem prosty projekt, który używa RTC – zwykły przekaźnik sterowany czasem. Coś podobnego do zegara Findera, który kiedyś prezentowałem na blogu. Efekt możecie zobaczyć w filmie poniżej.
Kod oraz schemat znajdziecie tutaj.
Wyjście jest włączone od danej godziny do danej, jak na wykresie.
Niezmiernie mi miło, że zainteresowaliście się tym projektem i powstało kilka dodatkowych pomysłów co do niego. Opiszę tutaj jak przeprowadzić zaproponowane rozszerzenia.
Wszystko można także znaleźć na live streamach tutaj.
Wariant 1.
Dodanie kolejnego okresu w ciągu dnia, kiedy przekaźnik będzie włączony.
Na wzór tej częście kodu:
const DateTime m_start = DateTime(2000, 1, 1, 16, 48, 0); ///time when realy turn on
const DateTime m_stop = DateTime(2000, 1, 1, 16, 50, 0); ///time when realy turn off
dodajemy kolejne czasy start i stop, np.
const DateTime m_start_2 = DateTime(2000, 1, 1, 18, 48, 0); ///< time when realy turn on
const DateTime m_stop_2 = DateTime(2000, 1, 1, 19, 20, 0); ///< time when realy turn off
należy także zmodyfikować warunki:
static bool is_turn_on = false;
if (is_in_range(now, m_start, m_stop) && !is_turn_on)
{
Serial.println("Start");
digitalWrite(m_output_pin, HIGH);
is_turn_on = true;
}
else if (is_in_range(now, m_start_2, m_stop_2) && !is_turn_on)
{
Serial.println("Start");
digitalWrite(m_output_pin, HIGH);
is_turn_on = true;
}
else if (!is_in_range(now, m_start, m_stop) && !is_in_range(now, m_start_2, m_stop_2) && is_turn_on)
{
Serial.println("Stop");
digitalWrite(m_output_pin, LOW);
is_turn_on = false;
}
Może to nie wygląda najlepiej, a jeśli miałoby się to dalej rozbudowywa, to po pierwsze, warto te godziny start i stop wrzucić w jakąś tablicę, a po drugie, skorzystać może z maszyny stanów, którą prezentowałem tutaj. Znajdziecie tam też trochę o millis używanej także w tym projekcie 😉
Wariant 2.
Dodanie drugiego przekaźnika z innymi godzinami włączenia i wyłączenia.
Także potrzebujemy dodatkowego start i stop:
const DateTime m_start_2 = DateTime(2000, 1, 1, 18, 48, 0); ///< time when realy turn on
const DateTime m_stop_2 = DateTime(2000, 1, 1, 19, 20, 0); ///< time when realy turn off
ale będzie potrzebny także dodatkowy pin:
const byte m_output_pin_2 = 3; ///< pin connected to relay
a warunki będą wyglądały tak:
static bool is_turn_on = false;
if (is_in_range(now, m_start, m_stop) && !is_turn_on)
{
Serial.println("Start");
digitalWrite(m_output_pin, HIGH);
is_turn_on = true;
}
else if (!is_in_range(now, m_start, m_stop) && is_turn_on)
{
Serial.println("Stop");
digitalWrite(m_output_pin, LOW);
is_turn_on = false;
}
static bool is_turn_on_2 = false;
if (is_in_range(now, m_start_2, m_stop_2) && !is_turn_on_2)
{
Serial.println("Start 2");
digitalWrite(m_output_pin_2, HIGH);
is_turn_on_2 = true;
}
else if (!is_in_range(now, m_start_2, m_stop_2) && is_turn_on_2)
{
Serial.println("Stop 2");
digitalWrite(m_output_pin_2, LOW);
is_turn_on_2 = false;
}
Porada dotycząca czystości taka sama jak wcześniej d: Ale to zostawiam już Wam.
Przekaźnik włączany cyklicznie
Projekt potrzebował troszkę większej przebudowy, aby wyjście włączało się co dany okres, na zadany czas.
Ten projekt znajdziecie jako osobny na repozytorium tutaj.
Urządzenie można byłoby zbudować trochę inaczej, ponieważ większość RTC posiada funkcję budzika. Wtedy ustawiamy godzinę i RTC wystawi nam odpowiedni stan na pinie, kiedy to pora wstać, włączyć przekaźnik czy dać jeść kotu. Jednak podejście ze stałym odczytem i porównywaniem czasu, które tutaj zastosowałem, łatwiej będzie użyć w programach, które pokażę w drugiej części 😉
Nietypowo i po raz pierwszy dołączyłem konfigurację do formatowania .clang-format. Używałem tego narzędzia już wcześniej w projektach komercyjnych, ale to nowość w programach, które prezentuję na blogu.
Opis, co i jak z tym formatowaniem, zamieściłem także w ReadMe, które staram się teraz trochę lepiej prowadzić. Znajdziecie tam m.in. schematy, informacje o konfiguracji czy przygotowaniu środowiska.
Z wiadomości od Was wiem, że przydatne byłoby urządzenie które zależnie od godziny będzie sterowało wyjściem PWM i je właśnie opiszę w drugiej części. Dodatkowo godziny działania będą szczególne – wschód i zachód słóńca, które są codziennie zmienne!
Jeśli potrzebujecie jeszcze czegoś z przekaźnikiem czasowym, co można zamknąć w obudowie lub dodać ekran i ustawianie godzin, piszcie 🙂 Przy okazji zachęcam także do wsparcia kanału 😉