12.1. Why a protocol library¶
A pair of cables and a baud rate is enough to move bytes from a cam
to a host PC. USB-CDC and UART both give the cam program a stream
where write puts bytes in one end and read takes them out
the other. So what does a protocol library add on top of that?
Three things you would have to write yourself, every time, if you tried to build a serious cam-to-host channel directly on raw bytes:
Framing.
A byte stream has no inherent structure. The cam writes
temp=42 and the host reads temp= plus an interrupt arriving
later, then 42 plus the next message starting with humid=...
already running into it. Bytes don’t have boundaries. Every
non-trivial host link ends up inventing some marker – \n
between messages, length-prefix headers, escape sequences for
binary payloads – so the receiver knows where one message ends and
the next begins. The protocol library gives you a uniform packet
format with a sync word and a length field, and the receiver never
has to guess.
Reliability. USB-CDC doesn’t drop bytes silently in normal operation, but UART does (when the host stops servicing the port quickly enough), and a serial cable unplugged and reseated can leave one side with a partial packet. The right thing to do is to detect the corruption, ask the other side to retransmit, and only ever hand application code messages that arrived intact. The protocol library does that for every packet with a CRC and per-packet acknowledgements – on by default; the application doesn’t see the retries.
Multiplexing.
There’s exactly one USB-CDC port between the cam and the host. If
the cam is streaming an image and the host is sending it
configuration and the IDE is reading stdout for print
output, all three exchanges have to share that single byte stream.
The protocol library gives each independent stream a channel
number, lets the cam register a Python class for each one, and
keeps the host’s reads on each channel from interfering with the
others. From application code, each channel looks like its own
private link.
12.1.1. Why not write that yourself¶
You can. It’s a few weeks of work to get all three correct on a serial line and another few weeks to make the framing handle hot-plug recovery cleanly, the retransmits work without burning energy on round-trips, and the multiplexer survive partial reads without corrupting one channel’s bytes into another’s.
The protocol library has already done that work, has been validated
on every supported cam, and has matching libraries on the host side
that speak the same wire format. Using it means the cam-side code
is one small class per channel and the host-side code is a
Camera object with channel_read and
channel_write methods. The mental space saved goes to whatever
the application actually does.
This chapter teaches the protocol from the ground up: the wire format, the framing rules, the reliability machinery, the channel model, and finally the Python classes on both ends. By the end the reader can build a host GUI that talks to the cam, a script that streams sensor data from cam to laptop, and the kind of interactive calibration tool that ships in openmv-projects/tools/.