Toto je první díl ze tří – úvodního kurzu Micropython na ESP32. Nejedná se ani o výuku programování, ani o úzké zaměření na elektroniku. Naší snahou je jednoduchou formou přiblížit aktuální možnosti elegantních a dostupných zařízení. Pokud si po přečtení článku i něco sami vyzkoušíte, určitě vám to přinese víc.
Několik let se zaměřujeme na vývoj elektronických zařízení – a naši pozornost neustále směrujeme k nejmodernějším technologiím. Zabýváme se virtuální realitou, umělou inteligencí, zařízeními pro internet věcí, technologií blockchainu, mechatronikou a robotikou… Řešíme hardware i software a pokaždé přemýšlíme, jak si co nejvíce usnadnit práci. Jak zefektivnit výrobu prototypů a jak přilákat nové zájemce o toto nové a ne úplně jednoduché odvětví. Vytvořili jsme proto elektronické moduly i programové rozhraní, které sami efektivně využíváme.
Námi navržené vývojové a experimentální moduly slouží i jako finálně zapojitelné prvky pro projekty nebo jejich části. Jednoduché (nebo částečně zapojené) projekty výborně pomáhají i při výuce.
Představeno v článku: https://chiptron.cz/articles.php?article_id=233
Na co se v tomto díle zaměříme?
1. HW – ESP32
2. FW – Micropython
3. SW – Začínáme – ukázky programování elektronického zařízení
Pro základní pokusy s Micropythonem na ESP32 potřebujete „pouze“ modul ESP32, do kterého si „naflashujete“ Micropython. Zní to jednoduše, ale pro mnohé začátečníky je to tou nejnáročnější částí kurzu.
Pro ulehčení další práce jsme připravili modul se souborem knihoven, který nazýváme octopus(). V dalších ukázkách už bude nezbytný.
Tento modul si společně s Micropythonem nahrajete a nakonfigurujete podle následujícího odkazu: https://www.octopuslab.cz/micropython-octopus/
1. ESP 32 – WROOM
Na destičce o velikosti poštovní známky je mikrokontrolér spolu s několika klíčovými komponenty včetně krystalu, leptané antény a impedančního přizpůsobení. Tím usnadňují použití ESP32 a jsou okamžitě připraveny k integraci do koncových produktů.
ESP32 má:
- dvě CPU jádra s nastavitelnou taktovací frekvencí do 240 MHz
- klasické Bluetooth i podporu Bluetooth Low Energy (BLE)
- 4MB Flash paměť
- 3 bloky paměti RAM v celkové velikosti 520kB
- periferie zahrnují kapacitní dotykové senzory, Hallův snímač, zesilovač s nízkým šumem, rozhraní pro SD kartu, Ethernet, vysokorychlostní SPI, UART, I2S a I2C
Takže má dostatečný výkon, aby na něm mohl běžet i robustnější systém, jako je Micropython.
2. Micropython
Micropython je zjednodušenou verzí programovacího jazyka Python. Je to open-source převážně psaný v jazyce C. Jeho zdrojové kódy jsou dostupné na: https://github.com/micropython/micropython
Poznámka: Toto není výuka Micropythonu – ale jen ukázky a experimenty s přihlédnutím na interakci s vybraným HW. Pro podrobnější proniknutí do tajů programování v Pythonu doporučujeme:
> https://naucse.python.cz/
> https://naucse.python.cz/course/mi-pyt/intro/micropython/
> http://howto.py.cz/index.htm
Základní ukázky a experimentování se provádí v interaktivním modu.
To znamená, že mikrokontrolér vykonává přímo příkazy psané v Pythonu (aniž by je kompiloval) a ke komunikaci využíváme emulátor terminálu (příkazové řádky) putty nebo screen (v Linuxu a pro Mac)
- výhoda: jednoduché, nemusí se kompilovat a hned běží
- nevýhoda: drží se v paměti jen po dobu napájení, po vypnutí se vše „zapomene“ – a tak není vhodné pro složitější programy nebo větší projekty s více soubory.
Řešení: programovat mimo kontroler a až pak program nahrát jako soubor nebo spustit přes ampy run, případně přes webrepl.
3. Začínáme – první pokusy
Klávesové zkratky terminálu, které budeme občas potřebovat:
základem je CTRL-C pro přerušení běžícího programu
a CTRL-D pro soft reset kontroléru, celý přehled z helpu:
-------------------------------------------------------- Control commands: CTRL-A -- on a blank line, enter raw REPL mode CTRL-B -- on a blank line, enter normal REPL mode CTRL-C -- interrupt a running program CTRL-D -- on a blank line, do a soft reset of the board CTRL-E -- on a blank line, enter paste mode -------------------------------------------------------- REPL = Read–eval–print loop
Rychlý úvod do Pythonu
>>> ">>>" toto je takzvaný "prompt", terminálová výzva, abychom tam něco napsali: příkaz nebo "posloupnost příkazů" >>> a = 123 do proměnné se uložila hodnota (číslo 123) >>> a 123 vytiskne / zobrazí hodnotu proměnné nebo print(a) pokud to chcete použít v programu >>> a + 10 133 zobrazí vypočtenou hodnotu (jako kalkulačka) někdy chceme složitější matematické výrazy, než je + sčítání - odčítání * násobení / dělení >>> import math importujeme knihovnu, až když jí potřebujeme, jinak nám zbytečně blokuje operační paměť >>> math.log10(1000) 3.0 >>> math.pi 3.141593 počet desetinných míst je omezený *) pouze v této úvodní části jsme naznačili, co píše systém (tučně) a co píšete vy (normálně) - poznámky pak píšeme šikmo >>> šipky nahoru nebo dolů -> historie příkazů >>> metoda + tečka > TAB doplnění / nápověda zkuste například: >>> import math >>> math. a po tečce stisknout TAB > vypíše vám: __class__ __name__ pow acos acosh asin asinh atan atan2 atanh ceil copysign cos cosh degrees e erf erfc exp expm1 fabs floor fmod frexp gamma isfinite isinf isnan ldexp lgamma log log10 log2 modf pi radians sin sinh sqrt tan tanh trunc Micropython má obrovskou výhodu v tom, že běží jako interpret: když uživatel napíše název proměnné, třídy nebo instance objektu, skoro všechno se o nich můžeme dozvědět. Právě proto máme k dispozici všechny metody, po "tečka TAB". TAB tedy slouží i jako "nápověda" nebo pro efektivní našeptávač pro dokončování příkazů, což s jistou praxí může znatelně urychlit práci z "komand-lajny" (podobně jako v Linuxu)
Nové funkce se dají definovat z příkazové řádky
Více řádkové "dočasné definice vlastních funkcí": def název(parametry): nezapomenout na dvojtečku! >>> def suma(x, y): ... return x + y Pozor na odsazení druhého řádku a důsledné zarovnávání logických bloků. Ukončení definice lze nejrychleji "uENTRováním" (lépe po BACKSPACE). ... ... >>> a zkusíme, jak nám nová funkce funguje: >>> suma (1, 2) 3 Lambda - pro jednoduché funkce: >>> sumaL = lambda a, b: a + b >>> sumaL(1, 2) 3 Jsou situace, kde je potřeba funkce na jedno použití někde uvnitř jiné funkce. Převážně k tomu se lambda funkce používá. Nám se to ale může hodit pro rychlé jednořádkové definice z konzole.
Standardní knihovna a knihovna esp32
některé základní funkce z standardní knihovny
čekací prodlevy:
program bude pokračovat až po uplynutí dané doby
from time import sleep > již je v octopus()
sleep(1) > 1 sekunda pauza
sleep_ms(100) > 100 mili sec
sleep_us(500) > 500 micro sec
teplota u procesoru:
>>> import esp32
>>> esp32.raw_temperature()
127
hallova sonda - magnetického pole:
>>> import esp32
>>> esp32.hall_sensor()
129
cca standard hodnota
>>> esp32.hall_sensor()
976
po přiložení magnetu
Ještě drobná vsuvka - cykly a podmínky zmíníme v další části, ale už nyní používáme jednu základní formu: "nekonečný cyklus" while podmínka: ... prováděj_pokud_je_splněná_podmínka() a = 0 while True: ... a += 1 ... print(a) v nekonečné smyčce maximální rychlostí vypisuje obsah zvětšující se proměnné "a"
Pro další práci už využijeme i octopus()
Pokud máte octopusLAB verzi Micropythonu, máte ulehčenou práci – stačí zadat: octopus_initial.setup()
pak nastavit wifi, připojit se a následně z cloudu stáhnout celý systém.
Vše bylo již popsáno v návodu instalace systému.
Objektové programování? Trochu teorie:
Všechno v Pythonu je objekt. Základní vlastností těchto abstraktních objektů je to, že obsahují jak data (informace), tak chování – instrukce nebo-li metody, které s těmito daty pracují. To se nám náramně hodí pro zjednodušení programování objektů reálného světa.
To, co je pro programátory základní úlohou "zobrazit HELLO WORLD", je ve světě číslicové techniky "blikání LEDkou". Svítivou diodu (LED) vám podrobněji představovat asi nemusíme. Stačí vědět, že je to malá elektronická součástka, kterou když teče proud - tak svítí.
V Pythonu pak můžeme mít vytvořen objekt "Led" (s velkým počátečním písmenem) jehož definice vychází z obecného objektu Pin. A my si k němu přidáme další metody, které se nám v projektech mohou hodit - například "blink()" pro blikání - metoda má závorky, buď prázdné nebo s případnými parametry.
Pak bychom si práci s periferiemi představovali nějak takto:
led = Led() vytvoření instance objektu Led
led.value(1) > instance objektu "tečka" metoda "( parametry )"
zde: hodnota (value) s parametrem 1 znamená, že se LEDka rozsvítí.
Chceme jinou Led? Na jiném pinu? Vytvoříme instanci objektu:
led2 = Led(pin) > a pak ji používáme "stejně":
led2.value(1)
Na rozdíl od proměnné: "a = 123" metoda nebo funkce data získá nebo na základě parametrů zpracuje, proměnná je obsahuje.
Blikáme, pípáme – základ práce s periferiemi
Práce s octopus() „modulem“ s ROBOTboard
Toto je jen ukázka - jak se dají ovládat základní periferie, v dalších dílech se s některými seznámíme blíže.
octopus() nezapomínejte spustit hlavní modul knihoven po každém novém zapnutí a po resetu Ukážeme si tři základní třídy: Led, Buzzer a Rgb včetně odkazů na zdrojové kódy třída Led > zdrojový kód led = Led(2) instance objektu Led s defaultním nastavením na pinu 2 (což je BUILT_IN_LED - vestavěná modrá LEDka) led.value(1) nastavení hodnoty na "1" - dioda svítí led.value(0) nastavení hodnoty na "0" - dioda nesvítí blikání poprvé: while True: ... led.value(1) ... sleep(1) ... led.value(0) ... sleep(1) led.value() bez parametru vrátí hodnotu nastavení - nyní tedy: 0 led.toggle() "přepnout" > změní stav - nyní tedy z 0 na 1 blikání podruhé: while True: ... led.toggle() ... sleep(1) led.blink() metoda pro jedno bliknutí blink() default parametry: 1s svítí a 1s nesvítí (což si sami najdete ve zdrojových kódech) led.blink(1000,500) metoda blink (s parametry: 1s svítí a 0.5s nesvítí) parametr se zadává v milisekundách blikání potřetí: while True: ... led.blink() a právě tento příklad máme jako základní ukázku ve složce "examples": https://github.com/octopusengine/octopuslab/blob/master/esp32-micropython/examples/blink.py led2 = Led(33) instance objektu Led na pinu 33 ... třída Buzzer > zdrojový kód piezzo = Buzzer(18) piezzo.beep() napřímo přes octopus(): beep() základní pípnutí (1000,50) > 1kHz na 50ms beep(440,500) komorní a 440Hz na 0.5s from util.buzzer import notes Notes.A4 440 k dispozici jsou tóny C3-C7 tone(440) => buzzer.play_tone(Notes.A4) from util.buzzer import melody piezzo.play_melody(melody.mario) třída Rgb > zdrojový kód ws = Rgb() deklarace základu je provedena už spuštěním octopus() ws = Rgb(32,8) na pinu 32 máme 8 ws LEDek ws.num 8 nám vrátí property (vlastnost, proměnnou: počet LEDek), a vrátí 8, protože jsme nastavili 8 (systém to jinak nepozná) ws.simpletest() jednoduchý test, na první LED postupně R > G > B ws.color(RED) ws.color((128,64,0)) možnosti zadání barvy from util.rgb import wheel metoda wheel konvertuje číslo na posouvané RGB >>> wheel(10) (225, 30, 0) >>> wheel(50) (105, 150, 0) chceme blikat náhodnými barvami? from util.rgb import random_color while True: ... ws.color(random_color()) ... sleep(0.3) ....
Barva podle tweetu?
Pokud jste si stáhli octopus-verzi Micropythonu a nastavovali WiFi podle návodu, využijeme skvělé vlastnosti robustnějšího systému (oproti C). Micropython umí pracovat se soubory, a přímo pracovat nejen se řetězci znaků, ale i s json formátem nebo jednoduchou databází. Všechny nastavené WiFi jsou tedy strukturovaně uložené ve vašem ESP v json-souboru: config/wifi.json chcete vidět co tam je? Zadejte: (octopus() nemusíte pokaždé, stačí jen po restartu, ale start navíc ničemu neublíží, RAM se průběžně optimalizuje automaticky) octopus() f("config/wifi.json") f jako file vám obsah souboru vypíše Pro připojení k wifi nám stačí: octopus() w() Na závěr dnešního dílu si ukážeme využití "api třetích stran" - webovou aplikaci, která aktualizuje RGB nastavení podle twitteru: http://api.thingspeak.com/channels/1417/field/2/last.txt Když publikujete například zprávu: #octopusLAB and #micropython example #cheerlights orange výše uvedený odkaz zaktualizuje svůj stav na poslední publikovanou barvu za hashtagem #cheerlights do knihoven octopus (ve složce ukázek examples) jsme implementovali jednoduchou metodu twitter_rgb(), takže vám stačí zadat pouze pár řádků: >>> octopus() >>> w() >>> from examples.twitter_rgb import twitter_rgb >>> ws.color(twitter_rgb()) inicializace octopus, připojení k wifi, natažení knihovny a jednorázové spuštění příkazu a RGB LEDka vám svítí podle posledního tweetu Pokud chcete průběžnou aktualizaci, nedávejte to v nekonečné smyčce bez prodlevy, server umlátíte nereálným http dotazováním několikrát za vteřinu, což je krok regulernímu DDoS útoku (Distributed Denial of Service) takže vás záhy nejspíš odpojí :-) Ptal bych se nejrychleji jednou za 10 vteřin, lépe tak jednou za minutu. while True: ... ws.color(twitter_rgb()) ... sleep(30) kompromis, každých 30 vteřin, stejně rychleji tweetovat nebudete zdrojový kód > https://github.com/octopusengine/octopuslab/blob/master/esp32-micropython/examples/twitter_rgb.py
Většina našich zdrojových kódů je opensource – a aktualizována na:
https://github.com/octopusengine/octopuslab/tree/master/esp32-micropython
Možná vám je znám fakt, že pokud psaní kódu trvá jednotku času, tak jeho testování a odladění trvá často i trojnásobek času – a sepsání dokumentace je někdy ještě náročnější.
Navíc se jedná o nekončící proces vývoje, kdy se průběžně obměňuje část knihoven a ukázek… proto prosíme o shovívavost – a když už naleznete nějakou nesrovnalost, budeme vám vděčni, pokud nás na ní upozorníte. Samozřejmě že i spolupracovníky a další tvůrce velmi přivítáme.
Odkazy
http://docs.micropython.org/en/latest/esp32/quickref.html https://naucse.python.cz/ https://naucse.python.cz/course/mi-pyt/intro/micropython/ http://howto.py.cz/index.htm https://www.octopuslab.cz/vyvojove-desky/robot-board/ https://chiptron.cz/articles.php?article_id=233 https://www.dfrobot.com/blog-692.html https://www.octopuslab.cz/micropython-octopus/ https://www.octopuslab.cz/workshop-micropython1/ https://www.octopuslab.cz/workshop-micropython2/ https://www.octopuslab.cz/workshop-micropython3/ https://www.octopuslab.cz/micropython-web-ide/ https://www.octopuslab.cz/upyshell/ https://www.octopuslab.cz/micropython-octopus-help/ https://www.octopuslab.cz/examples1/