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 |
