In tools/rpc: Remove the desktop RPC library. · openmv/openmv@0d4a786 · GitHub , the rpc_usb_vcp_master is removed. If i need to transform image and imu data to raspberry pi through USB, which library should I use? Thank you very much
See the new OpenMV pip command line tool: GitHub - openmv/openmv-python: Python Library and CLI for communicating with OpenMV Cameras · GitHub
Here are examples of what you can do with the new v5.0.0 serial protocol: openmv-projects/tools at master · openmv/openmv-projects · GitHub
You can pretty much move any data you like back and forth between the camera and PC.
It’s completely better than what the RPC VCP was.
Thank you very much for super helpful answer.
Sample code in protocol manual page stream data slowly
from openmv.camera import Camera
import time
# The on-cam script above, stored as a string (or read from a file).
SCRIPT = open("frame_streamer_on_cam.py").read()
ts = time.monotonic_ns()
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)
ts2 = time.monotonic_ns()
print('interval', (ts2 - ts)//1000000, 'ms')
ts = ts2
opemv side
import csi
import protocol
csi0 = csi.CSI()
csi0.reset()
csi0.pixformat(csi.GRAYSCALE)
csi0.framesize(csi.VGA)
csi0.framerate(10)
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
host side get frame at a regular interval 649ms
Change read to readp
def readp(self, offset, size):
This uses a much faster version of the read command. However, it doesn’t work nicely on windows. Use mac or linux.
Also, disable acks in the Camera constructor. You can also disable crcbut, that doesn’t help much.
Disabling acks gives you the most speed boost. Then, use readp. Then, disabling crcs.
…
Note, you want read/crcs for windows. You can get away without acks as long as you handle exceptions.
Thank you so much for helping. By using readp() and ack=False, it is much faster on Raspberry Pi / Debian now.
There is a send_event() in protocol — OpenMV Protocol Channels - OpenMV MicroPython 1.28 documentation
It is also mentioned in 15.8. Streaming frames - OpenMV MicroPython 1.28 documentation
send_event()notifies the host the instant a new frame lands so it can begin pulling without polling.
But there is no corresponding API on host side. Maybe I miss something? Thank you very much
The current implementation of the protocol library doesn’t have support for anything but the built-in events: openmv-python/src/openmv/camera.py at master · openmv/openmv-python · GitHub
Create a bug ticket about that on the openmv-python repo. However, any protocol implementation can add support for handling an event.
As for what you can do right now. Subclass Camera and override _handle_event, the transport binds self._handle_event at connect, so your override gets used.
class MyCamera(Camera):
def _handle_event(self, channel_id, event):
super()._handle_event(channel_id, event)
name = self.channels_by_id.get(channel_id, {}).get("name")
# ... your logic: route the event wherever you like
Call super() first, it maintains frame_event and pending_channel_events that the rest of the class relies on.
Thank you so much for helping, I will try subclass way.