W dzisiejszych czasach, gdy inteligentne urządzenia stają się coraz bardziej popularne, wyobraź sobie, że masz inteligentny zegar, który nie tylko pokazuje dokładny czas, ale także oferuje wiele dodatkowych funkcji. Właśnie taki zegar stworzyłem, wykorzystując platformę ESP32 oraz potężne możliwości programowania w Micropythonie.

W tym artykule przedstawię Ci mój inteligentny zegar, który automatycznie łączy się z Internetem, synchronizuje czas, wyświetla cytat co 20 minut, odczytuje temperaturę i wilgotność otoczenia oraz dostosowuje jasność podświetlenia do natężenia światła. Czy jesteś gotowy na nową erę zegarów?

SmartClock V2

Funkcje inteligentnego zegara

Inteligentny zegar składa się z następujących elementów:

Podstawowe funkcje zegara

  • Wyświetlanie godziny: Mój inteligentny zegar oparty na ESP32 wykorzystuje 8 połączonych ze sobą wyświetlaczy matrix LED 8×8 MAX7219, aby pokazywać godzinę w czytelny sposób.
  • Łączność internetowa i zarządzanie zegarem: Po włączeniu zasilania, inteligentny zegar tworzy punkt dostępu WiFi. Umożliwia to połączenie się z nim przez urządzenie mobilne lub komputer. Wystarczy połączyć się z zegarem i otworzyć w przeglądarce adres http://192.168.4.1/. Na tej stronie pojawi się prosty menadżer WiFi, który umożliwia wybór sieci, z którą zegar ma się połączyć. Dzięki temu można łatwo skonfigurować połączenie z domową siecią WiFi.
  • Automatyczna synchronizacja czasu: Po pomyślnym połączeniu z Internetem, inteligentny zegar automatycznie synchronizuje czas z serwerem NTP (Network Time Protocol). Oznacza to, że zawsze będzie wyświetlać dokładną informację o czasie, bez konieczności ręcznego ustawiania zegara.
  • Inteligentne dostosowanie do czasu letniego i zimowego: Mój inteligentny zegar sam wie, kiedy następuje zmiana czasu. Dzięki wbudowanej logice i synchronizacji z serwerami czasu, zegar automatycznie dostosowuje się do zmiany czasu letniego i zimowego, co pozwala Ci cieszyć się niezakłóconą i precyzyjną informacją o czasie bez konieczności ręcznego dostosowywania zegara.

Dodatkowe funkcje

  • Cytaty jako inspirujące dodatki: Chciałem, aby mój inteligentny zegar nie tylko informował o czasie, ale także dostarczał dodatkową wartość. Dlatego dodałem funkcję wyświetlania cytatów co 20 minut. Korzystając z prostego menadżera na stronie konfiguracyjnej zegara, można dodać własne cytaty do bazy danych zegara. Cytaty te będą rotować co 20 minut, dostarczając inspirujące myśli i pozytywne przesłania w trakcie dnia.
  • Odczyt temperatury i wilgotności otoczenia: Inteligentny zegar, wyposażony w czujnik AHT10, odczytuje temperaturę i wilgotność otoczenia. Co 5 minut zegar automatycznie aktualizuje te wartości i wyświetla je na wyświetlaczu. Dzięki temu zawsze mam na wyciągnięcie ręki informacje o aktualnych warunkach atmosferycznych w swoim otoczeniu.
  • Automatyczna regulacja jasności podświetlenia: Zegar jest również wyposażony w funkcję automatycznej regulacji jasności podświetlenia. Wykorzystując fotorezystor, zegar mierzy natężenie światła w otoczeniu i dostosowuje jasność podświetlenia, aby zapewnić optymalne warunki czytelności. To oznacza, że niezależnie od tego, czy pomieszczeniu jest ciemno czy słonecznie, inteligentny zegar dostosuje się automatycznie, zapewniając komfortowe korzystanie.

Koszt projektu

Łączna kwota, którą wydałem na podzespoły wyniosła około 100 zł. Składa się na nią zakup dwóch modułów MAX7219 Matryca wyświetlacz LED 32×8, każdy kosztujący około 30 zł, moduł ESP32-DevKitC-32U o wartości około 32 zł oraz czujnik AHT10, który nabyłem za około 10 zł. Pozostałe elementy, które już posiadałem, nie miały znaczącego wpływu na końcowy wydatek.

Szczegóły techniczne

Hardware

Jako, że w miejscu, w którym chciałem żeby stał zegar jest słaby zasięg wifi, jako główny układ urządzenia wybrałem ESP32-DevKitC-32U. Posiada on złącze U.FL dzięki czemu można do niego podłączyć zewnętrzną antenę.

Do odczytu temperatury użyłem układu: AHT10, to wysokiej jakości czujnik temperatury i wilgotności. Oparty jest na technologii CMOS i zapewnia precyzyjne odczyty parametrów środowiskowych.

Pomiar natężenia światła wykonywany jest za pomocą fotorezystora, który połączony szeregowo z rezystorem tworzy dzielnik napięcia. Im jest wyższe natężenie światła tym, wyższe staje się napięcie na dzielniku. Napięcie to jest następnie mierzone za pomocą ADC (przetwornika analogowo-cyfrowego) mikrokontrolera.

Zegar zasilany jest przy pomocy portu micro usb wbudowanego w mikrokontroler. Przy napięciu z ładowarki USB 5.07V pobór prądu wynosi ok. 230mA, a gdy wyłączymy wyświetlacz: 110mA.

Software

Zmiana czasu letni/zimowy

Synchronizacja czasu z serwerem wykonywana jest co jedną minutę z użyciem standardowej funkcji w micropythonie: settime(). Zmiana czasu letni/zimowy okazała się być dużo większym wyzwaniem. Żeby to osiągnąć napisałem 2 funkcje:

#Check week day
def checkWday(year, month, day):
    a = (14 - month) // 12
    y = year - a
    m = month + 12 * a - 2

    wday = (day + y + y // 4 - y // 100 + y // 400 + (31 * m) // 12) % 7
    
    if wday == 0:
        wday = 7
        
    return wday

#check dying saving time
def daylightSavingTime(year, month, day, wday, hour, minute):
    # Check if the month is March (3) or October (10)
    if month < 3 or month > 10:
        return False
    if month >= 3 and month <= 10:
        # Get the last Sunday in March and October
        lastSundayMarch = 31 - monthLastWday(year, 3, 31)
        lastSundayOctober = 31 - monthLastWday(year, 10, 31)
      
        if month == 3:
            if day > lastSundayMarch:
                return True
            elif day == lastSundayMarch:
                if hour >= 2:
                    return True
                else:
                    return False
            else:
                return False
           
        elif month == 10:
            if day < lastSundayOctober:
                return True
            elif day == lastSundayOctober:
                if hour >= 2:
                    return False
                else:
                    return True
            else:
                return False
        else:
            return True

offset = 1
hour += offset
hour += 1 if daylightSavingTime(year, month, day, wday, hour, minute) else 0

Funkcja o nazwie monthLastWday(year, month, day) przyjmuje podany rok, miesiąc i dzień jako argumenty i na ich podstawie oblicza, jaki dzień tygodnia przypada na tę datę. Wynik zwracany przez funkcję jest wartością od 1 do 7, gdzie 1 oznacza poniedziałek, a 7 oznacza niedzielę. Dzięki temu algorytmowi, możemy łatwo sprawdzić, który dzień tygodnia przypada na daną datę.

W drugiej funkcji, porównuje się podany czas z datą i godziną, które określają moment zmiany czasu na zimowy lub letni. Aby obliczyć ostatnią niedzielę marca i października, wykorzystałem z pierwszą funkcję oraz uwzględniam fakt, że te miesiące zawsze mają 31 dni..

Aby ustalić datę ostatniej niedzieli danego miesiąca, należy od liczby 31 odjąć numer dnia tygodnia, na który przypada ostatni dzień tego miesiąca. Na przykład, jeśli 31 marca 2023 roku przypada na piątek (numer dnia tygodnia 5), to odejmujemy 5 od 31, co daje nam wynik 26. W roku 2023 ostatnia niedziela marca przypada na dzień 26.

Obliczanie jasności podświetlenia

ESP32 posiada przetwornik analogowo-cyfrowy (ADC) o rozdzielczości 12-bitowej. Gdy w pomieszczeniu panuje całkowita ciemność, napięcie na pinie 36 spada do kilkuset mV, a odczyt z ADC wynosi 0. Natomiast w bardzo jasno oświetlonym pomieszczeniu, gdy napięcie na tym samym pinie wynosi około 3.3V, odczyt z przetwornika analogowo-cyfrowego wynosi 4095.

Aby regulować jasność wyświetlacza, korzystam z funkcji display.brightness(int), gdzie wartość int podawana jest w zakresie od 0 do 15. Ze względu na fakt, że odczyt jasności otoczenia mieści się w zakresie 0-4095, a ustawienie jasności podświetlenia odbywa się w zakresie 0-10, zastosowałem poniższy wzór do przeliczenia wyniku z jednej skali na drugą:

x_b = ((x_a - a_min) / (a_max - a_min)) * (b_max - b_min) + b_min

'''
x_a - wartość w skali A, czyli wartość, którą chcemy przekształcić na inną skalę
a_min - minimalna wartość skali A
a_max - maksymalna wartość skali A

x_b - wartość w skali B czyli wynik, który chcemy uzyskać
b_min - minimalna wartość skali B
b_max - maksymalna wartość skali B
'''

Aby zaoszczędzić trochę prądu i przedłużyć żywotność diod LED na wyświetlaczu, postanowiłem ograniczyć maksymalne podświetlenie do poziomu 7. Po wprowadzeniu odpowiednich wartości do wzoru, otrzymałem poniższy kod:

lightLevel = photoresistor.read()
brightness = ((lightLevel - 0) / (4095 - 0)) * (7 - 0) + 0  
display.brightness(round(brightness))

Najpierw kod wykonuje pomiar natężenia światła, a następnie przekształca skalę tego pomiaru. Po przekształceniu, wynik jest zaokrąglany do liczby całkowitej, a ostatecznie ustawiana jest jasność wyświetlacza na podstawie tego wyniku.

Ustawienia zegara

Sieć bezprzewodowa zegara działa w dwóch trybach. Pierwszym z nich jest połączenie z siecią WiFi, co umożliwia zegarowi łączność z Internetem. Drugim trybem jest funkcja punktu dostępowego, która pozwala innym urządzeniom połączyć się bezpośrednio z zegarem. Jeśli chcemy skorzystać z tej funkcji, wystarczy znaleźć sieć o nazwie “SmartClock v2” na naszym smartfonie i połączyć się z nią. Po ustanowieniu połączenia, mamy możliwość otwarcia przeglądarki internetowej i wpisania adresu: http://192.168.4.1/

Na tej stronie znajdują się 4 zakładki:

  • Pierwszą z nich jest strona główna, pełniąca rolę “menadżera cytatów”. Na tej stronie możesz aktywnie dodawać, usuwać oraz edytować teksty, które będą losowo wyświetlać się co 20 minut na zegarze.
  • Drugą zakładką jest sekcja Alarmy, która aktualnie jest pusta, ale w przyszłości może rozbuduje zegar o funkcjonalność budzika.
  • Kolejna zakładka to Ustawienia, gdzie głównie znajduje się prosty menadżer WiFi. Dzięki niemu możesz łatwo połączyć się z dowolną siecią i w razie potrzeby zmienić ustawienia. Dodatkowo, w tej sekcji można także wyłączyć lub włączyć wyświetlacz.
  • Ostatnia zakładka to Strona o mnie, która zawiera informacje o autorze projektu oraz informacje o zainstalowanej wersji oprogramowania.

To, co przedstawiam tutaj, to są jedynie fragmenty kodu. Jednakże, gorąco zachęcam do zapoznania się z całością. Znajdziesz tam wiele ciekawych rozwiązań oraz pomysłów, które mogą być inspirujące i wartościowe. Przyjrzenie się pełnemu kontekstowi pozwoli lepiej zrozumieć wszystkie aspekty i potencjał tego kodu.

Schemat połączeń

Opis wyprowadzeń układu ESP32-DevKitC-32U
Opis wyprowadzeń układu ESP32-DevKitC-32U Źródło: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/hw-reference/esp32/get-started-devkitc.html

Wyświetlacz

ESP32 komunikuje się z wyświetlaczem za pomocą sprzętowego SPI (Serial Peripheral Interface). Ich wyprowadzenia połączyłem w następujący sposób:

WyświetlaczESP32
VCC3V3
GNDGND
DINGPIO13 (HSPI_MOSI)
SCGPIO23
CLKGPIO14 (HSPI_SCK)
Opis połączeń matrycy LED i ESP32

Czujnik AHT10

Natomiast czujnik temperatury i wilgotności powietrza AHT10 przesyła informacje za pomocą interfejsu I2C. Jego cztery piny przylutowałem za pomocą przewodów do mikrokontrolera w takiej konfiguracji:

AHT10ESP32
VIN3V3
GNDGND
SCLGPIO22 (WIRE_SCL)
SDAGPIO21 (WIRE_SDA)
Opis połączeń czujnika AHT10 i ESP32

Fotorezystor

Do pomiaru natężenia światła użyłem fotorezystora 100mW /5-10kΩ i rezystora 10kΩ. Pin, który wykorzystałem do pomiaru przez ADC to: GPIO36 (ADC1_0)

Schemat ideowy połączenia fotorezystora i rezystora do ESP32
Schemat połączenia fotorezystora

ESP32 posiada dwa przetworniki analogowo-cyfrowe: ADC1 i ADC2 jednak gdy używana jest sieć wifi – ADC2 jest niedostępny.

Kod oraz schemat ideowy

Pełny kod w języku micropython, oraz schemat ideowy w formacie PDF, znajduje się na moim GitHub’ie. Całość można pobrać za pomocą komendy:

git clone https://github.com/Krzysztof-Antosik/SmartClock-v2.git

lub bezpośrednio z repozytorium: Krzysztof-Antosik/SmartClock-v2. Co jakiś czas do kodu wprowadzam drobne poprawki, usuwam błędy i dodaje nowe funkcje.

Schemat ideowy projektu: Inteligenty zegar DIY na ESP32
Pełny schemat ideowy zegara

Galeria

Podsumowanie

Inteligentny zegar oparty na ESP32, który stworzyłem i zaprogramowałen w Micropythonie, oferuje znacznie więcej niż zwykłe wyświetlanie godziny. Dzięki połączeniu z Internetem, automatycznej synchronizacji czasu, funkcji czasu letniego i zimowego, wyświetlaniu cytatów, odczytowi temperatury i wilgotności oraz automatycznej regulacji jasności, zegar staje się wszechstronnym narzędziem, które dodaje wartość do twojego otoczenia.

Dzięki prostemu interfejsowi konfiguracyjnemu i łatwej obsłudze, możesz dostosować zegar do swoich preferencji i cieszyć się inteligentnym towarzyszem, który doskonale spełnia swoje zadania. Wyobraź sobie, jak ten zegar może ułatwić Ci życie i dodawać przyjemności w codziennych czynnościach. A to dopiero początek możliwości, jakie oferuje rozwój inteligentnych urządzeń.

Jeśli masz jakieś uwagi lub pytania dotyczące artykułu zapraszam do dyskusji w komentarzach lub wiadomość poprzez formularz kontaktowy dostępny pod adresem: https://antosik.dev/kontakt/.

0 Shares:
2 komentarze
  1. Bardzo fajny artykuł. Podoba mi się rozwiązanie w kodzie dotyczące zmiany czasu z letniego i zimowego. Na pewno wykorzystam to w swoich przyszłych projektach.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

Możesz także polubić
Na zdjęciu widać zdjęcie monitora, laptoa, na którym jest widoczny kod w języku programowania
Czytaj dalej

Two Direction Sticky Sidebar – JavaScript

Two Direction Sticky Sidebar to projekt napisany w JavaScript poprawiający wygląd strony oraz doświadczenie użytkownika. Skrypt powoduje podążanie bocznego panelu nawigacyjnego za użytkownikiem, nawet gdy ten jest wyższy niż okno przeglądarki.