15.3.1.6. API reference¶
The public surface of the openmv package is the
Camera class for talking to a cam and the
OMVException hierarchy for protocol errors.
Both are documented on this page.
15.3.1.6.1. The Camera class¶
- class openmv.Camera(port: str, *, baudrate: int = 921600, crc: bool = True, seq: bool = True, ack: bool = True, events: bool = True, timeout: float = 1.0, max_retry: int = 3, max_payload: int = 4096, drop_rate: float = 0.0)¶
The host-side proxy for an OpenMV cam reached over USB serial.
- Parameters:
port – Serial device path. On Linux,
/dev/ttyACMxfor USB CDC and/dev/ttyUSBxfor a USB-to-UART bridge. On macOS,/dev/tty.usbmodem...or/dev/cu.usbmodem.... On Windows,COMx.baudrate – Serial baud rate. Over USB,
921600is the magic value that switches the cam from the MicroPython REPL to the OpenMV protocol – any other value on a USB link leaves the cam in REPL mode, so the default must be used. Over a UART link the value is the actual line baud rate and can be set freely on both sides.crc – Enable CRC validation on every packet.
seq – Enable per-packet sequence numbers.
ack – Require packet acknowledgement.
events – Enable event notifications from the cam.
timeout – Per-operation timeout in seconds.
max_retry – Number of retries before raising on a failed packet.
max_payload – Maximum negotiated payload size in bytes. The cam may negotiate down.
drop_rate – Test-only probability of dropping a packet, in
[0.0, 1.0]. Leave at0.0in production.
The class supports the context-manager protocol;
with Camera(port) as cam:callsconnect()on entry anddisconnect()on exit.
15.3.1.6.2. Connection¶
- Camera.connect() None¶
Open the serial port and perform the protocol handshake. Cached state (channel list, system info, version info) is populated as a side effect. Called automatically by the context manager.
- Camera.disconnect() None¶
Close the serial port and release the transport. Called automatically when the context manager exits.
- Camera.boot() None¶
Jump the cam into its bootloader. The connection is dropped because the cam reboots.
- Camera.update_capabilities() None¶
Renegotiate the protocol capabilities (CRC, sequence checking, ACKs, events, max payload) with the cam. The cam reports the maximum payload it can handle; the host’s request is clipped to that and the agreed settings are pushed back. Called automatically by
connect()– there is no reason to call it from user code unless the constructor flags need to be renegotiated on an existing connection.
15.3.1.6.3. Script execution¶
15.3.1.6.4. Streaming¶
- Camera.streaming(enable: bool, raw: bool = False, resolution: tuple[int, int] | None = None) None¶
Turn the frame stream on or off and pick the on-the-wire format.
- Parameters:
enable –
Trueenables streaming,Falsedisables it.raw – When
False(default), the cam JPEG-compresses each frame before placing it in the stream channel andread_frame()decompresses on the host. WhenTrue, the cam sends the captured pixel buffer uncompressed – the right choice on cams without hardware JPEG support, where software compression is the slowest step in the loop.resolution –
(width, height)target the cam scales each raw frame down to before sending, since uncompressed frames are much larger than JPEG-compressed ones. Required whenraw=True; ignored otherwise.
- Camera.read_frame() dict | None¶
Read the latest frame from the stream channel.
- Returns:
Noneif no frame is waiting, or a dict with keyswidth(int, pixels),height(int, pixels),format(int, the pixel-format identifier the cam declared),depth(int, the compressed image size in bytes for JPEG / PNG frames; unused for uncompressed formats),data(bytes, RGB888 of lengthwidth * height * 3), andraw_size(int, bytes the cam sent over USB before decode).
15.3.1.6.5. Custom channels¶
- Camera.has_channel(name: str) bool¶
- Returns:
Trueif a channel registered withnameexists on the cam.
- Camera.channel_size(name: str) int¶
- Returns:
Number of bytes the named channel currently has available, or
0when the channel is empty or does not exist.
- Camera.channel_write(name: str, data: bytes) bool¶
Write
datato a custom channel. Larger-than-payload writes are automatically split across packets.- Parameters:
name – Channel name registered by the cam-side script.
data – Bytes-like payload to send.
- Returns:
Trueif the channel exists and the write was sent,Falseotherwise.
- Camera.read_status() dict[str, bool]¶
Poll every registered channel.
- Returns:
Dict mapping channel name to a boolean of “data is ready to read”.
- Camera.update_channels() None¶
Refresh the cached channel list from the cam. Runs automatically the next time a channel-by-name lookup is performed after a channel-registration event arrives; an application that wants to learn a newly-registered channel immediately can call this directly.
- Camera.get_channel(name: str | None = None, channel_id: int | None = None) int | str | None¶
Look up a channel either by name (returning its numeric ID) or by ID (returning its name). Refreshes the channel cache via
update_channels()first if channel-registration events are pending.- Parameters:
name – Channel name to resolve to an ID.
channel_id – Channel ID to resolve to a name.
- Returns:
The corresponding ID or name, or
Nonewhen the channel does not exist. One ofnameorchannel_idmust be supplied.
15.3.1.6.6. Device introspection¶
- Camera.version() dict¶
Return the cam’s protocol, bootloader, and firmware version triples. Cached after
connect(). Each triple is a(major, minor, patch)tuple ofint:protocol_version– the version of the OpenMV wire protocol the cam implements.bootloader_version– the bootloader image resident in flash.firmware_version– the MicroPython firmware currently running.
- Camera.system_info() dict¶
Return the cam’s hardware capability and memory information. Cached after
connect(). The returned dict’s keys fall into four groups.Identity
cpu_id– 32-bit CPU identifier.device_id– 3-tuple of 32-bit words, the unique device serial baked into the silicon.chip_id– 3-tuple of 32-bit words, one entry per image sensor connected to the cam.usb_vid– USB vendor ID.usb_pid– USB product ID.
Memory sizes (all in kilobytes)
flash_size_kb– total internal flash.ram_size_kb– total RAM.framebuffer_size_kb– RAM reserved for image capture.stream_buffer_size_kb– RAM reserved for the stream channel that ships frames to the host.
Capability flags (one boolean per feature, all named
<feature>_present)gpu_present– graphics processing unit.npu_present– neural processing unit.isp_present– image signal processor.venc_present– video encoder.jpeg_present– JPEG hardware encoder.dram_present– external DRAM.crc_present– CRC accelerator.pmu_present– performance monitoring unit.wifi_present– Wi-Fi radio.bt_present– Bluetooth radio.sd_present– SD card slot.eth_present– Ethernet PHY.multicore_present– multiple CPU cores.
Other
usb_highspeed– boolean,Truewhen USB enumerated in high-speed (USB 2.0 HS, 480 Mbps) mode.pmu_eventcnt– number of PMU event counters available;0when no PMU.
15.3.1.6.7. Diagnostics¶
15.3.1.6.8. Profiler¶
The profiler reports per-function call counts and min /
max / total execution times for the instrumented
firmware modules – currently image, ml,
and ulab. Function entry and exit are
intercepted at compile time; the runtime samples a
monotonic microsecond counter on each, accumulates the
result per function, and exposes the table to the host
through the profile channel.
The profiler is only built into the firmware when
PROFILE_ENABLE=1 is passed to make. Stock
firmware images do not include it – the
-finstrument-functions flag the build adds to the
tracked modules has non-trivial runtime overhead, so
profiling builds are produced from source for the
specific debugging session that needs them. When the
firmware was not built with the flag, the profile
channel is not registered and every profiler method on
this page returns silently without doing anything.
The Arm Performance Monitoring Unit (PMU) is the
Cortex-M55’s hardware counter block – a small set of
configurable counters that track cycle counts, cache
hits and misses, branch behaviour, and other
architecture-defined events without slowing the code
under measurement. On cams that have one – the AE3
and the N6, the two cams in the OpenMV lineup built
around the M55 – the profiler samples these counters
alongside the timing data and the event totals show up
in each per-function record. Cams without a PMU still
produce timing records; the event fields come back as
zero, and profiler_event() is a no-op.
- Camera.profiler_mode(exclusive: bool = False) None¶
Switch between inclusive and exclusive timing. Inclusive timing charges callees’ time to the caller; exclusive timing does not.
- Parameters:
exclusive –
Trueselects exclusive timing,Falseselects inclusive.
- Camera.profiler_reset(config: list | None = None) None¶
Clear all profile counters.
config=Nonealso restores the default PMU event assignment.- Parameters:
config – Reserved for future per-counter configuration overrides. Pass
Noneto keep the defaults.
- Camera.profiler_event(counter_num: int, event_id: int) None¶
Bind one of the PMU counter slots to a specific hardware event.
- Parameters:
counter_num – Counter index.
event_id – Architecture-defined event identifier.
- Camera.read_profile() list[dict] | None¶
Return the per-function profile records collected since the last reset. Each record is a dict with
address,caller,call_count,min_ticks,max_ticks,total_ticks,total_cycles, and aneventstuple sized to the cam’spmu_eventcnt.- Returns:
List of record dicts, or
Noneif the profile channel is not available or no data has been collected.
15.3.1.6.9. Subclassing and channel internals¶
The methods documented above cover every common use of
the package. A few patterns – handling cam-side events
the host wants to react to, locking a channel for a
multi-step exchange, talking to channels that carry
shaped data instead of byte streams, or driving
channel-specific control commands – need methods that
Camera keeps prefixed with an underscore.
These names are private by convention (Python does
not name-mangle them), and applications that need them
are expected to either subclass Camera or call
the methods directly.
Subclassing to react to events.
Every event the cam emits arrives through
Camera._handle_event(). Subclassing
Camera and overriding the method is the way
an application reacts to events its cam-side script
raises; the Events page walks the full pattern.
- Camera._handle_event(channel_id: int, event: int) None¶
Dispatch one event from the cam. Called by the transport layer whenever an event packet arrives. Override in a subclass to add application-specific handling; call
super()._handle_event(...)to keep the default behaviour (channel-list refresh onCHANNEL_REGISTERED, frame-ready tracking on thestreamchannel,stdin-channel start / stop logging).- Parameters:
channel_id –
0for system events, otherwise the registered channel ID.event – Event identifier; values come from the
EventTypeenum for system events and from whatever the cam-side channel backend chose for channel events.
A subclass that adds its own protocol-talking methods
should decorate them with retry_if_failed() so
they inherit the same resync-and-retry behaviour every
shipped method on this page has.
- static Camera.retry_if_failed(func)¶
Decorator. Wraps an instance method so that it retries once when the transport raises
ResyncException. Any method that calls into_send_cmd_wait_resp()(directly or through one of the_channel_*wrappers) should carry this decorator:class MyCamera(Camera): @Camera.retry_if_failed def my_custom_command(self, payload): return self._send_cmd_wait_resp(Opcode.MY_CMD, 0, payload)
Channel locking ensures the channel’s state does
not change between two related operations (a
_channel_size() followed by a
_channel_read(), for example, on a channel that
keeps appending data). read_frame() and
read_profile() use this internally; an
application driving a custom channel with multi-step
access does the same.
- Camera._channel_lock(channel_id: int) bool¶
Acquire an exclusive lock on a channel. Other host operations on the same channel block until the lock is released.
- Parameters:
channel_id – Numeric channel ID, typically resolved with
get_channel().- Returns:
Truewhen the lock was granted.
- Camera._channel_unlock(channel_id: int) bool¶
Release a lock previously taken with
_channel_lock(). Always paired with a lock call; usetry/finallyto make sure the unlock happens even when the read in between raises.- Parameters:
channel_id – Numeric channel ID, typically resolved with
get_channel().
Shaped channels carry structured records rather
than a flat byte stream. The profiler channel is the
shipped example: its shape is
(record_count, record_size) and a host that wants
to know how many records are waiting reads the shape
rather than the byte size.
- Camera._channel_shape(channel_id: int) tuple[int, ...]¶
Read the shape descriptor of a channel.
- Parameters:
channel_id – Numeric channel ID, typically resolved with
get_channel().- Returns:
Tuple of unsigned 32-bit integers describing the channel’s layout. The meaning is channel-specific.
Channel-specific control commands – start, stop,
reset, configure – ride a single opcode
(CHANNEL_IOCTL) with a channel-specific command
number and an optional struct.pack payload. The
shipped methods like stop(), exec(), and
streaming() are thin wrappers around
_channel_ioctl() calls against the stdin and
stream channels; a custom cam-side channel that
defines its own ioctl menu is driven the same way.
- Camera._channel_ioctl(channel_id: int, cmd: int, fmt: str | None = None, *args) bytes | None¶
Issue an ioctl command on a channel.
- Parameters:
channel_id – Numeric channel ID, typically resolved with
get_channel().cmd – Command number defined by the cam-side channel backend.
fmt – Optional
structformat string for the argument tuple. PassNonefor ioctls that take no arguments.args – Values matching
fmt.
- Returns:
Whatever payload the channel returned, or
None.
By-ID byte-stream variants of the public channel
methods skip the name-to-ID lookup and accept an
explicit byte offset – useful for reading a chunk
from the middle of a large buffer (the profile
channel records, for example).
- Camera._channel_size(channel_id: int) int¶
- Parameters:
channel_id – Numeric channel ID, typically resolved with
get_channel().- Returns:
Bytes currently available on the channel.
- Camera._channel_read(channel_id: int, offset: int, length: int) bytes¶
Read
lengthbytes starting atoffset. Multi-packet reads are reassembled automatically.- Parameters:
channel_id – Numeric channel ID, typically resolved with
get_channel().offset – Byte offset to start reading from.
length – Number of bytes to read.
- Camera._channel_write(channel_id: int, data: bytes, offset: int = 0) None¶
Write
dataat the givenoffset. Multi-packet writes are split across packets automatically.- Parameters:
channel_id – Numeric channel ID, typically resolved with
get_channel().data – Bytes-like payload to write.
offset – Byte offset to start writing at.
Protocol primitives are the lowest level the class exposes – the raw send-a-command, fetch-the-raw- channel-list, and manual-resync entries everything above is eventually built on. An application reaches for them when sending an opcode the class does not already wrap, or when implementing custom recovery in a subclass.
- Camera._send_cmd_wait_resp(opcode: int, channel: int = 0, data: bytes = b'') bytes | None¶
Send a protocol command and wait for the cam’s response. The primitive every other method in this section is built on.
- Parameters:
opcode – Command number. The shipped
Opcodeenum lists the codes the firmware ships with, but the parameter is just an integer – a custom firmware build can define and respond to its own.channel – Channel ID, or
0for system commands.data – Command-specific payload.
- Returns:
Response payload, or
Nonefor commands likeOpcode.SYS_RESETandOpcode.SYS_BOOTthat drop the connection.
- Camera._channel_list() dict¶
Fetch the current channel list from the cam without touching the cached
channels_by_idandchannels_by_namedictionaries thatupdate_channels()populates. Useful for a subclass that wants to inspect the cam’s channel state directly.- Returns:
Dict mapping channel ID to
{'name': str, 'flags': int}.
- Camera._resync() None¶
Re-run the protocol handshake from scratch. Called automatically by
connect()on initial connection and by every public method that catches anOMVExceptionfrom the transport. An application implementing its own recovery loop in a subclass may call this directly after handling the underlying error.
15.3.1.6.10. Exceptions¶
- exception openmv.OMVException¶
Base class for every protocol-level error. The three subclasses below all inherit from it, so a single
except OMVExceptioncovers the entire error surface.
- exception openmv.TimeoutException¶
The cam did not respond within the configured timeout. Subclass of
OMVException.
- exception openmv.ChecksumException¶
A packet’s CRC did not match. Raised after the protocol has exhausted its retry budget. Subclass of
OMVException.
- exception openmv.SequenceException¶
A packet arrived with an unexpected sequence number after retries. Subclass of
OMVException.