3.19. UART dalam kode¶
machine.UART membungkus satu saluran hardware UART. Buat satu dengan id bus dan laju baud; semua yang lain memiliki nilai default yang wajar:
from machine import UART
uart = UART(3, baudrate=115200)
id memilih hardware UART mana yang akan digunakan; nilainya bergantung pada board (lihat Papan OpenMV untuk nomor bus yang tersedia dan penugasan pin pada kamera tertentu). Format bingkai default adalah 8 bit data, tanpa paritas, satu bit berhenti -- "8N1" yang diharapkan semua orang.
3.19.1. Menulis dan membaca¶
Output UART dikirim melalui write():
uart.write("hello\n")
uart.write(b"\x01\x02\x03")
write menerima str (dikodekan sebagai UTF-8) atau bytes / bytearray. Fungsi ini langsung kembali setelah byte-byte diantrekan dalam buffer TX; hardware menyelesaikan pengirimannya di latar belakang.
Pembacaan dilakukan melalui tiga metode, tergantung pada apa yang dibutuhkan:
n = uart.any() # bytes available to read right now
data = uart.read(8) # up to 8 bytes, or None on timeout
line = uart.readline() # bytes ending in '\n', or None on timeout
any() memeriksa buffer RX tanpa pemblokiran. read() membaca sejumlah byte tetap, mengembalikan None jika timeout (dapat dikonfigurasi melalui argumen timeout dalam konstruktor) habis terlebih dahulu. readline() membaca hingga dan termasuk baris baru berikutnya, berguna untuk protokol berbasis baris.
Loop sederhana yang menggemakan apa pun yang diterimanya:
uart = UART(3, baudrate=115200, timeout=100)
while True:
if uart.any():
data = uart.read()
uart.write(data)
read() tanpa argumen panjang terus membaca byte hingga jalur penerimaan tetap sunyi selama timeout yang dikonfigurasi, kemudian mengembalikan apa pun yang telah terakumulasi. Dengan timeout=100, setiap panggilan di sini mengembalikan satu burst byte -- semua yang dikirim pengirim tanpa jeda 100 ms antar byte. Tanpa timeout, panggilan tidak akan memiliki sinyal bahwa pengirim sudah selesai dan dapat menggantung tanpa batas.
3.19.2. Data biner dengan struct¶
Mengirim integer dan float melalui kabel adalah fungsi dari modul struct. Modul ini mengemas nilai lebar tetap ke dalam objek bytes menggunakan string format yang menamai urutan byte dan tipe setiap field:
import struct
uart.write(struct.pack("<lhb", count, temperature_x100, status))
"<" di awal memilih urutan byte little-endian; "l" adalah integer bertanda 32-bit, "h" adalah integer bertanda 16-bit, "b" adalah integer bertanda 8-bit. Sisi lain membongkar dengan string format yang sama:
payload = uart.read(7) # 4 + 2 + 1 = 7 bytes
count, temperature_x100, status = struct.unpack("<lhb", payload)
String format adalah kontrak antara kedua ujung. Ketidakcocokan apa pun -- urutan byte yang salah, ukuran tipe yang salah, urutan field yang salah -- menghasilkan nilai yang tidak bermakna.
3.19.3. Buffering dan pembacaan kecepatan tinggi¶
Loop polling yang memanggil any() dan read() dapat mengikuti sebagian besar lalu lintas secara mandiri, selama loop utama beriterasi cukup cepat untuk menguras buffer penerimaan sebelum penuh. Dua opsi konstruktor penting ketika kecepatan meningkat atau loop sedang sibuk.
rxbuf mengatur ukuran buffer RX perangkat lunak. Defaultnya adalah beberapa ratus byte; untuk sensor yang memancarkan ratusan byte per burst, atau ketika loop utama melakukan pekerjaan panjang antara polling, memperbesar buffer mencegah byte yang masuk terjatuh saat loop sedang sibuk di tempat lain:
uart = UART(3, baudrate=115200, timeout=100, rxbuf=4096)
Apa pun yang tiba saat buffer penuh akan hilang; ukuran rxbuf harus mencakup jeda terpanjang antara pengosongan.
Untuk kecepatan tinggi yang berkelanjutan, readinto() membaca ke dalam buffer yang telah dialokasikan sebelumnya alih-alih mengembalikan objek bytes baru setiap pemanggilan:
buf = bytearray(256)
while True:
n = uart.readinto(buf)
if n:
process(buf, n)
Tidak ada alokasi yang terjadi pada jalur baca, yang penting ketika heap terfragmentasi atau ketika latensi alokasi akan melampaui anggaran timing antar-byte.