MicroPython a IoT

Úvod

Embedded system, vestavěný systém (zabudovaný systém) je jednoúčelový systém, ve kterém je řídicí počítač zcela zabudován do zařízení, které ovládá. Jestliže zařízení mezí sebou komunikuji, může tvořit základ IoT.

Internet věcí (anglicky Internet of Things, zkratka IoT) je v informatice označení pro síť fyzických zařízení, vozidel, domácích spotřebičů a dalších zařízení, která jsou vybavena elektronikou, softwarem, senzory, pohyblivými částmi a síťovou konektivitou, která umožňuje těmto zařízením se propojit a vyměňovat si data. Každé z těchto zařízení je jasně identifikovatelné díky implementovanému výpočetnímu systému, ale přesto je schopno pracovat samostatně v existující infrastruktuře internetu.

BBC micro:bit

BBC micro:bit je mikropočítač, který vznikl v britském univerzitním prostředí jako výuková platforma. V roce 2016 byl tento kit rozdán zdarma všem žákům 7. tříd (11-12let) ve Velké Británii. Po doplnění vnějšími obvody může měřit fyzikální veličiny, sbírat data nebo ovládat rozličné akční členy (elektromotorky, serva atd.) a je tedy vhodným prvkem pro zapojení do internetu věcí (IoT).

Micro:bit je založen na obvodu SoC (system on a chip) firmy Nordic nRF51822 s 32‑bitovým procesorovým jádrem ARM Cortex‑M0 a komunikačním rozhraním Bluetooth. Obsahuje 256 kB paměti Flash a 16 kB paměti SRAM.

Programování BBC micro:bit

  1. Blocks - Javascript: https://makecode.microbit.org
  2. Python - Mu IDE: Code With Mu https://codewith.mu
  3. Python - Thonny IDE: https://thonny.org

MicroPython je (re)implementace Python pro zabudované zařízení. Implementovaná s limitovanou množinou knihoven. Podporované platformy najdete např. zde: https://www.bc-robotics.com/product-tag/micropython/

Více informace o MicroPython: https://micropython.org.


Text a obrázky na matici LED

Úkol 1

Zobrazte na matici LED např. text "Ahoj lidi!" nebo smajlíka!

Úkol 2

Pomocí cyklu zobrazte odpočítání 9 až 0 v sekundových intervalech!

Inspiraci můžete čerpat z následujícího kódu:

from microbit import *
 
# Text...
display.scroll('Hello!')
 
# ...obrázek...
display.show(Image.HEART)
sleep(2000)
 
# ...znak...
display.show('Q')
sleep(2000)
 
# ...a číslo
a = 6
display.show(str(a))


Úkol 3

Rozsvěcujte a zhasínejte jednotlivé LED-y!

Co bude výsledek běhu následujícího programu?

from microbit import *
from random import *
 
display.clear()
while True:
  display.set_pixel(randint(0, 4), randint(0, 4), 9)
  sleep(700)
  display.set_pixel(randint(0, 4), randint(0, 4), 0)
  sleep(700)

Jak změníme kód aby se vždy rozsvítilo jen jeden náhodný bod?


Zkuste odhadnout, co definuje znakový řetězec - parametr použitý při vytvoření instance Image

from microbit import *
okno = Image('99999:90909:99999:90909:99999')
display.show(okno)


Úkol 4

Vytvořte ikony - jednotlivé strany hrací kostky zobrazující 1 až 6 bodů!

Animace

from microbit import *
 
# hotový seznam obrázků
display.show(Image.ALL_CLOCKS, loop=True, delay=100)

from microbit import *
 
# seznam obrázků
smileys = [Image.HAPPY, Image.ANGRY, Image.SAD, Image.CONFUSED, Image.ASLEEP]
display.show(smileys, loop=True, delay=200)


Úkol

Zobrazte na matici LED jednoduchou animaci!

Tlačítka - ovládání

Příklad kódu:

from microbit import *
 
while True:
    if button_a.is_pressed():
        display.show(Image.HAPPY)
    elif button_b.is_pressed():
        break
    else:
        display.show(Image.SAD)
display.clear()


Úkol 1

Na matici LED zobrazte světelný bod. Po stisknutí tlačítka A resp. B ho posuňte doleva resp. doprava! Po stisknutí obou tlačítek posuňte bod doprostřed.

Úkol 2

Naprogramujte hru kámen, nůžky a papír - nechť po stisknutí tlačítek A, B a současně A i B se zobrazí jedna ze třech ikon.

Zvuky

Samotná destička micro:bit není schopen vydávat zvuky. Budeme tedy potřebovat přídavnou desku s piezoměničem

Nejjednodušším způsobem je rychlé střídání logických úrovní na výstupu 0.

from microbit import *
 
while True:
    pin0.write_digital(1)
    sleep(10)
    pin0.write_digital(0)
    sleep(100)

Jednodušší je ovšem použít knihovnu music a nastavit přímo frekvenci…

import music
 
while True:
    for freq in range(880, 1760, 16):
        music.pitch(freq, 6)
    for freq in range(1760, 880, -16):
        music.pitch(freq, 6)

…nebo definovat melodii pomocí hudební notace:

from microbit import *
import music
 
tune = ["C4:4", "D", "E", "C", "C", "D", "E", "C", "E", "F", "G:8",
        "E:4", "F", "G:8"]
music.play(tune)
sleep(1000)
music.play(music.PRELUDE)

Názvy „hotových“ melodií najdete zde: https://microbit-micropython.readthedocs.io/en/latest/tutorials/music.html


Vstup - ovládání dotykem

from microbit import *
 
while True:
    if pin0.is_touched():
        display.show(Image.HAPPY)
    else:
        display.show(Image.SAD)


Úkol

Reagujte na dotyk plošek 0, 1 a 2 přehráváním různých tónů! Dotýkáme se nejlépe kovovým předmětem, druhá ruka je spojena s GND.

Senzor sklonu

Zkuste odhadnout výsledek běhu následujících kódů.

from microbit import *
 
while True:
    reading = accelerometer.get_x()
    if reading > 20:
        display.show("R")
    elif reading < -20:
        display.show("L")
    else:
        display.show("-")

from microbit import *
 
while True:
    reading = accelerometer.get_x()
    if reading > 20:
        display.show("R")
    elif reading < -20:
        display.show("L")
    else:
        display.show("-")

from microbit import *
import music
 
while True:
    acc = abs(accelerometer.get_y()) # pitch nechce zaporne hodnoty
    music.pitch(acc, 10)


Úkol

Dokážete vyrobit vodováhu?

Gesta

from microbit import *
 
while True:
    gesture = accelerometer.current_gesture()
    if gesture == "face up":
        display.show(Image.HAPPY)
    else:
        display.show(Image.ANGRY)

Názvy gest najdete zde: https://microbit-micropython.readthedocs.io/en/latest/tutorials/gestures.html


Úkol

Naprogramujte simulaci hrací kostky - po zatřesení ("shake") zobrazte náhodně ikonu bodů 1-6!

Senzor teploty

Neposkytuje úplně přesný údaj - měří teplotu čipu.

from microbit import *
 
while True:
   temp = temperature()
   display.scroll(str(temp) + 'C')
   sleep(500)


Úkol

Dokážete naprogramovat alarm hlídající překročení teploty?

Kompas

from microbit import *
 
compass.calibrate()
while True:
    display.scroll(compass.heading())


Rádio

from microbit import *
import radio
 
radio.on()
radio.config(channel=19, power=7)  # 0-100, 0-7
while True:
    radio.send("Pingu vola zakladnu!")
    incoming = radio.receive()
    if incoming:
        display.show(incoming)
    sleep(500)


Úkol

Naprogramujte vysílání (a příjem) zprávy v případě události jako otřes, změna osvětlení, teploty atd...!

Programováni pohybu robota

V dalších úkolech budeme ovládat motory robotického vozítka prostřednictvím desky moto:bit. Abychom vyhnuli složitosti ovládání (děje se přes rozhraní I2C) budeme používat hotovou knihovnu. Jelikož ale náš on-line editor neumožňuje upload knihoven do micro:bit (i v editorech Mu nebo Thonny k tomu potřebujeme admin přístup) kód této knihovny potřebný k ovládání motorů (můžeme ho stáhnout zde ) vždy umístíme na začátek vlastního kódu.

Pokud do robota nahráváte program, jež bude spouštět motory, tj. robot se bude pohybovat, nechte vypínač na desce moto:bit v levé, vypnuté poloze, a zapínejte ho, až je robot odpojen od kabelu USB a položen na místo, kde má dostatečný prostor pro pohyb.

V záhlaví, hned pod kódem moto:bit uvedeme následující příkazy:

# =======================...
 
from microbit import *
 
moto = motobit.MotoBit()
moto.enable()
leftMotor = moto.left_motor()
rightMotor = moto.right_motor()

které nám inicializují ovládání motorů a poskytnou proměnné „leftMotor“ a „rightMotor“, které pak použijeme k natavení jejich rychlosti a směru otáčení.

Na konci programu napíšeme:

moto.disable()

ke korektnímu ukončení práce s moto:bit.

Nyní se dostáváme k nejjednodušší části, tj. k vlastnímu ovládání motorů. Budeme používat funkce typu:

leftMotor.forward(25)
rightMotor.reverse(60)

Kde název funkce „forward“ nebo „reverse“ znamená směr otáčené motoru, parametr v závorkách pak rychlost otáčení (od -100 do 100, přičemž záporné hodnoty znamenají otáčení opačným směrem). Směry „forward“ nebo „reverse“ nejsou jasně definované, je třeba určit, kde má robot „předek“ (obvykle v místě třech senzorů odraženého světla - červených obdélníčků - na spodní straně vozíku).


Dálkové ovládání vozítka pomocí rádia

Jak už víme, micro:bit disponuje zabudovaným rádiem, pomocí kterého můžeme naprogramovat „autíčko“ na dálkově ovládání.


Úkol 1.

Naprogramujme micro:bit (spojený s napájecí deskou mi:power) jako vysílač!

Abychom mohli použít rádio, v záhlaví kódu uvedeme:

from microbit import *
import radio
 
radio.on()

pak vytvoříme nekonečnou smyčku s krátkým čekáním, například takto:

while True:
  # sem napiseme svuj kod
  sleep(10)

a doplníme kód na vysílání příkazů, jako například „levý motor dopředu“ nebo „pravý motor dozadu“ apod. Prvním úkolem je tyto příkazy - včetně kódů, které se budou přenášet rádiem - vymyslet.

Příklad příkazů a jednotlivých kódů:

Význam Kód přenášený rádiem
pravý i levý motor dopředu „F“
pravý i levý motor dozadu „B“
pravý motor dopředu „R“
levý motor dopředu „L“
pravý motor dozadu „Q“
levý motor dozadu „K“

Výše uvedený způsob ovládání slouží pouze jako inspirace. Vymyslete si vlastní příkazy, umožňující například ovládat i rychlost pohybu vozítka! Jinak hrozí, že jiné skupiny studentů začnou ovládat vaše vozítko!

K ovládání, tedy k vyvolání jednotlivých příkazů můžeme použít tlačítka micro:bit, například:

if button_a.is_pressed():

nebo gesta (up, down, left, right, face up, face down, freefall, 3g, 6g, 8g, shake) např.:

if accelerometer.is_gesture("up"):

či přímo míru náklonu podle akcelerometru:

naklonDopreduDozadu = accelerometer.get_y()

řídit rychlost pohybu.

Mále-li rozmyšlené ovládání, kód sestavíme snadno: jako reakce na určitou událost (stisk tlačítka, naklonění destičky, atd.) vyšleme rádiem určený kód. Abychom usnadnili hledání chyb, můžeme kód ukázat i na displeji.

Fragment kódu, ilustrující výše uvedený přístup:

command = ' ' # nic nedelej
if button_a.is_pressed() and button_b.is_pressed():
    command = 'F' # jdi dopredu
    # dalsi kod...
    display.show(command)
    radio.send(command)


Úkol 2.

Naprogramujme micro:bit (ovládající motory) jako přijímač!

Do hotového kódu na ovládání motorů přidáme řádek zapínající rádio a nekonečnou smyčku s krátkou prodlevou, přijímající vyslané signály. Máme zde opět řádku, zobrazující přijatý příkaz, poslouží při hledání chyb.

Fragment kódu, přijímače:

# knihovni kod moto:bit
# ...
# ===========...
 
from microbit import *
import radio
 
radio.on()
while True:
  command = radio.receive()
  if command:
    display.show(command)
  else:
    display.clear()
    # zde budeme ovladat motory na zaklade prijateho kodu
  sleep(10)


Možné řešení (jeho úplná funkčnost závisí na mechanickém uspořádání vozítka)

Kompletní kód vysílače dálkového ovládání

Kompletní kód přijímače dálkového ovládání


Robot - sledovač čáry

Roboti se můžou pohybovat i samostatně, na základě dat získaných ze senzorů.


Úkol

Zkusme sestavit jednoduchý sledovač černé čáry!

Nápad je prostý: senzor odraženého světla je nasměrován na podložku. Je-li podložka světlá, odrazí se více světla, a tedy senzor naměří vyšší hodnoty, než když je podložka tmavá. K tomu, abychom sledovali levý okraj černé čáry na bíle podložce pak postačí následující:

Robot jede pomalu dopředu. Naměří-li vysokou hodnotu odrazu, otáčí se lehce doprava, naopak, je-li hodnota odrazu příliš nízká (senzor je nad černou čarou) robot se bude otáčet mírně doleva.

Co je vysoká a nízká hodnota odrazu? micro:bit nám poskytuje naměřenou hodnotu osvětlení od 0 do 1023. Hodnotu „hranice“ tj. prahovou hodnotu, nad kterou budeme považovat podložku za světlou a pod kterou za tmavou, si musíme určit experimentálně, například kódem:

from microbit import *
 
while True:
    display.scroll(str(pin0.read_analog()))
    sleep(10)

Levý senzor postupně umísťujeme nad černou plochu čáry a nad bílou podložku, následně spočítáme průměry různě naměřených hodnot „světlé“ a „tmavé“. Prahovou hodnotu pak určíme jako průměr „světlé“ a „tmavé“.

V následujícím kódu používáme prahovou hodnotu 700:

Fragment kódu přijímače:

# knihovni kod moto:bit
# ...
# ===========...
 
from microbit import *
 
THRESHOLD = 700
 
moto = motobit.MotoBit()
moto.enable()
l = moto.left_motor()
r = moto.right_motor()
 
while True:
    # POUZE PRO LADENI: display.scroll(str(pin0.read_analog()))
    if pin0.read_analog() > THRESHOLD:
        display.show(Image.ARROW_W)
        r.reverse(40)
        l.forward(10)
    else:
        display.show(Image.ARROW_E)
        r.forward(10)
        l.reverse(40)
    sleep(10)

Zkuste, jestli Vám tento kód zajistí spolehlivé sledování čáry. Dokážete vylepšit kód a zrychlit robota - sledovače čáry?

Všímejte si, že k řešení úkolu používáme pouze jeden senzor. Pro více senzorů musíme navrhnout jiný algoritmus. Dokázali byste vymyslet a naprogramovat kód pro sledování tenké černé čáry dvěma senzory?

Možné řešení (jeho úplná funkčnost závisí na mechanickém uspořádání vozítka)

Kompletní kód sledovače čáry


courses/pri-bootcamp/embedded_python.txt · Last modified: 2019/09/12 13:46 by seredlad