Workshop – MicroPython

Toto je první ze tří úvodních seznamovacích kurzů.

Pro základní pokusy s Micropythonem na ESP32 potřebujete „pouze“:
modul ESP32, do kterého si „naflashujete“ Micropython – což je pro mnohé začátečníky na delší dobu tou nejnáročnější částí kurzu.

Pro ulehčení další práce (a v některých ukázkách nezbytností) máme připravenou nadstavbu octopus(), kterou si společně s Micropythonem nahrajete a nakonfigurujete podle následujícího odkazu:
https://www.octopuslab.cz/micropython-octopus/

Připravujeme: Další možností bude objednat si už nachystaný modul ESP se základním firmware a ukázkovým software.

ESP32 – WROOM | Mikrokontrolér, kontrolér, nebo „známka“ – tyto všechny výrazy používáme pro označení „srdce“ používaného modulu, na kterém běží celý systém: MicropPython, programové moduly a knihovny, octopus() – vývojová nadstavba.
Pro první a druhý blok workshopů pracujeme s deskou ROBOTboard – pro její jednoduché základní sestavení a možnost postupného rozšiřování a doplňování, ale pro úvodní seznámení ji vůbec nepotřebujete, pouze urychlí práci s některými periferiemi.
Doplňkové informace o nastavení PINů - jak máme v ukázkách použity:

oeLAB-esp32 (DoIt) 2x15 pins:                                [ROBOT Board]:::
                           -----------     (GPIO)
                       EN -           - D23 (23)  MOSI       [SPI_MOSI_PIN]
[PIN_ANALOG]     (36)  VP -           - D22 (22)  SCL(I2C)   [I2C_SCL_PIN]
[I39_PIN]        (39)  VN -           - TXD (1)   D2
[I34_PIN]             D34 -           - RXD (3)   D3
[I35_PIN]             D35 -           - D21 (21)  SDA(I2C)   [I2C_SDA_PIN]
[ONE_WIRE_PIN]   DEV1 D32 -           - D19 (19)  MISO       [SPI_MISO_PIN]
              T8 DEV2 D33 -  (ESP32)  - D18 (18)  SCLK       [SPI_CLK_PIN]
[MOTOR_12EN]          D25 -           - D5  (5)   CS0        [SPI_CS0_PIN]
[MOTOR_1A]            D26 -           - TX2 (17)             [PIN_PWM1] /Servo1
[MOTOR_4A]    T7      D27 -           - RX2 (16)             [PIN_PWM2] /Servo2
[MOTOR_3A]    T6      D14 -           - D4  (4)          T0  [PIN_PWM3] /Servo3
[MOTOR_2A]    T5      D12 -           - D2  (2)          T2  [BUILT_IN_LED]
[MOTOR_34EN]  T4      D13 -           - D15 (15)         T3  [WS_LED_PIN] //v1(13)     
                      GND -           - GND
                      VIN -           - 3V3 +
                           -----------


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 „terminál“ / příkazové řádky: putty nebo screen (Linux)
Někdy potřebujeme jednoduchý ovladač – USB>UART)

  • 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.

Většina našich zdrojových kódů je 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á minimálně 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.


Jednotlivé ukázky se v mezích možností snažíme dělit na: 

  [Základy] 
Jedním nebo občas i několika po sobě jdoucími příkazy pouze "komandujeme" ESP mikrokontroler s připojenými periferiemi. Jedná se o základní  "početní úkony" a jednoduché metody práce s HW, ovládání LED (svítivé diody), RGB (barevné diody), piezo, jednoduchý podprogram... 

  [Lehce pokročilejší] 
HW: Displeje a základní čidla... a mechatronika: servo motor 
SW: Podrobnější vysvětlení  (větvení programu - podmínka, cyklus, ...) > jednoduché projekty, hry a aplikace.

   [Trochu náročnější]  
Pokud se toho bojíte, ani na to nekoukejte. Další programátorská teorie: pole, seznamy, slovníky a složité datové struktury... a speciální návody.
    [Náročné] 
Nic podobného Vám v tomto bloku neukážeme :-P 

  [Poznámka] ...nebo tak.
  [Zajímavost] Tady by to mohlo být modré celé
 [Pozor!] Nechceme nikoho stresovat, proto to moc nevyužijeme :-P

Připojení

  • v prvním díle pouze po sériové lince pomocí USB kabelu
    (hned ve druhém pokračování zkusíme webrepl)
  • počítač slouží pouze jako „terminál“ – všechno se děje v mikrokontroléru ESP32, který s námi komunikuje po sériové lince
  • proto potřebujeme převodník USB > UART
Po propojení by se měla rozsvítit červená signalizační LEDka na ESP32
(Tato svítivá dioda nás pouze informuje o tom, že je připojeno napájení a svítí po celou dobu)
Modrá kontrolní LEDka a barevná RGB LED je pod naší kontrolou.
Tlačítko boot se dá také použít – což si ukážeme v dalším díle.

První spuštění

Po restartu nám ESP32 posílá do našeho počítače na terminál první zprávy.
Zeleně jsou systémové inforamce, které nás v tuto chvíli nezajímají.
Po stisknuté CTL+C uvidíme verzi Micropythonu
MicroPython v1.11-180-g8f55a8fab-dirty-build-octopusLAB on 2019-07-29; 
module with ESP32                                                                                                             
Type "help()" for more information. 



--------------------------------------------------------
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
-------------------------------------------------------- 

Nastavení

Pokud máme ESP již připraveno (to znamená, že je tam nahraný Micropython i základní octopus systém). Je nutno pouze individuálně nakonfigurovat podle HW požadavků (a možností) a donastavit některé další drobnosti – např. připojení k WiFi.

Rovnou si zkusíme


>>>              ">>>" 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            vytiskne / zobrazí hodnotu proměnné 
123              nebo print(a) 
                
>>> 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ý                 



Více řádkové "dočasné definice vlastních funkcí":
def suma(x, y):  def název(parametry): nezapomenout na dvojtečku!
... return x + y

>>> suma (1, 2)
3

*) 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

 
Lambda - pro jednoduché funkce:
>>> sumaL = lambda a, b: a + b
>>> sumaL(1, 2)
3          










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

Velmi stručně o Pythonu:

  • logické členění se provádí pomocí striktního odsazování bloků
  • pozor na závorky u metod a funkcí > print(„řetězec“) a uvozovky pro takzvané řetězce (shluky písmen, co nejsou číslo)
  • pozor na dvojtečku za deklarací funkce, cyklu nebo podmínky:
    def fce(parametr):
    … co se má dělat

    if (podmínka):
    … co se má dělat při splněné podmínce

    while True: > toto je nekonečná smyčka
    dělej, dokud je splněna podmínka
    zde: pořád


HW hello world -> LED

Rozsvícení LED diody > ovládání / blikání

Pro rozpojování nebo spojování obvodu se použije spínač – ale co když chceme ovládat zařízení na dálku? Nebo chceme, aby LED „sama“ pravidelně“ blikala? Nebo aby se rozsvítila, když se setmí?

Inicializace knihovny pro práci s HW

Modul/knihovna octopus() je základní rozšíření Micropythonu pro práci s octopusLAB moduly a připojenými periferiemi. Zjednoduší uživateli nastavení (již provedeno v setup() - a zpřehlední začátečníkům jednoduché experimenty.
Pro pokročilejší - slouží jako hlavní modul, který se využívá i ve složitějších programech. 
Její instalcae je popsána v  https://www.octopuslab.cz/micropython-octopus/ 

 
>>> octopus()
   ,'''`.
  /      \
  |(@)(@)|
  )      (
 /,'))((`.\
(( ((  )) ))
)  \ `)(' / (
(octopus lib.ver: 8.7.2019)
This is basic library, type o_help() for help

Ovládáme LED diodu:
>>> led.value(1)  po odeslání (enter) by se měla rozsvítit dioda
>>> led.value(0)  a zde opět zhasnout


"Blikáme LEDkou" hned několika způsoby:
>>> while True:
... led.value(1) 
... sleep(1)
... led.value(0)
... sleep(1) 

> ctrl+C (pro přerušení běhu programu)

>>> while True:
... led.value(not led.value())
... sleep(0.5)  

for _ in range(10):
…    blink(led,1000,1000)
…

Pípání piezzo měničem (buzzer):
(na ROBOTboard je ozazen na 4A [pin 27] a zem - na místo L293)
 
>>> beep()            základní pípnutí (1000,50)
>>> beep(440,500)     komorní a na 0.5 s
>>> tone(440)         = buzzer.play_tone(Notes.A4)
>>> Notes.A4 > 440    k dispozici jsou tóny C3-C7

>>> from util.buzzer import melody
>>> piezzo.play_melody(melody.mario)

Objekty
-> instance – metody – parametry

Všechno v Pythonu je objekt. 
Základní vlastnost objektů je to, že obsahují jak data (informace), tak chování – instrukce nebo metody, které s těmito daty pracují. 
 

led.value(1) > instance objektu "tečka" metoda "( parametry )"

chceme jinou Led? Na jiném pinu? Vytvoříme instanci objektu:
led2 = Led(pin) > a pak jí používáme "stejně": led2.value(1) 

na rozdíl od proměnné:
a = 123
Medotoda nebo funkce data získá nebo na základě parametrů zpracuje, proměnná je obsahuje.



dir(led)
['class', 'init', 'module', 'qualname', 'value', 'dict', 'pin', 'blink', 'toggle', 'state']

>>> led.pin
> Pin(2)                 přednastaveno, na ESP32 modulu je BUILT_IN_LED 
                         na pinu 2
>>> led.state
> False
>>> led.value(1)
>>> led.state
1

. >TAB nabídka metod 
Micropython má obrovskou výhodu v tom, že běží jako interpret: když uživatel napíše název proměnné nebo instance objektu, skoro všechno se o nich můžeme dozvědět. 
Napište "led" . (tečka) a stiskněte TAB
led.
class       init        module      qualname
value           dict        pin             blink
toggle          state
led. 

>>>  šipky nahoru nebo dolů  -> historie příkazů         
  
 http://docs.micropython.org/en/latest/esp32/quickref.html 

WS- RGB barevná LED dioda


>>> ws.test()             problikne R G B cca - default 500ms
>>> ws.test(100)          s parametrem 100ms
>>> ws.color(BLUE)        zobrazení barvy, RED/GREEN/BLACK je černá
>>> ws.color((128,0,0))   parametr color je (128,0,0) 
>>> ws.rainbow_cycle()    "projedou barvy" duhy 


ws na jiném pinu?
>>> ws2 = Rgb(pin,num)       > číslo pinu a počet LEDek

>>> ws.color(5,RED)      > při LED pásku  > nastavení páté na RED 
                         




Displeje


8 x 7-mi segmetový displ7:
>>> d7 = disp7_init()      nezbytná inicializace: 
                           mikrokontroléru se "sdělí", 
                           který displej používáme, 
                           ten si ho připojí a vyzkouší 
                           a předá nám instanci objektu
   
>>> d7.show(123.456)       > zobrazení čísla
>>> d7.show("ahoj")        > omezené zobrazení řetězce 


lcd
>>> d = lcd2_init()          
                           
i2c_scann() > devices:
[39]
display test: octopusLAB  na displeji by se měl ukázat text

>>> for i in range(10):
       ...  d.clear()     smaže displej / jinak se přepisuje 
       ...  disp2(d,i)
       ...  sleep(1)

>>> disp2(d,text,1,6)    zobrazí "text" na pozici 1 = 2. řádek, první je 0
                         a na 5. sloupci (první je opět 0) 


 
oled:
>>> o = oled_init()
>>> oled(o,txt)

>>> oledSegmentTest(o)

>>> o.fill(1)
>>> o.show()

>>> o.hline(x, y, h, color) 
>>> o.vline(x, y, w, color)   
  

>>> def onePoint(x,y): 
...    o.pixel(x,y,1) 
...    o.show()
...  

>>> from assets.icons9x9 import ICON_clr, ICON_heart
>>> o.draw_icon(ICON_heart,115,15) 

>>> def heartBeat()               
...    o.draw_icon(ICON_heart,115,15)
...    sleep(1)
...    o.draw_icon(ICON_clr,115,15)                 
...    sleep(1)
...
Na stejnou vývojovou desku se dá snadno připojit několik různých displejů

Další zajímavé informace

  • Ukázky dalších importů, složitějších konstrukcí. Některé akce mohou při špatném provedení být „destruktivní“ – zničí se základní FW systém a bude nutno provést znovu celou inicializaci systému od esptool.erase + flash.micropython… až po rozbalení a nakonfigurování.
    Ale NE – neuvedeme zde příklady: „toto nedělejte“ 😛

>>> i()        basic info obsahuje zajímavé informace - zde IoT board:
[--- device ---]
config/device: {"board_type": "oLAB IoTBoard1", "soc_type": "esp32"} 
 
[--- pinout ---]
<module 'pinouts.olab_esp32_iot_board1' from 'pinouts/olab_esp32_iot_board1.py'> 
[--- io_conf ---]
{'led': 1, 'led7': 1, 'oled': 1, 'button': 1, 'temp': 1, 'ws': 8}

f('pinouts/olab_esp32_iot_board1.py') zobrazí aktuálně nastavený pinout 
(přímo ze souboru)

dostupné metody třídy Led:
>>> dir(led)
['class', 'dict', 'init', 'module', 'qualname', 'pin', 'value', 'blink', 'state', 'toggle']         
 
   
standard lib. functions:
čekací prodlevy:   > program bude pokračovat až po uplynutí dané doby 
sleep(1)           > 1 sekund pauza
sleep_ms(100)      > 100 mili ses 
sleep_us(500)      > 500 micro sec


rozšíření RGB: 
from util.rgb import wheel   > konvertuje číslo na posouvané RGB
wheel(10)
> (225, 30, 0)   test, vypíše RGB hodnoty
wheel(50)
> (105, 150, 0) 


   
 standardní knihovna esp32:
>>> import esp32
>>> esp32.raw_temperature()

127
>>> esp32.hall_sensor()
129                           > cca standard hodnota
>>> esp32.hall_sensor() 
976                           > po přiložení magnetu 
 

Ukázky web – api

Bez dalšího komentáře uvádíme některé naše ukázky, na kterých vysvětlujeme možnosti vzdáleného připojení ale především rizika připojení nezabezpečeného - některé metody dostupné v octopus() - a následně ukázková stránka na našem serveru:

>>> getApiJson()  
http://www.octopusengine.org/api/onoff.php 
on/off - nezabezpečeno, GETem, bez ID - bezpečnostní chyby
message - POSTem, MD5(UID), "device" jen pro kontrolu

>>> getApiText()  
https://octopusengine.org/api/text19.php 
trochu lepší - https, zabezpečeno alespoň s heslem ) ale "veřejným"
a také už dbáme na ID zařízení, které může sloužit i jako heslo pro přístup do "IoT sítě" (proto UID pokud nemusíme - veřejně neuvádíme)

>>> SetApiValue() 
připravujeme, ale můžete si zkusit sami - aktuální hodnoty (nebo i log či instalované verze systému) pak uvidíte v aplikaci - zatím je to ve fázi hrubé rozpracovanosti:
https://www.octopusengine.org/api/last.php

Máme vlastní otestovanou binárku Micropythonu – snažíme se držet aktuální: https://www.octopusengine.org/download/micropython-octopus1907.bin

Odkazy

Pro zvídavé pár dalších odkazů:
http://docs.micropython.org/en/latest
http://docs.micropython.org/en/latest/esp32/quickref.html

https://github.com/micropython/micropython
https://github.com/micropython/micropython-lib

https://github.com/mithru/MicroPython-Examples
https://www.hackster.io/projects/tags/micropython
https://docs.pycom.io/gettingstarted/programming/examples