W dawnych mikroproceorowych czasach określanie czasu było sporym problemem. Czas tyka ciągle a już mikroprocesor niekoniecznie. Wymyślono więc zegar na rękę dla mikroprocesora, który tyka bez przerwy. Ma bateryjkę i rezonator kwarcowy by tykać szybko i dokładnie. Ale kosztuje i zabiera miejsce (szczególnie bateryjka). No i jak się okazało w praktyce wcale nie jest taki dokładny.
Zmieniono więc ideę i od czasu wszechobecnego internetu za odmierzanie czasu odpowiada serwer (serwery) czasu. Wszystkie komputery, telefony a nawet zegarki z dostępem do internetu synchronizują swój wewnętrzny zegar z internetowym serwerem czasu. I choć producenci zegarków dla mikrokomputerów wciąż rają nam zakup układów RTC to od chwili gdy nasz ESP włączył się do międzygalaktycznej sieci możemy aktualny czas pobrać z serwera czasu NTP. Trzeba tylko dołączyć do naszego programu bibliotekę protokołu transmisji z takim serwerem (to jest UDP) i jakąś bibliotekę potrafiącą obrobić dane przesyłane przez serwer na bardziej przyjazną postać typu godzina/minuta/sekunda.
Skąd taki temat? W moim domowym systemie automatyki dostawcą zegara był stale działający serwer BLYNKa. Specjalny widget umożliwiał podjęcie określonych działań przez ESP w określonym czasie. W VIRTUINO IoT jest podobny widget ale zakładam iż aplikacja będzie łączyła się mikromodułem sporadycznie więc w takiej konfiguracji jest on nieprzydatny. Potrzebuję innego sposobu określenia czasu w mikroprocesorze a jak wspomniałem wcześniej dołożenie dodatkowego modułu RTC nie wchodzi w grę. Pozostaje tylko połączyć nasz ESP do serwera NTP i stamtąd pobrać aktualny czas.
Dla Arduino polecana jest biblioteka NTPClient. Zobaczymy jak taki zegar współpracuje z oprogramowaniem VIRTUINO IoT.
Na początek deklaracje dodatkowych bibliotek:
#include <ESP8266WiFi.h> // to już mamy w VIRTUINO
#include <NTPClient.h>
#include <WiFiUdp.h>
definiujemy klienta NTP
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org");
inicjalizujemy klienta w setup()
timeClient.begin();
// dopasowanie strefy czasowej
// GMT +1 = 3600
// GMT -1 = -3600
timeClient.setTimeOffset(0);
i pobieramy z serwera NTP aktualne dane - gdzieś w naszym programie
timeClient.update();
Teraz pozostaje już tylko odczytać aktualne ( w miarę) dane o czasie. W miarę gdyż nie należy zapominać o opóźnieniach wynikających z czasu łączenia się z serwerem i przetwarzania danych w ESP. Ale nie przekroczą one nigdy 1 sekundy co daje nam dokładność naszego zegara niedostępną dla większości układowych RTC. Z danych NTP odczytujemy aktualny czas i datę ale ja dla projektu potrzebuję czas i to z dokładnością do 1 minuty. Możemy odczytać czas w takim formacie
String formattedTime = timeClient.getFormattedTime();
Serial.print("Formatted Time: ");
Serial.println(formattedTime);
lub poszczególne jego elementy
int currentHour = timeClient.getHours();
Serial.print("Hour: ");
Serial.println(currentHour);
int currentMinute = timeClient.getMinutes();
Serial.print("Minutes: ");
Serial.println(currentMinute);
int currentSecond = timeClient.getSeconds();
Serial.print("Seconds: ");
Serial.println(currentSecond);
I w odpowiedzi widzimy piękny wydruk na monitorze
Formatted Time: 18:26:58
Hour: 18
Minutes: 26
Seconds: 58
I odczyt czasu działa bezbłędnie. I niech tak zostanie
Brak komentarzy:
Prześlij komentarz