Micro Python i pyboard czyli Python na mikrokontrolerach steruje elektroniką

Co oferuje i jak działa implementacja Pythona na mikrokontrolery MicroPython oraz co potrafi płytka pyboard?

MicroPython to implementacja Pythona 3 dostosowana do działania na mikrokontrolerach. PyBoard to pierwsza płytka z mikrokontrolerem z działającym na nim MicroPythonem. Płytka może być skryptowana Pythonem i działa bez konieczności podłączenia do PC jak np. PyMCU. Kilka miesięcy temu projekt został ufundowany dzięki zbiórce na Kickstarterze, a teraz trafia do otwartej sprzedaży. Sprawdźmy więc co Micro Python i pyboard potrafią.

PyBoard

Płytka PyBoard wyposażona jest w mikrokontroler STM32F405RGT6 (ARM 32-bit Cortex-M4 CPU z FPU), akcelerometr Freescale MMA766, a także złącze micro SD i micro USB. Liczne złącza GPIO zapewniają obsługę I2C, SPI, USART, czy DAC/ADC.

Rozkład pinów i ich funkcjonalności na płytce PyBoard

Rozkład pinów i ich funkcjonalności na płytce PyBoard

PyBoard w całej okazałości
PyBoard od spodu

PyBoard można kupić ze sklepu projektu i potencjalnie w innych sklepach z elektroniką (jak na razie mamy deficyt płytek). Najlepiej kupić wersję z przylutowanymi żeńskimi złączami GPIO. Sztuka, którą dostałem z Kickstartera taki złączy nie posiadała i musiał się trochę namęczyć by przylutować męskie piny, które są mniej poręczne, bo płytka jest nieco za szeroka na zwykłe płytki stykowe (o ile w ogóle poprzeczny rząd pinów GPIO przerzucimy na górę). Do płytki dostępna jest dokumentacja, jak i tutorial Micro Pythona, ale o nim to za chwilę.

PyBoard jest zbyt szeroka dla zwykłych płytek stykowych

PyBoard jest zby szeroka dla zwykłych płytek stykowych

Wersja sprzedawana z żeńskimi złączami GPIO jest znacznie bardziej poręczniejsza

Wersja sprzedawana z żeńskimi złączami GPIO jest znacznie bardziej poręczniejsza

Jak to działa?

Na płytce znajduje się mały system plików oznaczony jako 0:/. Jeżeli podłączona zostanie karta microSD to dostanie oznaczenie 1:/. Gdy PyBoard startuje wybiera system plików, z którego ma się uruchomić. System wybierze kartę microSD lub wbudowany system plików, gdy karta nie będzie obecna. System wykona plik boot.py a następnie main.py. Ten drugi plik jest bardzo ważny bo to w nim umieszczamy kod naszej aplikacji. Gdy podłączymy PyBoard do komputera dostaniemy system plików, który został użyty do uruchomienia systemu - możemy wtedy np. przekopiować pliki z nowym kodem, odmontować i zresetować PyBoard by płytka uruchomiła się ponownie z nowym kodem.

Jeżeli czerwona i zielona dioda LED miga naprzemiennie to w skrypcie wystąpił błąd (co można zdebugować za pomocą REPL - konsoli). Jeżeli wszystkie cztery diody migają powoli to wystąpił poważniejszy (sprzętowy) błąd i potrzebny jest hard-reset.

Oprócz wrzucania kodu na system plików płytki można także uzyskać dostęp do Pythonowej konsoli REPL, czyli Read Evaluate Print Loop. Żeby dostać konsolę będziemy musieli nawiązać połączenie szeregowe. dokumentacja opisuje jak to uzyskać dla poszczególnych systemów operacyjnych. W przypadku Linuksa wystarczy wykonać:

sudo screen /dev/ttyACM0

By po chwili dostać dostęp do konsoli (u mnie trzeba było wcisnąć Enter po tym jak wypisał AT na ekranie). Wpisanie help() powinno wyświetlić pomoc modułu pyb jak i skróty działające w obrębie REPL. Żeby zamknąć konsolę należy wcisnąć CTRL + a a następnie CTRL + d.

W obrębie REPL możemy zaimportować moduł pyb jak i nasze moduły (np. z pliku main.py i innych o ile takie wrzuciliśmy) i je wykonać. Funkcjonalność zbliżona jest do interaktywnego interpretera Pythona. Oto prosty przykład z akcelerometrem:

import pyb
accel = pyb.Accel()

while True:
    print(accel.filtered_xyz())
    pyb.delay(250)

Pętla będzie wypisywała obecne położenie w trzech osiach jakie zwraca akcelerometr umieszczony na płytce (przekrzywiaj płytkę na boki, albo góra/dół by zaobserwować jak zmieniają się wartości).

MicroPython

Jak już mogłeś zauważyć głównym modułem jest pyb, który zapewnia obsługę funkcjonalności mikrokontrolera, w tym pinów GPIO. W dokumentacji znajdziesz opis wszystkich klas z tego modułu. Kod, który napiszemy zostanie wykonany przez Micro Pythona - implementację języka Pythona napisaną specjalnie pod mikrokontrolery - gdzie nie ma systemu operacyjnego, a zasoby są ograniczone. Oznacza to że nie będziemy użyć wielu bibliotek i modułów do Pythona 3 (a na pewno nie te binarne). O bibliotece standardowej też możemy zapomnieć, bo na chwilę obecną dostępnych jest tylko kilka modułów.

Ograniczone zasoby mikrokontrolera, jak i brak systemu operacyjnego wymusiły więc duże zmiany w implementacji. Dostajemy kilka modułów, oraz składnię i to by było na tyle. W tle implementacja też czasami odbiega od CPythona, np. reprezentacji liczb, czy garbage collectora. Szczegóły implementacji autor Micro Pythona zaprezentował na poniższym wykładzie:

Micro Python może pracować na całej rodzine mikrokontrolerów Cortex M4 STM32 i czas pokaże czy i jakie inne płytki pracujące pod jego kontrolą zobaczymy. Może pojawią się porty na niektóre mikrokontrolery z rodziny mbed?

PyBoard w akcji

API modułu pyb wydaje się być łatwe w użyciu i całkiem przyjazne. Kod pisany dla pyMCU dość łatwo przenieść na MicroPythona podmieniając klasy i metody. Swego czasu pisałem o serwomechanizmach. Moduł pyb posiada gotową klasę do sterowania serwami. Na rogu płytki mamy piny od X1 do X4 i to one zapewniają modulację szerokości impulsów (PWM) do sterowania serwomechanizmem. Zasilanie i GND są tuż obok więc serwo łatwo podłączyć do trzech pinów jeden za drugim. Metoda angle ustawi serwo pod podanym kątem. Możemy wykorzystać akcelerometr by ustawienie serwa odpowiadało wychyleniu w jednej z osi:

import pyb
servo = pyb.Servo(1)
ac = pyb.Accel()
SCALE_MULTIPLIER = 3

while True:
  pyb.delay(250)
  servo.angle(ac.x() * SCALE_MULTIPLIER)

Serwo podłączone zostało do pinu X1 więc podajemy 1 jako wartość do konstruktora. Wartość z osi X akcelerometru mnożę razy 3 żeby zakres ruchu serwa był wyraźniejszy. Po uruchomieniu pętli wystarczy przechylać płytkę i obserwować ruch serwomechanizmu.

PyBoard z podłączonym serwomechanizmem

PyBoard z podłączonym serwomechanizmem

Pisałem też o wyświetlaczach LCD sterowanych za pomocą połączenia szeregowego. Zaprezentowaną tam klasę LCD bardzo łatwo przerobić na wersję dla Micro Pythona. Zamiast PySerial mamy pyb.UART:

import pyb


class LCD(object):
    END = chr(0xFF)

    def __init__(self, device, rows, columns):
        self.commands = {
            'display_string': chr(1),
            'set_cursor_position': chr(2),
            'clear_line': chr(3),
            'clear': chr(4),
            'set_lcd_type': chr(5),
            'backlight': chr(7)
        }
        self.device = device
        self.rows = rows
        self.columns = columns
        self.connection = None

    def configure(self):
        self.connection = pyb.UART(self.device, 9600)
        pyb.delay(1000)
        self.execute_command('set_lcd_type', chr(self.rows) + chr(self.columns))
        self.clear()

    def clear(self):
        self.execute_command('clear', '')

    def clear_line(self, line):
        self.execute_command('clear_line', chr(line))

    def set_backlight(self, brightness):
        self.execute_command('backlight', chr(brightness))

    def set_cursor_position(self, row, column):
        self.execute_command('set_cursor_position', chr(row) + chr(column))

    def display_string(self, string):
        self.execute_command('display_string', string)

    def close(self):
        self.connection.deinit()

    def execute_command(self, command, payload):
        self.connection.send(self.commands[command] + payload + self.END)

Zmiany zaszły w metodzie configure oraz execute_command, gdzie po prostu podmieniłem klasę i metody.

Wyświetlanie czegoś na wyświetlaczu wygląda tak samo jak w przypadku pyMCU bo interfejs klasy nie uległ zmianie:

def do_serial_demo():
    lcd = LCD(3, rows=4, columns=20)
    lcd.configure()
    lcd.set_backlight(25)
    accel = pyb.Accel()

    while True:
        lcd.clear()
        lcd.set_cursor_position(1, 1)
        lcd.display_string(str(accel.x()))
        lcd.set_cursor_position(2, 1)
        lcd.display_string(str(accel.y()))
        pyb.delay(500)

Wykorzystałem UART3 na pyboardzie bo go znalazłem jako pierwszego (TX na pinie Y9). Do testów użyłem dużego wyświetlacza 4x20. W pierwszym wierszu wyświetla się wychylenie osi X, a w drugim osi Y.

PyBoard obsługuje wyświetlacz LCD poprzez UART

PyBoard obsługuje wyświetlacz LCD poprzez UART

Na zakończenie

PyBoard i Micro Python obecnie oferują najlepsze wsparcie dla Pythona pośród płytek z mikrokontrolerami. PyMCU jest zależne od komputera, a nakładki na Arduino też wymuszają taką konfigurację (i nie pozwalają na wiele). Co prawda cena nie jest niska bo 30 funtów (około 160 zł), ale być może z czasem zacznie spadać, albo pojawi się firmware Micro Pythona dla płytek ST Nucleo z platformy mbed, które kosztują około 50 zł (czy też Chińczycy coś wymyślą).

blog comments powered by Disqus

Kategorie

Strony