---
title: "ArduCAM × W6300-EVB-Pico2 High-Speed JPEG Streaming Project (C/C++)"
url: "https://maker.wiznet.io/TheoIm/projects/arducam--w6300-evb-pico2-high-speed-jpeg-streaming-project-c-c/"
markdown_url: "https://maker.wiznet.io/TheoIm/projects/arducam--w6300-evb-pico2-high-speed-jpeg-streaming-project-c-c/md"
type: "WCC: WIZnet Created Content"
author: "theo"
author_url: "https://maker.wiznet.io/TheoIm/"
original_author: "theo"
published: "2025-10-14"
language: "en"
hardware: ["Arducam Quick-Bootup 3MP DVP Camera for IoT"]
likes: 0
views: 1330
comments: 0
source: "WIZnet Makers (https://maker.wiznet.io/)"
---

# 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.

Original author: theo

## Components

- **Arducam Quick-Bootup 3MP DVP Camera for IoT** x 1

## Article

## **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**.

![](https://maker.wiznet.io/upload/ckeditor5/646823462%5F1760453988%2Epng)

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.

![](https://maker.wiznet.io/upload/ckeditor5/646823462%5F1760459035%2Egif)

[**ArduCam X WIZnet Pico UDP Streaming Github Project Link**](https://github.com/theoim/ArduCam_Mega_X_WIZnet_Pico_UDP_Streaming)

> 🧠 **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\]**](https://docs.wiznet.io/Product/Modules/Open-Source-Hardware/rp2040_based)

[**\[WIZnet Pico RP2350 Based Link\]**](https://docs.wiznet.io/Product/Modules/Open-Source-Hardware/rp2350_based)

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\]**](https://www.arducam.com/arducam-quick-bootup-3mp-dvp-camera-for-iot.html)

| 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)**

```plaintext
① VSYNC ↑ → Frame Start  
② HSYNC ↑ → New Line Start  
③ PCLK ↑ → Sample D0–D7 (8-bit pixel)  
④ DMA stores 32-bit chunks into line buffer  
⑤ HSYNC ↓ → Line End  
⑥ VSYNC ↓ → Frame End
```

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:**

```plaintext
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)**

```c
total_packets = (jpeg_size + PAYLOAD_SIZE - 1) / PAYLOAD_SIZE;

for (pkt_id = 0; pkt_id < total_packets; pkt_id++) {
    tx_packet[0] = frame_id;
    tx_packet[1] = pkt_id;
    tx_packet[2] = total_packets;
    tx_packet[3] = (pkt_id == total_packets - 1) ? 0x01 : 0x00;

    memcpy(tx_packet + 4, jpeg_data + offset, chunk_size);
    sendto(socket, tx_packet, chunk_size + 4, destip, destport);
}
```

---

### 🧩 **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:

```python
fid, pid, tot = pkt[0], pkt[1], pkt[2]
self.buf.setdefault(fid, {})[pid] = pkt[4:]
if len(self.buf[fid]) == tot:
    data = b"".join(self.buf[fid][i] for i in range(tot))
    return data  # Complete JPEG frame restored
```

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 |

---

Source: https://maker.wiznet.io/TheoIm/projects/arducam--w6300-evb-pico2-high-speed-jpeg-streaming-project-c-c/
