Python library and CLI for communicating with OpenMV cameras.
pip install openmv# Basic usage - stream video from camera
openmv --port /dev/ttyACM0
# Run a custom script
openmv --port /dev/ttyACM0 --script my_script.py
# Adjust display scale (default is 4x)
openmv --port /dev/ttyACM0 --scale 5
# Run throughput benchmark
openmv --port /dev/ttyACM0 --bench
# Load firmware symbols for profiler function names
openmv --port /dev/ttyACM0 --firmware build/firmware.elf
# Quiet mode (suppress script output)
openmv --port /dev/ttyACM0 --quiet
# Debug mode (verbose logging)
openmv --port /dev/ttyACM0 --debug
# Preview a custom data channel
openmv --port /dev/ttyACM0 --channel ticks| Option | Default | Description |
|---|---|---|
--port PORT | /dev/ttyACM0 | Serial port |
--script FILE | None | MicroPython script file to execute |
--scale N | 4 | Display scaling factor |
--poll MS | 4 | Poll rate in milliseconds |
--bench | False | Run throughput benchmark mode |
--raw | False | Enable raw streaming mode |
--timeout SEC | 1.0 | Protocol timeout in seconds |
--baudrate N | 921600 | Serial baudrate |
--firmware FILE | None | Firmware ELF file for profiler symbol resolution |
--channel NAME | None | Custom data channel to poll and print |
--quiet | False | Suppress script output text |
--debug | False | Enable debug logging |
| Option | Default | Description |
|---|---|---|
--crc BOOL | true | Enable CRC validation |
--seq BOOL | true | Enable sequence number validation |
--ack BOOL | true | Enable packet acknowledgment |
--events BOOL | true | Enable event notifications |
--max-retry N | 3 | Maximum number of retries |
--max-payload N | 4096 | Maximum payload size in bytes |
--drop-rate N | 0.0 | Packet drop simulation rate (0.0-1.0, for testing) |
| Key | Action |
|---|---|
ESC | Exit |
P | Cycle profiler overlay (Off → Performance → Events) |
M | Toggle profiler mode (Inclusive ↔ Exclusive) |
R | Reset profiler counters |
fromopenmvimportCamerascript="""import csi, timecsi0 = csi.CSI()csi0.reset()csi0.pixformat(csi.RGB565)csi0.framesize(csi.QVGA)clock = time.clock()while True: clock.tick() img = csi0.snapshot() print(clock.fps(), "FPS")"""# Connect to camerawithCamera('/dev/ttyACM0') ascamera:
# Stop running script (if any)camera.stop()
# Execute script and enable streamingcamera.exec(script)
camera.streaming(True)
# Read frames and outputwhileTrue:
ifframe:=camera.read_frame():
print(f"Frame: {frame['width']}x{frame['height']}")
iftext:=camera.read_stdout():
print(text, end='')Custom channels allow bidirectional data exchange between the camera and host.
Camera-side script (MicroPython):
importtimeimportprotocolclassTicksChannel:
defsize(self):
return10defread(self, offset, size):
returnf'{time.ticks_ms():010d}'defpoll(self):
returnTrueprotocol.register(name='ticks', backend=TicksChannel())Host-side (Python):
fromopenmvimportCamerawithCamera('/dev/ttyACM0') ascamera:
camera.exec(script)
whileTrue:
# Check if channel has dataifcamera.has_channel('ticks'):
size=camera.channel_size('ticks')
ifsize>0:
data=camera.channel_read('ticks', size)
print(f"Ticks: {data.decode()}")fromopenmvimportCameraCamera(
port, # Serial port (e.g., '/dev/ttyACM0')baudrate=921600, # Serial baudratecrc=True, # Enable CRC validationseq=True, # Enable sequence number validationack=True, # Enable packet acknowledgmentevents=True, # Enable event notificationstimeout=1.0, # Protocol timeout in secondsmax_retry=3, # Maximum retriesmax_payload=4096, # Maximum payload sizedrop_rate=0.0, # Packet drop simulation (testing only)
)| Method | Description |
|---|---|
connect() / disconnect() | Manage connection |
is_connected() | Check connection status |
exec(script) | Execute a MicroPython script |
stop() | Stop the running script |
streaming(enable, raw=False, resolution=None) | Enable/disable video streaming |
read_frame() | Read video frame → {width, height, format, depth, data, raw_size} |
read_stdout() | Read script output text |
read_status() | Poll channel status → {channel_name: bool, ...} |
has_channel(name) | Check if channel exists |
channel_read(name, size=None) | Read from custom channel |
channel_write(name, data) | Write to custom channel |
channel_size(name) | Get available data size |
version() | Get firmware, protocol, and bootloader versions |
system_info() | Get camera system information |
host_stats() / device_stats() | Get protocol statistics |
| Method | Description |
|---|---|
read_profile() | Read profiler data |
profiler_mode(exclusive) | Set inclusive/exclusive mode |
profiler_reset(config=None) | Reset profiler counters |
profiler_event(counter_num, event_id) | Configure event counter |
| Exception | Description |
|---|---|
OMVException | Base protocol exception |
TimeoutException | Timeout during communication |
ChecksumException | CRC validation failure |
SequenceException | Sequence number mismatch |
Full API documentation: docs/api.md
- Python 3.8+
- pyserial >= 3.5
- numpy >= 1.20.0
- pygame >= 2.0.0
- pyelftools
MIT License - Copyright (c) 2025 OpenMV, LLC.