Założenia nowego rozwiązania
Zasilanie z 230V AC z przetwornicą zainstalowaną w obudowie. Zasilanie włączane obecnie nie używanym łącznikiem. Dodatkowo możliwość włączania wentylatora ręcznie drugim łącznikiem z całkowitym pominięciem logiki. Takie rozwiązanie powinno umożliwić przejście na “tryb ręczny” w wypadku, gdyby wystąpiła jakaś awaria. Początkowo myślałem o jakimś prymitywnym rozwiązaniu bez mikrokontrolera, ale w tym chińskim higrostacie spodobały mi się dwie rzeczy – wyświetlanie obecnej wilgotności, oraz możliwość dopasowania progów włączenia wyłączenia za pomocą przycisków. Dlatego zdecydowałem się na budowę wersji full wypas z mikrokontrolerem RP2040 (konkretniej nieco starszą wersją Raspberry Pi PICO, bo walała się po domu i do niczego konkretnego nie służyła)
Wyzwania
3.1. Higrometr (czujnik wilgotności)
Zdecydowałem się na zastosowanie popularnego czujnika DHT22. Wybór był trochę przypadkowy, ale bardzo celny. Co prawda odczytu można dokonywać tylko co 2 sekundy, ale za to rozpiętość pomiaru sięga od 0 – 100%, a te 100% mojej żonie udaje się osiągnąć bez problemu. Dokładność pomiaru jest w moim projekcie niespecjalnie istotna, ale zgodnie z kartą katalogową sięga mniej więcej 2% (ale nie wyjaśniono, czy przekłamuje wynik o te procenty, czy o dwa punkty procentowe, ale obstawiałbym to drugie). Mnie osobiście zadowala wszystko poniżej 10 punktów procentowych. Częstotliwość pomiarów to raz na dwie skundy (czy jak wolą fizycy 0,5Hz). Niezbyt duża, ale do moich celów więcej niż wystarczająca. Sam zaś czujnik jest dość (przynajmniej dla mnie) ciekawy ze względu na sposób komunikacji. Korzysta on bowiem z protokołu one-wire (albo czegoś analogicznego) i pierwszy raz korzystałem z tego cuda. Niestety jak tylko odkryłem, że czujniki DHT mają swoją dedykowaną bibliotekę w standardowych firmware’ach do PICO wybrałem ścieżkę leniwca i natychmiast z niej skorzystałem. W ten sposób całość okazała się nie tyle łatwa, co wręcz banalna. Schemat połączeń na płytce prototypowej wygląda tak:
a tak wygląda caluteńki kod (który można jeszcze o kilka linijek skrócić):
from machine import Pin
from time import sleep
import dht
sensorPin = Pin(22)
sensor = dht.DHT22(sensorPin)
while True:
try:
sleep(2)
sensor.measure()
temp = sensor.temperature()
hum = sensor.humidity()
print('Temperatura %3.1f C' %temp)
print('Wilgotonosc %3.1f %%' %hum)
except OSError:
print("Fejl")
from machine import Pin
from time import sleep
import dht
sensorPin = Pin(22)
sensor = dht.DHT22(sensorPin)
while True:
try:
sleep(2)
sensor.measure()
temp = sensor.temperature()
hum = sensor.humidity()
print(’Temperatura %3.1f C’ %temp)
print(’Wilgotonosc %3.1f %%’ %hum)
except OSError:
print(„Fejl”)
3.2. Ekran LED
A właściwie mikroskopijny ekranik LED o oszałamiającej rozdzielczości 128×32 pixele – moje Atari 800XL którego rodowód to przełom lat 70-tych i 80-tych potrafił wyświetlić więcej pikseli (320×192 w aż 16 kolorach) wprawdzie na telewizorze, ale zawsze. Szczerze mówiąc wszystko poszło zgodnie z oczekiwaniami, a oczekiwałem pewnych problemów. Zacznijmy jednak od tego, że kolejny raz miałem odrobinę szczęścia. W szale zakupów wyświetlacz jaki utrafiłem okazał się być kompatybilny z bardzo pospolitym na rynku sterownikiem SSD1306. Dzięki temu stosunkowo łatwo udało mi się odkopać kod biblioteki w micropythonie, która ładnie zagadnienie ogarnia. Co ciekawe – z tą biblioteką były dwa problemy – po pierwsze źródła kierujące do jej githuba często są nieaktualne – tj. tej biblioteki już tam nie ma. Po drugie – o ile jej kod jest stosunkowo łatwy do odnalezienia, o tyle wymaga on dopisania dwóch metod w klasie SSD1306 (która pełni w tej bibliotece funkcję klasy abstrakcyjnej, czyli wstępnie implementującej niektóre metody – po głębsze wyjaśnienia odsyłam do poradników programowania obiektowego), które kompletnie nic nie robią (zostają przesłonięte przez końcowe implementacje klas). Kod biblioteki, razem z resztą będzie można sobie podglądnąć na githubie.
Teraz tak – aby nasza biblioteka zadziałała trzeba oczywiście pamiętać, że nasz program aby z niej skorzystać potrzebuje mieć do niej dostęp (niby oczywiste). Jeśli korzystamy z VSCode to rozwiązujemy ten problem poprzez wrzucenie biblioteki na nasz sterownik przed uruchomieniem testowego programu. Sam zaś program główny rozrósł do oszałamiających 25 linii i jest teraz zdolny do podawania wyników na wspomnianym na początku wyświetlaczu. Kod programu poniżej:
from machine import Pin, I2C
from time import sleep
import ssd1306
import dht
#preparations
sensorPin = Pin(22)
sensor = dht.DHT22(sensorPin)
i2c = I2C(0, scl=Pin(1),sda=Pin(0))
oled_width = 128
oled_height = 32
oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c)
oled.text("Starting...",5,5)
oled.show()
sleep(2)#wait 2 seconds to initilize DHT sensor
oled.fill(0)#fill screen with zeros (empty pixels)
sensor.measure()
while True:
oled.fill(0)
oled.text("Rh=" + str(sensor.humidity()) + "%",5,5)
oled.text("T =" + str(sensor.temperature()) + "C",5,17)
oled.show()
sleep(2) #DHT can measure only once per two seconds
sensor.measure()
Natomiast zestaw testowy wygląda teraz tak (ekran LED po lewej – i tak, to rzeczywiste parametry mojej pracowni):
Ostatni problem jaki ogarniałem to konfiguracja protokołu I2C. Otóż w produktach fundacji Raspberry (jakim niewątpliwie jest procesor RP2040 na mojej płytce) istnieją dwa rodzaje numeracji pinów. Numeracja płytki (board) i numeracja logiczna. Jak widać na załączonym na obrazku poniżej (wyciągniętym z rozszerzenia MicroPico dla VSCode) potrafią się nie pokrywać (fizyczne piny na szarym tle, logiczne na zielonym):
Ja oczywiście je pomyliłem i godzinę straciłem na ustanowieniu komunikacji na pinach, do których moja płytka nie była podłączona. Myślałem też przez moment, że przetwornica 3,3V nie wyrabia, dlatego ekran zasilany jest z linii 5V, co na szczęście obsługuje i sprawdziłem to zanim go przełączyłem. Uwaga jeśli korzystacie z czujników na różnych gotowych płytkach, mimo iż producent czujnika może twierdzić, że pracuje on na 5V, to producent płytki może zastosować komponenty, które obniżą to napięcie do 3,3V i tego akurat dowiedziałem się kilka lat temu podczas pracy nad projektem automatu do zamykania okien, gdzie też miałem wrażenie, że zasilanie 3,3V nie wyrabia i podłączyłem czujnik na płytce pod 5V (wg karty katalogowej sam czujnik powinien dać sobie z tym spokojnie radę), co zamieniło go w nieco śmierdzącego dymu i zostałem z płytką, która nadawała się już tylko na śmietnik. Tak czy siak, ekran działa jak miał działać i nie wygląda na to, żeby miał ochotę sprawiać jakieś dodatkowe problemy.