Seznamujeme se s CyberPi (2)

Jeden z celkem dobrých důvodů, proč uvažovat nad CyberPi, je kromě jednoduchého rozhraní pro připojení dalších periférií také možnost programování v Pythonu. V tomto díle se na tuto možnost zaměříme.

Python je vysokoúrovňový programovací jazyk, oblíbený zejména díky příznivé křivce učení a širokými možnostmi použití. Pokud s Pythonem máte malé nebo žádné zkušenosti, doporučuji začít třeba na následujících stránkách:

Python existuje v řadě implementací a jednou z nich je microPython, implementace Pythonu určená zejména k programování mikrokontrolérů (např. STM32) a kompatibilní s jazykem Python 3. V tomto díle představení CyberPi se zaměříme na programování v microPythonu pomocí knihovny Cyberpi, které implementuje přístup k jednotlivým komponentům mikropočítače.

Začínáme

V předchozím dílu této minisérie jsem popisoval trable, které jsem zažil při prvním pokusu o naprogramování CyberPi prostřednictvím jazyka Python. Jedním ze zdrojů problému bylo nepochopení filozofie mBlock-Python editoru, který funguje trochu jinak, než je zvyklý uživatel programující ve Scratchi: v módu Živě totiž lze totiž pouštět i programy napsané v Python 3, i s použitím knihoven, které na mikropočítači ani nemohou běžet. A naopak, některé knihovny microPythonu nemají v desktopovém Pythonu ekvivalent.

Pro první krůčky s microPythonem je možné využít skvělou vlastnost mBlock editoru – náhled kódu, který odpovídá programu napsanému ve Scratchi.

Konverze mezi programem ve Scratchi a jeho implementací je vynikající zejména pro programátory, kteří již nějaké zkušenosti mají a zajímá je konkrétní implementace některých bloků nebo možnosti použití některých částí knihovny Cyberpi. Někdy to může být dokonce rychlejší než zkoumání dokumentace.

Ahoj CyberPi!

Jak začneme? Pochopitelně zvoláním Hello World!, nebo ještě lépe Ahoj CyberPi! V knihovně Cyberpi slouží pro základní práci s displejem třídy console a display, které poskytuje rozhraní (API) pro tisk textu. Nejjednodušší program by mohl tedy vypadat třeba takto:

import cyberpi
cyberpi.console.print("Ahoj CyberPi!")

Na pokročilejší práci s textem lze využít funkci show_label, která umožňuje umístit textovou informaci na určitou pozici nebo změnit velikost fontu.

import cyberpi
cyberpi.display.show_label('x', 10, 1, 1)

Funkce print a println z třídy cyberpi.console používají displej v režimu terminálu, již vytištěný text na displeji zůstává a pokud výpis informace dosáhne spodního okraje, text se automaticky odroluje. Funkce show_label pracuje v grafickém režimu: písmena volitelné velikosti (16, 24, 32) lze vykreslit na libovolnou pozici displeje udanou v pixelech, lze kreslit přes text vypsaný pomocí funkcí třídy cyberpi.console, ale je možné mít na displeji pouze jeden. Rychlost vykreslování není nijak vysoká, takže ani nelze příliš uvažovat o nějakých komplikovanějších výpisech. Přesto je možné efektně demonstrovat jednoduché algoritmizační úlohy. Následující příklad pohybuje znakem z levého horního rohu do pravého dolního, kde se odrazí a letí zpět. To vše se odehrává v těle nekonečné smyčky a znak během pohybu mění barvu pomocí funkce set_brush.

import cyberpi
# nekonecna smycka
while True:
    # pohyb z leveho horniho do prave spodniho
    for i in range(1, 120, 5):
        # zmena barvy, parametry funkce jsou RGB souradnice
        cyberpi.display.set_brush(2*i, 160, 80)
        cyberpi.display.show_label('o', 16, i, i)
    # pohyb z praveho dolniho do leveho horniho
    for i in range(1, 120, 5):
        cyberpi.display.set_brush(2*i, 160, 80)
        cyberpi.display.show_label('o', 16, 120-i, 120-i)

Kromě zmíněných funkcí lze data v textové podobě vykreslovat tabulovaně, je ale také možné data vykreslovat jako čárový, sloupcový nebo koláčový graf. Následující program červeně vykreslí jednu periodu harmonického signálu. Při kreslení je třeba zvážit několik aspektů kreslení na displej CyberPi:

  • návratová hodnota funkce math.sin je desetinné číslo v intervalu <-1,1>, aby se vykreslilo něco více než čára, je třeba výsledek vhodně škálovat, zde násobíme konstantou 20
  • protože půl periody harmonického signálu má zápornou hodnotu, je třeba celý signál posunout vhodnou aditivní konstantou, zde 60
import cyberpi, math

cyberpi.linechart.set_step(1)
cyberpi.display.set_brush(255, 0, 0)

for i in range(1, 360, 5):
    cyberpi.linechart.add(60+20*math.sin(6.28/360*i))

Vestavěné periferie

I bez připojených externích periferií lze využívat jako vstupy periferie vestavěné, zejména RGB LED diody, joystick a vestavěný reproduktor.

LED diody na boční straně CyberPi jsou přístupné pomocí metod třídy cyberpi.led. V následujícím příkladu se pokusíme o efekt známý ze seriálu Knight rider. Kromě rozsvěcování LED procvičíme také volání funkcí, ukážeme si jak zpomalit běh programu a nechat cyklus čítat od vyšších čísel směrem k menším. Zároveň vyzkoušíme i přehrávání hudebních vzorků pomocí metod třídy cyberpi.audio, takže získáme vlastně jednoduchý metronom (při troše dobré vůle 🙂

import cyberpi, time

def set_leds(i):
    time.sleep(0.2)
    cyberpi.led.off()
    if i > 1:
        cyberpi.led.on(255, 10, 15, i-1)        
    cyberpi.led.on(255, 0, 0, i)
    if i < 5:
        cyberpi.led.on(255, 10, 15, i+1)

    if i == 1 or i == 5:
        cyberpi.audio.play_drum('open-hi-hat', 0.25)
    else:
        cyberpi.audio.play_drum('closed-hi-hat', 0.25)

while True:
    for i in range(2, 6):
        set_leds(i)
    
    for i in range(4, 0, -1):
        set_leds(i)

Události

Poslední programovací technikou, na kterou se v tomto díle zaměříme, je použití událostí. Pro identifikaci událostí jsou zde použity tzv. dekorátory, které označují funkce pro zpracování události. Následující kód používá hned čtyři události:

  • event.start je spuštěn při startu programu, zde restartuje časovač
  • event.greater_than se vyvolá, pokud čas od posledního restartu časovače je delší než 0.1s
  • dvě různé události event.is_press se vyvolají, pokud se změní stav joysticku do očekávané podoby

Program umožňuje nastavovat dobu mezi dvěma různými událostmi, zde reprezentovanými přehrátím zvukového vzorku. Doba, která uplyne před tím, než se přehraje znova zvuk, je reprezentována globální proměnnou delay. Hodnotu této proměnné je možné měnit joystickem. Každých 0.1s program zkontroluje, zda doba od posledního přehrání není delší než delay a vynuluje se časovač.

import event, time, cyberpi

delay = 0.5
current = 0

@event.start
def on_start():
    cyberpi.timer.reset()

@event.greater_than(.1, 'timer')
def prehraj():
    global current, delay
    current += cyberpi.timer.get()
    cyberpi.display.show_label(str(delay), 16, 'center')
    if current > delay:
        cyberpi.audio.play_drum('open-hi-hat', 0.1)
        current = 0
    cyberpi.timer.reset()
    
@event.is_press('up')
def zpomal():
    global delay
    delay -= 0.1
    
@event.is_press('down')
def zryhli():
    global delay
    delay += 0.1

Závěr

Cílem druhého dílu bylo ukázat možnosti programování CyberPi v microPythonu. Je to určitě dobrá volba zejména v případě, kdy by se programy ve Scratchi staly značně nepřehlednými. V dalším dílu si ukážeme, jak používat externí periferie.

Eshop

Makeblock CyberPi Go Kit

Programovatelný mikropočítač, který je určen pro výuku IoT a Pythonu.

Leave a Reply