Menu Zamknij

Programowanie Raspberry Pi w języku Python

Cel

Zapoznanie z możliwościami RPi przy wykorzystaniu języka Python. Budowa wizualnego termometru z cyfrowym 1-Wire czujnikiem temperatury.

Wymagania

  • Raspberry Pi,
  • cyfrowy termometr DS18B20,
  • dwukolorowa dioda LED,
  • rezystory, przewody goldpin, płytka stykowa.

Wprowadzenie

Samo sformułowanie „programowanie Raspberry Pi” ma w domyśle dwie rzeczy, o ile się ich nie doprecyzuje. Pierwszą jest system operacyjny Raspbian, drugą język programowania Python, chociaż możliwości wyboru języka programowania dla tej platformy są ogromne. Python dla RPi ma wielką społeczność, ale przede wszystkim mnóstwo gotowych dodatków (modułów) zapewniających wsparcie dla bardzo dużej liczby fizycznych komponentów. O języku Python i jego zaletach traktuje także rozdział Inne metody programowania modułu micro:bit niniejszego skryptu. W tym rozdziale zakładana jest przynajmniej podstawowa wiedza o tym języku.

Python na RPi

Skrypty Pythona, pliki tekstowe z rozszerzeniem *.py, zazwyczaj na Raspberry uruchamiać będziemy w wersji 2 języka, chociaż w Raspbianie dostępna jest także wersja 3. Listing przedstawia najprostszy program migający diodą podłączoną na pinie 13 (pamiętaj o rezystorze ograniczającym prąd – rozdział Nauka programowania z Arduino).

Listing 1

import RPi.GPIO as GPIO
from time import sleep

led_pin = 13
tau = 0.5

GPIO.setmode(GPIO.BCM)
GPIO.setup(led_pin, GPIO.OUT)

while True:
    GPIO.output(led_pin, GPIO.HIGH)
    sleep(tau)
    GPIO.output(led_pin, GPIO.LOW)
    sleep(tau)

Program ten należy traktować jako swego rodzaju szablon. Kilka elementów jest typowych, używanych przez wielu programistów w ten sam sposób, dla pisania skryptów w Pythonie na RPi. Pierwsza linia ładuje moduł RPi.GPIO i przemianowuje go na skrótową nazwę GPIO. Można pominąć zmianę nazwy lub nazwać po swojemu, jednak jest to już jakiś standard. W wierszu 7 funkcja setmode ustala numerację pinów zgodną z tą zamieszczoną w tabeli 1 rozdziału Systemowa obsługa wejść i wyjść Raspberry Pi. W wierszu 8 pin 13 jest ustawiany jako wyjście, a wiersze 11 i 13 na zmianę włączają i wyłączają diodę. Program uruchamiamy poleceniem:

$ python miganie.py

Takie programy często można spotkać w różnego rodzaju materiałach dla Raspberry, ale ma on zasadniczą wadę. Pętla while jest pętlą nieskończoną, analogiczną do funkcji loop() z Arduino i żeby ją przerwać, należy wcisnąć w konsoli ^C. Nagłe zatrzymanie programu spowoduje zachowanie stanu wyjścia – jeżeli dioda się świeciła w trakcie przerwania, to zostanie zaświecona. Powtórne uruchomienie programu odbędzie się z ostrzeżeniem o tym, że piny są już w użyciu. Możemy ten komunikat zignorować. Program będzie działał normalnie. Jeżeli nam to nie przeszkadza, to możemy tak pisać, jednak w następnym przykładzie przechwycimy przerwanie klawiaturowe i posprzątamy po sobie.

Dioda dwukolorowa

Podłączmy do Raspberry Pi, do styków 12 i 13, diodę dwukolorową. W przykładzie zastosowaliśmy zielono-czerwoną LED o wspólnej katodzie i podłączyliśmy zgodnie ze schematem 1. Program zaprezentowany na listingu 2 wykorzystuje do sterowania jasnością diody sygnał z regulowanym wypełnieniem. Raspberry Pi jest na tyle wydajnym komputerem, że programowo wspierane PWM jest dostępne na każdym pinie. Wsparcie sprzętowe tej modulacji obsługiwane jest jedynie na dwóch stykach: 12 i 13.

Rysunek 1. Podłączenie dwukolorowej diody do RPi

Listing 2

import RPi.GPIO as GPIO
from time import sleep

GPIO.setmode(GPIO.BCM)

red_pin = 12
green_pin = 13
tau = 0.01

GPIO.setup(red_pin, GPIO.OUT)
GPIO.setup(green_pin, GPIO.OUT)
red_pwm = GPIO.PWM(red_pin, 200)
green_pwm = GPIO.PWM(green_pin, 200)
red_pwm.start(100)
green_pwm.start(0)

try:
    while True:
        for intens in range(0,101):
            red_pwm.ChangeDutyCycle(intens)
            green_pwm.ChangeDutyCycle(100 - intens)
            sleep(tau)
        for intens in range(0,101):
            red_pwm.ChangeDutyCycle(100 - intens)
            green_pwm.ChangeDutyCycle(intens)
            sleep(tau)

except KeyboardInterrupt:
    print('OK!')
 
finally:
    red_pwm.stop()
    green_pwm.stop()
    GPIO.cleanup()

Działający program powoduje ciągłą zmianę barwy diody od czerwonej poprzez pomarańczową i żółtą do zielonej i z powrotem. Cały cykl trwa około 200 sekund.

Cyfrowy czujnik temperatury

Rysunek 2. Podłączenie czujnika temperatury DS18B20 do Raspberry Pi

Twórcy RPi nie przewidzieli, że świat fizyczny jest analogowy, i pozbawili użytkownika możliwości bezpośredniego przetwarzania A/D. Wyjścia z takiej sytuacji, o ile jest taka potrzeba, są dwa: albo zastosowanie zewnętrznego przetwornika analogowo-cyfrowego, a jest z czego wybierać, albo zastosowanie czujnika z wbudowanym przetwornikiem, o co obecnie czasami łatwiej i taniej niż o nabycie czujnika tradycyjnego. Czujniki takie komunikują się przeważnie popularnymi protokołami, jak poznane już poprzednio SPI czy I2C. W tym projekcie użyjemy popularnego czujnika temperatury DS18B20, używającego szeregowej komunikacji jednoprzewodowej 1-Wire.

Do realizacji tego projektu najlepiej zakupić czujnik w wodoszczelnej obudowie i z długim kablem. Podłączenie czujnika do RPi nie jest skomplikowane (rysunek 2), ale należy zwrócić uwagę na kilka spraw. Na złączu Raspeberry Pi występują oprócz napięć 3V3, także napięcia 5V. Ponieważ logika urządzenia jest trzywoltowa, pomyłka może nas drogo kosztować. Po drugie, komunikacja 1-Wire odbywa się tylko na pinie 4, o ile chcemy skorzystać z rozwiązań gotowych. Jednak protokół ten jest na tyle złożony, że w zasadzie jest to jedyne rozwiązanie. Po trzecie, do złącza sygnałowego należy podpiąć rezystor podciągający do zasilania o wartości 4k7. Nie wynika to ze złośliwości lub lenistwa producenta, ale z faktu, że do magistrali 1-Wire może być podłączonych wiele urządzeń bezpośrednio. Wbudowane rezystory zrównolegliłyby się wówczas.

Obsługę szeregowej magistrali jednoprzewodowej 1-Wire RPi daje nam już na poziomie systemowym, jednak odpowiednie moduły zapewniające komunikację nie są automatycznie ładowane do jądra systemu. Można to zrobić ręcznie poprzez polecenie modprobe, ale ma to tę niedogodność, że działanie tego polecenia ograniczone będzie do następnego uruchomienia systemu. Stałe ładowanie modułów do jądra wymaga odpowiednich wpisów w pliku konfiguracyjnym /etc/modules, dlatego lepiej skorzystać z narzędzia konfiguracyjnego RPi o nazwie raspi-config.

$ sudo raspi-config
Rysunek 3. Główne menu raspi-config

Główne okno raspi-config przedstawione jest na rysunku 3. Opcje standardu 1-Wire znajdziemy na piątej pozycji w menu głównym Inerfacing Options. Następnie obsługa konfiguratora raspi jest dosyć intuicyjna. Na pozycji P7 1-Wire dostaniemy możliwość włączenia tego interfejsu. Po zatwierdzeniu zmian zostaniemy zapytani, czy chcemy zrestartować urządzenie, moduły bowiem będą dostępne od następnego uruchomienia jądra.

Po starcie systemu możemy sprawdzić, czy moduły rzeczywiście są załadowane poleceniem lsmod. Jeżeli jest w1_gpio, ale nie ma w1_therm, oznacza to, że obsługa magistrali 1-Wire uruchomiła się, ale nie działa sam termometr. Trzeba wówczas sprawdzić połączenia, a w szczególności obecność rezystora podciągającego.

W tym momencie czujnik już pracuje. Jego stan można sprawdzić poprzez odczyt wirtualnego pliku. Urządzenia 1-wire znajdują się w katalogu /sys/bus/w1/devices. Po jego wylistowaniu będą widoczne podkatalogi o nazwach zgodnych z adresami urządzeń.

$ cd /sys/bus/w1/devices
$ ls

Nasz termometr będzie reprezentowany przez katalog 28-????????????????, gdzie pytajnik jest jakąś szesnastkową cyfrą. Jeśli podłączamy naraz tylko jedno urządzenie, nie będzie problemu z identyfikacją. Dane odczytane z termometru przechowywane są w pliku w1_slave znajdującym się w tym katalogu. Możemy je odczytać poleceniem cat.

$ cat 28<TAB>/w1<TAB>

Użyliśmy linuksowej sztuczki z rozwijaniem nazw klawiszem tabulacji. Wynik działania może być następujący:

56 01 4b 46 7f ff 0c 10 7b : crc=7b YES
56 01 4b 46 7f ff 0c 10 7b t=21375

Najważniejsze są ostatnie znaki po t=. To one reprezentują temperaturę w tysięcznych częściach stopnia Celsjusza. Jak widać do odczytu danych nie potrzeba uprawnień administracyjnych.

Wyłuskiwanie samej temperatury z pliku w1_slave, aczkolwiek możliwe, nie jest jednak szczytem wygody. W języku Python jest dostępny moduł obsługi takiego czujnika, nie jest on niestety zainstalowany. Najłatwiej pozyskać go instalatorem pakietów Pythona o nazwie pip.

$ sudo pip install w1thermsensor

Pozwoli nam to na bardzo prostą obsługę termometru z poziomu skryptów Pythona. Program, odczytujący co jakiś czas (zdefiniowany przez zmienną tau) temperaturę z czujnika i wyświetlający ją na standardowym wyjściu, prezentuje program 3.

Listing 3

import w1thermsensor
from time import sleep

sensor = w1thermsensor.W1ThermSensor()

tau = 2

while True:
    print(sensor.get_temperature())
    sleep(tau)

Wizualny termometr

Połączmy programy dwukolorowej diody i termometru tak, aby wynik pomiaru nie był wyświetlany tekstowo, a prezentowany kolorem diody: zielony – zimno, żółty – w sam raz, czerwony – ciepło. Program realizujący to zadanie przedstawiony jest na listingu 4.

Listing 4

import RPi.GPIO as GPIO
import w1thermsensor
from time import sleep

GPIO.setmode(GPIO.BCM)

red_pin = 12
green_pin = 13

tau = 1
tempMIN = 20
tempMAX = 80

sensor = w1thermsensor.W1ThermSensor()

GPIO.setup(red_pin, GPIO.OUT)
GPIO.setup(green_pin, GPIO.OUT)
red_pwm = GPIO.PWM(red_pin, 200)
green_pwm = GPIO.PWM(green_pin, 200)
red_pwm.start(0)
green_pwm.start(0)

try:
    while True:
        temp = sensor.get_temperature()
        if temp <= tempMIN:
            intens = 0
        elif temp >= tempMAX:
            intens = 100
        else:
            intens = 100 / (tempMAX - tempMIN) * (temp - tempMIN)
        red_pwm.ChangeDutyCycle(intens)
        green_pwm.ChangeDutyCycle(100 - intens)
        sleep(tau)
except KeyboardInterrupt:
    print('Koniec.')

red_pwm.stop()
green_pwm.stop()
GPIO.cleanup()
Rysunek 4. Gorąca woda! Działający termometr

Program ten nie wymaga komentarza, bo nie zawiera w stosunku do poprzednich programów żadnych nowych elementów. Zmienne tempMIN i tempMAX określają zakres temperatur zmiany barwy, a w linii 31 temperatura bieżąca jest przeliczana na wypełnienie sygnału PWM. Należy uważać, bo niewłaściwa wartość, spoza zakresu 0–100, podana jako parametr funkcji ChangeDutyCycle spowoduje nagłe przerwanie skryptu z błędem. Można się przed tym zabezpieczyć, odpowiednio obsługując wyjątek, co nie zostało uwzględnione na listingu 4.

Modyfikacje

Przedstawione w tym rozdziale wiadomości są wystarczające do budowy bardzo złożonych i funkcjonalnych urządzeń. W projekcie zamiast czujnika temperatury można zastosować dowolny, najlepiej cyfrowy, na przykład czujnik światła z rozdziału Zmierzchowy wyłącznik światła. Nie trzeba także ograniczać się do wyjść GPIO, można wykorzystać także wszystkie inne formy interfejsów, na przykład powiadamiania głosowego lub wysyłania informacji przez internet.

Prostą (pozornie) modyfikacją programu 4 może być wprowadzenie diody RGB i wyświetlania od niebieskiego – zimno do czerwonego – gorąco.

Literatura

Powtórzenie zaprezentowanych projektów nie wymaga studiowania dodatkowej literatury. Dopiero wprowadzenie modyfikacji może wiązać się z koniecznością uzupełnienia wiedzy. Najlepszym źródłem informacji w przypadku jakiegoś konkretnego problemu jest internet. Książka pisana swoją wyższość ukazuje dopiero jako podręcznik czy przewodnik.

Informacje bibliograficzne dotyczące źródeł internetowych zamieściłem bezpośrednio w tekście, przy zagadnieniach, których dotyczą.

Do zapisu linków, tylko w tym spisie, wykorzystywana jest metoda skracania adresów (URL shortening). W tym skrypcie wybrano serwis TinyURL. Dostęp do wszystkich internetowych zasobów został przetestowany 27.02.2020.

Bibliografia zawiera tylko materiały pomocnicze do projektów, których dotyczą, a pominięto literaturę o charakterze ogólnoinformatycznym. Dobór materiałów do nauki kodowania, czy obsługi programów narzędziowych, pozostaje po stronie nauczyciela.

Dla Arduino i Raspberry jest po prostu ogrom literatury i różnych zasobów internetowych – także w polskim języku. Jest na rynku bardzo ciekawa książka wspólna dla obu platform, prezentująca rozwiązania problemów równocześnie dla obu modułów:

  • Monk Simon, Zrób to sam. Generowanie ruchu, światła i dźwięku za pomocą Arduino i Raspberry Pi [e-book], tłum. Konrad Matuk, Helion, 2018.

Także Raspberry Pi nie należy do urządzeń, dla których trudno o dokumentację.

Z książkowych przewodników polecam:

  • Richardson Matt, Wallace Shawn, Wprowadzenie do Raspberry Pi [e-book], tłum. Maria Chaniewska, wyd. 2, Helion, 2016.
  • Upton Eben, Halfacree Gareth, Raspberry Pi. Przewodnik użytkownika. Wydanie III [e-book], tłum. Konrad Matuk, Helion, 2015. ale gama dobrych podręczników jest naprawdę szeroka.

Literatura uzupełniająca

W niektórych projektach nie wszystko da się podłączyć za pomocą pasujących do siebie wtyków i złącz. Należy wówczas wykonać takie podłączenia samodzielnie. Wymaga to nieco umiejętności majsterkowania i elektroniki. Bardzo ciekawą książką dla początkujących majsterkowiczów jest:

  • Roberts Dustyn, Wpraw to w ruch. Proste mechanizmy dla wynalazców, majsterkowiczów i artystów [e-book], tłum. Krzysztof Sawka, Helion, 2015.

Znajdziemy w niej oprócz podstaw elektroniki także dużo elementarnej mechaniki i materiałoznawstwa.

Majsterkowanie z użyciem systemów wbudowanych, tam gdzie nie wszystko pasuje do siebie za pomocą dedykowanych styków, wymaga elementarnej wiedzy z elektroniki. Niezmiennie najważniejszą książką na półce elektronika jest:

  • Horowitz Paul, Hill Winfield, Sztuka elektroniki, tłum. Bogusław Kalinowski, Grażyna Kalinowska, t. 1–2, wyd. 12 zmienione, WKŁ, Warszawa 2018.

Jednakże jest to pozycja dla wymagającego czytelnika. Podobnym standardem, ale skierowanym do początkujących jest:

  • Platt Charles, Elektronika. Od praktyki do teorii. Wydanie II [e-book], tłum. Konrad Matuk, Helion, 2016.

Na uwagę zasługuje ponadto, w moim przekonaniu bardzo dobra, książka polskiego autora:

  • Górecki Piotr, Wyprawy w świat elektroniki, t. 1, WKŁ, Warszawa 2006.
  • Górecki Piotr, Wyprawy w świat elektroniki. Wyższy stopień wtajemniczenia, t. 2, WKŁ, Warszawa 2011.

Dodaj komentarz

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