protocol --- Saluran Protokol OpenMV¶
Modul protocol mengekspos protokol host OpenMV ke Python. Modul ini memungkinkan tumpukan protokol sisi firmware untuk diinisialisasi dan dikonfigurasi, serta memungkinkan kode pengguna mendaftarkan saluran logis kustom yang didukung oleh objek Python yang mengimplementasikan antarmuka saluran (read, write, size, poll, dll.). Inilah yang digunakan alat pendamping desktop ketika mereka melakukan streaming data citra atau mengekspos widget interaktif ke kamera yang terhubung.
Contoh¶
Melakukan streaming citra RGB565 ke alat host menggunakan backend kustom yang mengimplementasikan antarmuka saluran mentah (backend.size(), backend.shape(), backend.poll(), backend.read()):
import csi
import protocol
csi0 = csi.CSI()
csi0.reset()
csi0.pixformat(csi.RGB565)
csi0.framesize(csi.HD)
img = csi0.snapshot()
img_mv = memoryview(img.bytearray())
frame_ready = True
class FrameChannel:
def size(self):
return len(img_mv)
def shape(self):
return (img.height(), img.width(), len(img_mv))
def poll(self):
return frame_ready
def read(self, offset, size):
global frame_ready
end = offset + size
chunk = img_mv[offset:end]
if end >= len(img_mv):
frame_ready = False
return chunk
protocol.register(name="frame", backend=FrameChannel())
while True:
if not frame_ready:
img = csi0.snapshot()
img_mv = memoryview(img.bytearray())
frame_ready = True
Skrip sisi host yang sesuai, menggunakan paket Python openmv (pip install openmv) untuk terhubung, mendorong skrip di kamera, dan menarik setiap bingkai:
import cv2
import numpy as np
from openmv.camera import Camera
# The on-cam script above, stored as a string (or read from a file).
SCRIPT = open("frame_streamer_on_cam.py").read()
with Camera("/dev/ttyACM0", baudrate=921600) as cam:
cam.stop()
cam.exec(SCRIPT)
while True:
status = cam.read_status()
if not cam.has_channel("frame") or not status.get("frame"):
continue
h, w, size = cam._channel_shape(cam.get_channel(name="frame"))
if cam.channel_size("frame") < size:
continue
data = cam.channel_read("frame", size)
rgb565 = np.frombuffer(data, dtype="<u2").reshape(h, w)
# Unpack RGB565 to an HxWx3 uint8 RGB image.
r = ((rgb565 >> 11) & 0x1F) << 3
g = ((rgb565 >> 5) & 0x3F) << 2
b = ( rgb565 & 0x1F) << 3
frame = np.dstack([r, g, b]).astype(np.uint8)
# Display with OpenCV (cv2 expects BGR, not RGB).
cv2.imshow("OpenMV", cv2.cvtColor(frame, cv2.COLOR_RGB2BGR))
if cv2.waitKey(1) == ord("q"):
break
cv2.destroyAllWindows()
Ganti /dev/ttyACM0 dengan port serial kamera (misalnya COM3 di Windows). Konstruktor openmv.camera.Camera menerima parameter protokol yang sama dengan init (crc / seq / ack / events / max_payload / max_retry / timeout) ketika tumpukan sisi kamera telah dikonfigurasi ulang agar sesuai.
Fungsi¶
- protocol.init(crc: bool = True, seq: bool = True, ack: bool = True, events: bool = True, max_payload: int = ..., rtx_retries: int = 3, rtx_timeout_ms: int = 500, lock_interval_ms: int = 10, poll_ms: int = 0) None¶
Menginisialisasi (atau mengonfigurasi ulang) tumpukan protokol dan mendaftarkan saluran data logis default (
stdin,stdout,streamdan, jika dikompilasi,profile). MemunculkanRuntimeErrorjika inisialisasi gagal. Firmware melakukan boot dengan tumpukan protokol USB default yang sudah berjalan, sehingga pemanggilan ini hanya diperlukan untuk mengubah transport atau mengganti parameter pembingkaian default.crcmengaktifkan validasi CRC pada bingkai protokol.seqmengaktifkan pelacakan nomor urutan.ackmengaktifkan pengakuan per bingkai.eventsmengaktifkan notifikasi event saluran.max_payloadadalah ukuran payload maksimum dalam byte. Jika dihilangkan, default per kamera di bawah ini digunakan; ini diturunkan dari ukuran buffer protokol setiap board sebagaibuffer - 10 (header) - 4 (CRC).Kamera
Ukuran buffer
Payload maksimum
OpenMV Cam M4 (
OPENMV2)512
498
OpenMV Cam M7 (
OPENMV3)512
498
OpenMV Cam H7 (
OPENMV4)512
498
OpenMV Cam H7 Plus (
OPENMV4P)4096
4082
OpenMV Pure Thermal (
OPENMVPT)4096
4082
OpenMV Cam RT1062 (
OPENMV_RT1060)4096
4082
OpenMV Cam N6 (
OPENMV_N6)8192
8178
OpenMV AE3 (
OPENMV_AE3)8192
8178
Arduino Portenta H7 (
ARDUINO_PORTENTA_H7)4096
4082
Arduino Giga (
ARDUINO_GIGA)4096
4082
Arduino Nicla Vision (
ARDUINO_NICLA_VISION)4096
4082
rtx_retriesadalah jumlah upaya retransmisi. Default3.rtx_timeout_msadalah timeout retransmisi dalam milidetik (digandakan setelah setiap timeout). Default500.lock_interval_msadalah interval kunci minimum dalam milidetik. Default10.poll_msadalah interval polling dalam milidetik.0(default) menonaktifkan polling timer.
- protocol.is_active() bool¶
Mengembalikan
Truejika host saat ini terhubung dan tumpukan protokol aktif, jika tidakFalse.
- protocol.register(name: str, *, backend: object, flags: int = 0) ProtocolChannel¶
Mendaftarkan objek Python
backendsebagai saluran logis baru dan mengembalikan handleProtocolChannel. Metode yang tersedia pada objekbackend(lihat Antarmuka Backend di bawah) menentukan kemampuan saluran;protocol.CHANNEL_FLAG_READ,protocol.CHANNEL_FLAG_WRITEdanprotocol.CHANNEL_FLAG_LOCKditambahkan keflagssecara otomatis ketika metode yang sesuai diimplementasikan.nameadalah nama saluran sebagai string. Dipotong ke ukuran buffer nama saluran firmware. Wajib.backendadalah objek Python yang mengimplementasikan antarmuka backend. Wajib. Biasanya diteruskan melalui kata kunci (backend=...).flagsadalah bit flag saluran tambahan (lihat konstantaCHANNEL_FLAG_*). Opsional; default ke0.Memunculkan
RuntimeErrorjika saluran tidak dapat didaftarkan (misalnya tidak ada slot saluran yang kosong).
Kelas¶
- class protocol.ProtocolChannel¶
Handle yang dikembalikan oleh
protocol.register. Instance tidak dibuat secara langsung.
Antarmuka Backend¶
Objek backend yang diteruskan ke protocol.register dapat mengimplementasikan subset dari metode berikut. Hanya metode yang ada pada objek yang dihubungkan ke lapisan protokol C; metode yang hilang membuat kemampuan yang sesuai dinonaktifkan.
- class protocol.backend¶
Objek backend saluran yang diteruskan ke
protocol.register. Metode di bawah ini menjelaskan antarmuka opsional yang dapat diimplementasikan oleh backend Python.- init() object¶
Dipanggil sekali ketika saluran diinisialisasi. Kembalikan nilai non-
Noneapa pun jika berhasil; pengecualian atau pengembalian yang hilang diperlakukan sebagai error.
- shape() tuple¶
Mengembalikan tuple hingga empat integer yang mendeskripsikan bentuk data (misalnya dimensi citra). Hingga empat elemen dikonsumsi oleh lapisan protokol.
- flush() object¶
Membuang semua data yang tertunda. Mengembalikan nilai non-
Noneapa pun jika berhasil.
- read(offset: int, size: int) bytes¶
Mengembalikan hingga
sizebyte mulai darioffsetsebagai objek sepertibytesyang mendukung protokol buffer.
- readp(offset: int, size: int) bytes¶
Varian tanpa salinan dari
read. Mengembalikan buffer yang memori dasarnya dibaca langsung oleh lapisan protokol; buffer harus tetap valid selama durasi transfer.
- write(offset: int, data: bytearray) int¶
Menulis
datapadaoffset.dataadalahbytearrayyang merujuk buffer C secara langsung. Mengembalikan jumlah byte yang ditulis, atau0untuk keberhasilan default.
- class protocol.CBORChannel(on_read: Callable | None = None, on_write: Callable | None = None)¶
Backend Python tingkat tinggi (disediakan oleh paket
protocolyang dibekukan) yang menserialisasi field bernama ke CBOR menggunakan kunci integer yang kompatibel dengan SenML. Mendukung widget tampilan (label,depth) dan kontrol interaktif (toggle,slider,select) dengan callbackon_read/on_write.on_readadalah callable opsionalon_read(channel)yang dipanggil sebelum saluran diserialisasi untuk host. Gunakan untuk menyegarkan nilai field.on_writeadalah callable opsionalon_write(channel, name, value)yang dipanggil ketika host menulis nilai baru untuk field bernama.- add(name: str, type: str, value: Any = None, unit: str | None = None, min: int | float | None = None, max: int | float | None = None, step: int | float | None = None, options: list | None = None, width: int | None = None, height: int | None = None) None¶
Menambahkan field bernama ke saluran.
nameadalah nama tampilan; harus unik dalam saluran ini.typeadalah tipe widget:"label","toggle","slider","select", atau"depth".valueadalah nilai awal. Default bergantung padatype.unitadalah string unit untuklabel/slider(misalnya"Cel","%RH").minadalah nilai minimum (rentang slider atau rentang depth).maxadalah nilai maksimum (rentang slider atau rentang depth).stepadalah ukuran langkah (slider).optionsadalah daftar string pilihan (select).widthadalah lebar piksel (depth).heightadalah tinggi piksel (depth).
- __getitem__(name: str) object¶
Mengembalikan nilai saat ini dari field bernama. Untuk field
depth, buffer data biner dikembalikan, jika tidak nilai skalar.
- __setitem__(name: str, value: Any) None¶
Mengatur nilai field bernama. Untuk field
slider, tuple(min, max, value)memperbarui rentang dan nilai saat ini secara bersamaan. Untuk fielddepth,valueadalah buffer data biner.
- poll() bool¶
Metode antarmuka backend. Mengembalikan
Trueketika data yang diserialisasi tersedia untuk host.
- size() int¶
Metode antarmuka backend. Memanggil
on_read(jika diatur) dan mengembalikan ukuran buffer yang diserialisasi.
Konstanta¶
Bit flag saluran (digabungkan secara bitwise; diteruskan ke protocol.register melalui flags atau diatur secara otomatis berdasarkan metode backend).
- protocol.CHANNEL_FLAG_PHYSICAL: int¶
Saluran mewakili transport fisik (sebagai lawan dari saluran data logis).
Pengenal saluran bawaan.