Hi everyone!
I’m happy to share PicoCamera, a camera library for RP2040 boards (Raspberry Pi Pico and many others) that supports OV2640, OV3660 and OV7670 sensors. It’s built on PIO + DMA for efficient capture, and its API is intentionally aligned with the well‑known esp32-camera library (just replace the esp_ prefix with pico_).
This library grew out of a discussion with another developer about runtime‑assembled PIO programs – all pins (VSYNC, HREF, PCLK, data) are configured at runtime in a camera_config_t struct, so you never need to edit or re‑compile a .pio file. It works out‑of‑the‑box in the Arduino IDE, PlatformIO, and even bare CMake projects with the Pico SDK.
Installation
Arduino IDE
Open Sketch → Include Library → Manage Libraries…, search for PicoCamera and click Install.
PlatformIO
Add to your platformio.ini:
lib_deps =
umeiko/PicoCamera@^0.2.0
Quick example
#include <PicoCamera.h>
camera_config_t config = {
.pin_pwdn = -1, .pin_reset = 29, .pin_xclk = 5,
.pin_sccb_sda = 12, .pin_sccb_scl = 13,
.pin_d0 = 14, .pin_d1 = 15, .pin_d2 = 16, .pin_d3 = 17,
.pin_d4 = 18, .pin_d5 = 19, .pin_d6 = 20, .pin_d7 = 21,
.pin_vsync = 2, .pin_href = 3, .pin_pclk = 4,
.xclk_freq_hz = 10000000,
.sccb_i2c_port = 0,
.pixel_format = PIXFORMAT_RGB565, // or PIXFORMAT_JPEG
.frame_size = FRAMESIZE_QVGA,
.jpeg_quality = 10,
.fb_count = 1,
};
void setup() {
pico_camera_init(&config);
}
void loop() {
camera_fb_t *fb = pico_camera_fb_get();
if (fb) {
// fb->buf, fb->len, fb->width, fb->height
Serial.printf("frame %ux%u len=%u captured in %ums checksum=%u\n",
(unsigned)fb->width, (unsigned)fb->height,
(unsigned)fb->len, (unsigned)(t1 - t0), (unsigned)sum);
pico_camera_fb_return(fb);
}
}
Notes / limitations
- The 8 data pins (
pin_d0..pin_d7) must be consecutive GPIOs – this is a hardware limitation of the RP2040 PIOin pinsinstruction. - No PSRAM support; frame buffers live in the 264KB SRAM. For RGB565, stay at QVGA or below in practice; JPEG buffers are estimated as
width*height/4 + 8KB. grab_modeis not supported –pico_camera_fb_get()captures one frame blocking (equivalent toCAMERA_GRAB_WHEN_EMPTY).
Repository
GitHub: https://github.com/umeiko/PicoCamera
License: MIT
I’d love to hear your feedback, bug reports, or feature requests. Feel free to open an issue or PR on GitHub.
Happy capturing!