====== 6. IoT zařízení - RPi Pico ====== ===== Cíle cvičení ===== - seznámení s vývojovým prostředím - seznámení s programovacím jazykem MicroPython - vytvoření programu pro Raspberry Pi Pico - UART komunikace s RPi Pico - IoT systém - propojení s aplikací ve Flasku ===== Micropython na Raspberry Pi Pico W ===== https://micropython.org/download/rp2-pico-w/ https://thonny.org/ https://github.com/cpwood/Pico-Go from machine import Pin, Timer led = Pin('LED', Pin.OUT) timer = Timer() def blink(timer): led.toggle() timer.init(freq=2.5, mode=Timer.PERIODIC, callback=blink) ===== Komunikace po UART ===== Cílem dílčí úlohy je poslat prostřednictvím rozhraní UART informaci o tom, jakou rychlostí se má rozsvítit LED na desce Raspberry Pi Pico. Nejprve si ale můžeme vyzkoušet samotnou komunikaci, tj. např. odesílání znaků z mikrokontroléru a jejich příjem na straně PC. ==== Aplikace na Raspberry Pi ==== Třída [[https://docs.micropython.org/en/latest/library/machine.UART.html|machine.UART]] je určena pro vytvoření fyzického UART rozhraní pomocí dvojice RX/TX pinů. Pokud bychom ji chtěli využít, potřeboval bychom na druhé straně obdobné zařízení, např. jiné Pico. Pokud bychom chtěli takto komunikovat s PC, je potřeba konvertor UART-USB, např. s FTDI čipem (např. [[https://dratek.cz/arduino/1158-eses-cp2102-usb-ttl-prevodnik.html|tento]]). Lze však využít toho, že USB rozhraní Raspberry Pi funguje jako sériové rozhraní s rychlostí 115200 kb/s. A data z desky Pico lze tedy poslat příjemci na PC např. pomocí funkce ''print()''. from machine import Pin, Timer import sys led = Pin('LED', Pin.OUT) while True: # x = input() x = sys.stdin.read(1) if x == 'a': led.toggle() print("UART: {}".format(x)) ==== Aplikace na PC ==== Pro UART komunikaci mezi embedded zařízením a PC použijeme knihovnu [[https://pypi.org/project/pyserial/|PySerial]]. Připojení proběhne vytvoření instance třídy, parametry konstruktoru jsou název sériového portu a rychlost komunikace. Je celkem vhodné ošetřit připojení pro případ, že spojení nelze uskutečnit. V následujícím kódo je zařízení připojeno k portu ''COMXXX'' (za XXX dosaďte podle potřeby) a komunikuje rychlostí 115200 baudů. import serial try: ser = serial.Serial('COMXXX', 115200) ser.flushInput() except: print("unable to open COM port") Se zařízením je možné komunikovat na úrovni bytů nebo znaků. Pokud zařízení posílá data ve formě znaků (tj. posílá byty s významem ASCII kódů), lze data přijmout třeba takto: data = ser.readline().decode() print(data) Pokud je z hlediska aplikace výhodnější používat byty ve s významem čísla (např. v rozsahu 0-255), je možné přijmout a dekódovat takto: byte = ser.read() decoded_bytes = int.from_bytes(byte, byteorder = 'little') Argumentem metody ''read()'' je počet bytů, které jsou najednou přečteny. Lze tedy např. předpokládat, že embedded zařízení posílá dva byty současně a tyto dva byty buď mohou reprezentovat číslo typu ''short'', nebo dva samostatné byty ''a'' a ''b'', které je třeba dekódovat: byte = ser.read(2) decoded_bytes = int.from_bytes(byte, byteorder = 'little') a = decoded_bytes & 255; b = (decoded_bytes >> 8) & 255; import serial try: ser = serial.Serial('COM7', 115200) ser.flushInput() # while True: ser.write(b'a') data = ser.readline().decode() print(data) except: print("unable to open COM port") ===== Zadání 4. miniprojektu ===== Naprogramujte Raspberry Pi Pico tak, aby s intervalem 20 sekund vygenerovalo náhodnou hodnotu datového typu Real (simulace měření teploty). Tuto hodnotu zapište na sériové rozhraní, odkud to flask aplikace přečte a zapíše do databáze. Data by měla být dostupná pomocí REST API, nebo UI, které jsou naprogramované na vašem webovém serveru. BONUS: * Vyzkoušejte obousměrnou komunikaci. Např. pomocí webového rozhraní měnte periodu generování dat v rpi * Implementujte kontrolu komunikace - pokud po 20 sekundách nepříjde nová hodnota, zobrazte na webu varování.