ArduCAM × W6300-EVB-Pico2 High-Speed JPEG Streaming Project (C/C++)
Real-time JPEG streaming using ArduCAM + WIZnet Pico(C/C++). Capture via DVP, stream over UDP, and decode live with Python OpenCV.

WIZnet - W6300-EVB-Pico2
x 1
ArduCam - Arducam Quick-Bootup 3MP DVP Camera for IoT
x 1
1. Project Overview
This project demonstrates a real-time Ethernet-based JPEG streaming system built using the WIZnet Pico (RP2040/RP2350) board combined with the ArduCAM Quick-Bootup 3MP DVP Camera.
Two main components make up the system:
Camera side (Pico): Captures JPEG frames via an 8-bit DVP interface and transmits them over Ethernet by splitting the data into UDP packets.
PC side (Python): Receives packets, reassembles complete frames using header information, and decodes the JPEGs in real time with OpenCV.
Through this project, makers can gain a complete understanding of real-time embedded camera streaming over Ethernet, forming a foundation for IoT vision, robotics, and remote monitoring applications.
ArduCam X WIZnet Pico UDP Streaming Github Project Link
🧠 Core Keywords:
RP2040 DVP PIO DMA / UDP JPEG Streaming / Frame Reassembly / OpenCV Real-Time Decoding
2. Hardware Modules
WIZnet Pico (RP2040 / RP2350)
[WIZnet Pico RP2040 Based Link]
[WIZnet Pico RP2350 Based Link]
Supports both RP2040 and RP2350 (up to 200MHz system clock)
Embedded Ethernet options:
W5100S / W5500 / W6100 — SPI (40MHz)
W6300 — QSPI Quad (37.5MHz)
Fully compatible with Pico SDK 1.5.1
Supports simultaneous use of DVP Camera + Ethernet + SPI Flash + UART
Arducam Quick-Bootup 3MP DVP Camera for IoT
[Arducam Quick-Bootup 3MP DVP Camera for IoT]
Specification | Description |
---|---|
Sensor | 3MP Mega DVP Color Sensor (2048×1536) |
Lens | 88° FOV, Fixed Focus, F/2.0 |
Output Format | JPEG / YUV / RGB |
Boot Speed | 300ms Instant Boot |
Power | Idle Off / 300ms Wake-up |
Size | 12.9 × 17 × 5.3mm |
Compatible MCUs | RP2040, Arduino, STM32, ESP32, Renesas, etc. |
Max Frame Rate | 2048×1536 @ 12fps |
💡 With its 300ms instant-on capability and ultra-low power design,
this module is ideal for “instant-response IoT vision applications.”
3. Performance Comparison (Sys Clock 200MHz)
MCU Module | Ethernet Interface | 1280×720 (HD) | 1920×1080 (FHD) |
---|---|---|---|
W5100S / W5500 / W6100 | SPI 40MHz | 10–17 fps | 2–6 fps |
W6300 | QSPI Quad 37.5MHz | 22–30 fps | 6–8 fps |
✅ The W6300 QSPI variant delivers smooth HD streaming even in real-time applications.
Resolution | Average Frame Size | Frame Rate | Data per Second (approx.) |
---|---|---|---|
320×240 (QVGA) | 4KB – 12KB | 30fps | 120KB – 360KB/s |
640×480 (VGA) | 14KB – 35KB | 30fps | 420KB – 1.05MB/s |
1280×720 (HD) | 35KB – 52KB | 30fps | 1.05MB – 1.56MB/s |
1920×1080 (FHD) | 65KB – 110KB | 8fps | 520KB – 880KB/s |
These values represent typical JPEG-compressed frame sizes and throughput measured under 37.5 MHz QSPI operation on the W6300-EVB-Pico2 board.
4. Pin Mapping (Pico ↔ ArduCAM)
Pico Pin | ArduCAM Pin | Function |
---|---|---|
GP00 | SDA | SCCB (I2C Data) |
GP01 | SCL | SCCB (I2C Clock) |
GP04 | VSYNC | Frame Sync |
GP05–GP12 | D0–D7 | 8-bit Pixel Data |
GP13 | PCLK | Pixel Clock |
GP14 | HREF | Line Sync |
VCC / GND | — | 3.3V / Ground |
📸 Each PCLK rising edge samples one pixel (8-bit data),
while VSYNC HIGH defines the active frame transmission window.
5. JPEG Frame Capture Sequence (on Pico)
The PIO handles the timing logic, while DMA continuously transfers 32-bit data blocks (512 bytes per line) into RAM.
📥 If the SOI marker (0xFFD8) isn’t detected within the first 4 lines (512B × 4),
the system retries until a valid frame is captured.
6. Final Streaming Process (UDP-based Transmission)
Since JPEG frames vary in size (a few KB to tens of KB),
a single UDP packet cannot contain the entire image.
Therefore, the Pico splits each frame into ≤1,400-byte payloads,
attaching a small 4-byte header to each.
Byte | Field | Description |
---|---|---|
[0] | Frame ID | Frame identifier |
[1] | Packet ID | Sequence number within the frame |
[2] | Total Packets | Total packet count |
[3] | End Flag | 0x01 = last packet |
[4~] | JPEG Data | Image data segment |
Example: UDP Packetization of a 30KB JPEG Frame
A 30KB (≈30,000 bytes) JPEG image is split into 22 UDP packets,
each carrying up to 1,400 bytes (4-byte header + 1,396B data).
Byte | Field | Description |
---|---|---|
[0] | Frame ID | Current frame number |
[1] | Packet ID | Sequence within frame |
[2] | Total | Total packet count |
[3] | End Flag | 0x01 = last packet |
[4~] | JPEG Data | Image segment |
Example Sequence:
Frame #1 (30KB JPEG)
├─ Packet 0: [Frame=1, ID=0, Total=22, End=0]
├─ Packet 1: [Frame=1, ID=1, Total=22, End=0]
...
└─ Packet 21: [Frame=1, ID=21, Total=22, End=1]
Receiver reassembles packets by Frame/Packet ID → complete JPEG → display.
📡 Transmission (Pico)
🧩 Reassembly (Python)
On the receiver side, each packet is reassembled based on Frame ID and Packet ID.
The Assembler
class reconstructs full JPEG frames as follows:
OpenCV then decodes and displays the frame in real time.
🖥️ Even with UDP transport, this design achieves lossless frame assembly through intelligent ID-based reordering.
7. Key Takeaways
Feature | Description |
---|---|
⚡ Ultra-Low Latency | Real-time 1-frame streaming with UDP + PIO + DMA |
🧩 Modular Architecture | Camera, network, and viewer are fully decoupled |
💡 Easy Customization | Adjustable JPEG quality, resolution, and frame rate |
🧠 Scalable Application | Ready for IoT cameras, machine vision, inspection, or robotics |