Smarthome – projekt higrostat cz.3

Przyciski

Wreszcie coś, co wszyscy chyba zrozumieją (chociaż założę się, że uda mi się to nieco skomplikować). Czym jest przycisk intuicyjnie chyba każdy z nas wie. Dla tych, którzy mimo to mają trudności pokrótce wytłumaczę, że jest to rodzaj łącznika, który zamyka obwód tak długo jak długo jest wciśnięty. Przyciski w liczbie co najmniej dwóch zamierzam wykorzystać do sterowania nastawami mojego higrostatu. Wydawałoby się, że zbliżamy się do końca podróży i wkrótce zaczniemy tutaj wszystko składać w całość, a przyciski to tylko formalność. No niestety nie jest to aż tak proste.

Okazuje się bowiem, że obsługę przycisków możemy zaimplementować na kilka sposobów, z których większość nie będzie się nadawać do niczego, albo poradzi sobie jedynie w najprostszych wypadkach. Niestety mój nie będzie najprostszy, ale do rzeczy. Większość najprostszych tutoriali odnośnie przycisków na mikrokontrolerze RP2040 sprowadza się do zainicjalizowania jakiegoś pinu, z przypadkową liczbą oznaczającą logiczny numerek pinu (zgodnie z obrazkiem, który wkleiłem w poprzednim rozdziale) z którego następnie w pętli odczytujemy stan – najlepiej kilka razy na sekundę. Problem pierwszy – w związku z pewną ilością zakłóceń w samym mikrokontrolerze odczytywane wartości mogą “samorzutnie” się zmieniać i niestety będzie to normalne. Na szczęście brać elektroniczna już dawno temu znalazła na to rozwiązanie – trzeba do sygnału podłączyć poprzez rezystor albo napięcie referencyjne, albo uziemienie. W tym pierwszym wypadku oznacza to, że nasz rezystor jest podciągający (PULL UP), w drugim ściągającym (PULL DOWN). Gdy nic się nie dzieje ten pierwszy ustala nam wartość sygnału na 1, a ten drugi na 0 (zdecydować się trzeba na jeden z nich i nie podpinać w ten sposób dwóch). Ciekawostką, która niezbyt przypada mi do gustu jest fakt, że wartość takiego rezystora nie jest odgórnie ustalona jakimś wzorem. Zwykle zaleca się oporniczek o wartości kilku, kilkudziesięciu kOhm. Na szczęście RP2040 ma swoje oporniczki i możemy je aktywować software’owo np. tak: 

p = Pin(id=5,pull=Pin.PULL_UP)

(dla czujnika DHT nie pomogło – musiałem dać dodatkowy oporniczek).

Załóżmy, że podciąganie sygnału opanowaliśmy, no to zapuszczamy pętlę w czasie której nasz program coś tam sobie robi i co jakiś czas sprawdza stan naszego przycisku. Problem polega na tym, że czas odczytu jest bardzo krótki i nasz przycisk musi być dokładnie wtedy wciśnięty. Złapanie dokładnego momentu zwolnienia przycisku (żeby np. odczytać jak długo był wciśnięty) jest w tym układzie praktycznie niemożliwe. Druga rzecz to tzw. debouncing (pojęcia nie mam jak to się tłumaczy na nasze). W telegraficznym skrócie polega to na tym, że zanim nastąpi takie kompletne zwarcie fizycznych styków w naszym przycisku może pojawić się delikatne iskrzenie, które przy odrobinie pecha może być zinterpretowane jako seria “wciśnięć”, trzeba wtedy pobawić się w liczenie, czy od wciśnięcia naszego przycisku minęło dość czasu, żeby uznać to za poprawne dane.Trzecia rzecz, że operacje jakie będziemy wykonywać w pętli mogą zajmować sporo czasu (kompletnie już abstrahując od tego jakie to mogą być w tym momencie operacje). Dlatego najlepiej, aby wciśnięcie naszego guzika wywoływało akcję od razu. Jak tego dokonać? Otóż służą do tego tzw. przerwania. Przerwania wstrzymują normalne wykonanie programu, wykonują przypisany im kod, po czym jak gdyby nigdy nic oddają kontrolę i wykonanie programu zostaje wznowione od punktu w którym został on zatrzymany.

Teraz pewnie niektórzy chcą jęknąć – “czy to naprawdę jest wszystko konieczne?!”. Okazuje się, że podobnie jak w przypadku pozostałych komponentów, którymi było mi dane się w tym projekcie pobawić – nie (i samemu łatwiej to ogarnąć niż wyświetlacz LCD), ale też i nie jest takie proste. Chyba, że używasz Thonny jako swojego IDE to wtedy masz inne problemy. Koniec końców wszystko sprowadza się do tego, że w micropythonie jest odpowiednia dla przycisków biblioteka. Nazywa się “picozero” i niestety jeśli ktoś jak ja używa do programowania swojego PICO narzędzi VS Code, to musi sobie sam tą bibliotekę zorganizować i przesłać do mikrokontrolera. Zapewne są do tego jakieś fajne rozwiązania, ale ja ich nie znalazłem. Posiłkowałem się więc tzw. metodą “na chama”.

Pierwsze co, to wycieczka do Powershella i wpisanie tam:  

pip install picozero                                                               

(zakładam, że macie Pythona i pip na pokładzie)

Bilioteka instaluje się nam wtedy w 

%appdata%\python\python39\site-packages

(a przynajmniej mi się tam zainstalowała). Nie jest to konieczny krok, ale dla wygody możemy sobie skopiować folder picozero do naszej przestrzeni roboczej i wgrać na płytkę plik picozero.py . Thonny ogarnia to wszystko sam, ale brak porządnego intellisense’a powoduje, że nie jest to dla mnie najwygodniejsze środowisko (no cóż – coś za coś). 

Kod wtedy wygląda mniej więcej tak:

from machine import Pin
from picozero import Button
import time


t : int


def active():
    global t
    t = time.time_ns()
    print("Aktywny jestem")


def inactive():
    global t
    print("Byłem aktywny przez: " + str((time.time_ns()-t)/1000000000) + " sekund(y)")


button = Button(16)
button.when_activated = active
button.when_deactivated = inactive
p = Pin(id=5,pull=Pin.PULL_UP)
while True:
    pass

Co może trochę zwracać uwagę, a wcale nie musi – w linii 5 kontrukcja t : int

to narzucenie typu int (liczba całkowita) zmiennej t. W ten sposób można trochę przymusić Pythona do tego, aby stał się jawnie typowany. W linii 8 i 13  global t oznacza, że za każdym razem gdy będziemy odwoływać się do zmiennej t to nie chcemy utworzyć nowej lokalnej, a korzystać z tej zadeklarowanej globalnie w linii 5. Czasem działa bez tego, częściej robi to źle – lepiej dawać. Ostatnia ciekawostka to polecenie pass, które w zasadzie nic nie robi. Nie, że robi coś, czego nie wiem – ono dosłownie robi “nic”. W tym wypadku chodzi o to, żeby program działał sobie w nieskończonej pętli bo Python trochę się obraża gdy nic nie wpiszesz. Poniżej przykładowy wydruk tego, co można takim kodem wymodzić: 

Aktywny jestem
Byłem aktywny przez: 0.090172 sekund(y)
Aktywny jestem
Byłem aktywny przez: 0.109141 sekund(y)
Aktywny jestem
Byłem aktywny przez: 0.102154 sekund(y)
Aktywny jestem
Byłem aktywny przez: 0.089162 sekund(y)
Aktywny jestem
Byłem aktywny przez: 0.088166 sekund(y)
Aktywny jestem
Byłem aktywny przez: 0.090146 sekund(y)

W tej chwili nieszczególnie zajmujące, ale to kolejny, niezbędny krok. Sensu zamieszczania w tym wypadku zdjęcia z płytką nie widzę. To przycisk plus dwa kabelki, z czego jeden idzie do uziemienia, a drugi do pinu 20 (czyli logicznej szesnastki).

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.