====== 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í.