---
title: "PicoCamera voit en 1600×1200. Sa RAM, beaucoup moins"
locale: "fr"
url: "https://irz.fr/fr/articles/picocamera-memory-wall-fr"
markdown_url: "https://irz.fr/fr/articles/picocamera-memory-wall-fr.md"
category: "tech"
tags: ["RP2040", "RP2350", "camera", "Arduino", "PIO", "DMA"]
published_at: "2026-08-20T09:01:00.000Z"
author: "Hugo Marchal"
translation: "https://irz.fr/en/articles/picocamera-memory-wall-en.md"
---

# PicoCamera voit en 1600×1200. Sa RAM, beaucoup moins

PicoCamera ouvre OV2640, OV3660 et OV7670 aux RP2040/RP2350. Mais en image brute, le vrai plafond n’est pas le capteur : c’est la taille du framebuffer.

Une OV2640 sait produire une image de 1600 × 1200 pixels. PicoCamera sait lui demander cette définition. Pourtant, brancher le capteur sur un RP2040 ne donne pas soudain à la puce la place nécessaire pour garder une telle image en mémoire.

C’est le détail qui rend cette jeune bibliothèque plus intéressante qu’une nouvelle couche de compatibilité Arduino. **PicoCamera expose des capacités de capteur qui dépassent très vite la mémoire du microcontrôleur**, et sa version 0.4.0, publiée le 18 août, vient justement d’ajouter le placement des framebuffers en PSRAM sur RP2350.[1](https://github.com/umeiko/PicoCamera/tree/6c558bdbc6c73d2f17f99eaa2452e26d400f3405)

Nous avons audité le dépôt au commit `6c558bd`, celui de la release 0.4.0. La promesse « RP2040 / RP2350 » tient à la compilation. Ce qui change réellement entre les deux familles, puis entre un RP2350 nu et une carte équipée de PSRAM, est la quantité d’image que l’on peut conserver à un instant donné.

## Trois capteurs

PicoCamera reprend volontairement une partie de l’API `esp32-camera`. Le préfixe `esp_` devient `pico_`, tandis que la configuration conserve l’idée d’un `camera_config_t`, d’un framebuffer renvoyé par `pico_camera_fb_get()` et d’un objet capteur contrôlable à l’exécution.[1](https://github.com/umeiko/PicoCamera/tree/6c558bdbc6c73d2f17f99eaa2452e26d400f3405)

Trois capteurs sont annoncés et marqués comme vérifiés sur matériel : **OV2640**, **OV3660** et **OV7670**. Les deux premiers savent produire du JPEG dans le capteur, alors que l’OV7670 est limité ici au RGB565 et ne possède pas d’encodeur JPEG embarqué.[1](https://github.com/umeiko/PicoCamera/tree/6c558bdbc6c73d2f17f99eaa2452e26d400f3405)

L’acquisition passe par les PIO et le DMA des puces Raspberry Pi. Les huit bits du bus caméra doivent arriver sur huit GPIO consécutifs, tandis que VSYNC, HREF et PCLK sont choisis à l’exécution. La SCCB utilisée pour configurer le capteur repose sur le vrai périphérique I2C, avec les contraintes de multiplexage des broches correspondantes.[2](https://github.com/umeiko/PicoCamera/blob/6c558bdbc6c73d2f17f99eaa2452e26d400f3405/docs/user_guide.md)

> Illustration: Fenêtre Python affichant une capture JPEG transmise par PicoCamera. Un des exemples envoie les images par USB série vers une petite visionneuse Python. L’acquisition reste faite sur le microcontrôleur. Credit: [umeiko / PicoCamera](https://github.com/umeiko/PicoCamera/tree/6c558bdbc6c73d2f17f99eaa2452e26d400f3405/examples/push_image_to_python).

Ce fonctionnement est assez proche de l’ESP32 pour faciliter le portage d’un sketch, mais la marge matérielle derrière l’API reste très différente.

## Le mur RGB

En refaisant ce calcul directement à partir du format RGB565, je me suis rendu compte que la contrainte devient visible presque immédiatement : **deux octets par pixel**.[2](https://github.com/umeiko/PicoCamera/blob/6c558bdbc6c73d2f17f99eaa2452e26d400f3405/docs/user_guide.md) Une image de 320 × 240 occupe 153 600 octets, soit 150 KiB. En passant à 640 × 480, on atteint déjà 614 400 octets, soit 600 KiB, et le 1600 × 1200 pousse le framebuffer à 3 840 000 octets, environ 3,66 MiB.

Raspberry Pi donne **264 KiB de SRAM** au RP2040 et **520 KiB** au RP2350.[5](https://www.raspberrypi.com/documentation/microcontrollers/pico-series.html) Même en imaginant que toute cette mémoire soit libre, un framebuffer VGA RGB565 de 600 KiB ne tient donc sur aucune des deux puces en SRAM interne.

La documentation PicoCamera en tire une règle beaucoup plus réaliste : sur RP2040, **QVGA 320 × 240 constitue le plafond pratique en RGB565**.[2](https://github.com/umeiko/PicoCamera/blob/6c558bdbc6c73d2f17f99eaa2452e26d400f3405/docs/user_guide.md) Il faut encore laisser de la mémoire au programme, à la pile, aux structures du pilote et au reste de l’application.

> 1 framebuffer RGB565
> **Le capteur grandit plus vite que la SRAM**
> - QVGA 320×240 : tient sur RP2040.: 150 KiB
> - VGA 640×480 : dépasse RP2040 et RP2350.: 600 KiB
> - UXGA 1600×1200 : exige une mémoire externe en brut.: 3,66 MiB
> - SRAM totale des RP2040 / RP2350.: 264 / 520 KiB
> Calcul IRZ : largeur × hauteur × 2 octets. La mémoire totale d’une puce n’est évidemment pas entièrement disponible au framebuffer.

Le passage au RP2350 ne suffit donc pas à franchir ce mur. Ses 520 KiB doublent presque la marge du RP2040, mais restent sous les 600 KiB d’une seule image VGA brute.

## La PSRAM change la carte

PicoCamera 0.4.0 ajoute trois politiques : framebuffer en SRAM, en PSRAM, ou mode automatique. Sur une carte RP2350 dont la PSRAM est activée par le core Arduino, le mode automatique tente `pmalloc()`. Si aucune PSRAM n’est disponible, il retombe en SRAM. Une demande explicite de PSRAM échoue, elle, si cette mémoire n’existe pas.[3](https://github.com/umeiko/PicoCamera/blob/6c558bdbc6c73d2f17f99eaa2452e26d400f3405/src/pico_camera.cpp)

Le RP2040 n’a pas cette voie dans la bibliothèque. Pour lui, le framebuffer reste en SRAM.[2](https://github.com/umeiko/PicoCamera/blob/6c558bdbc6c73d2f17f99eaa2452e26d400f3405/docs/user_guide.md)

Cette différence transforme la PSRAM en frontière fonctionnelle. Avec quelques mégaoctets externes, VGA, SVGA ou UXGA deviennent envisageables en RGB565. Sur une carte dépourvue de cette mémoire, augmenter la définition du capteur ne sert à rien si le tampon ne peut pas être alloué.

Le nombre de buffers compte aussi. `fb_count = 2` demande deux fois la place d’un buffer. Une image QVGA RGB565 représente 150 KiB. Deux buffers représentent déjà 300 KiB, au-delà de toute la SRAM d’un RP2040 avant même de compter le programme.[3](https://github.com/umeiko/PicoCamera/blob/6c558bdbc6c73d2f17f99eaa2452e26d400f3405/src/pico_camera.cpp)

## JPEG triche utilement

Les OV2640 et OV3660 possèdent un encodeur JPEG. PicoCamera peut donc recevoir une image déjà compressée au lieu de réserver deux octets pour chaque pixel.[1](https://github.com/umeiko/PicoCamera/tree/6c558bdbc6c73d2f17f99eaa2452e26d400f3405)

La bibliothèque ne connaît cependant pas à l’avance la taille du JPEG. Elle réserve un tampon estimé à `largeur × hauteur / 4 + 8 KiB`, puis capture jusqu’à la fin du flux JPEG.[3](https://github.com/umeiko/PicoCamera/blob/6c558bdbc6c73d2f17f99eaa2452e26d400f3405/src/pico_camera.cpp)

Avec cette formule, un tampon UXGA vaut environ **477 KiB**. Sur le papier, il passe sous les 520 KiB du RP2350, mais il laisserait une marge microscopique au reste du système. Sur RP2040, il dépasse largement les 264 KiB.

Et l’auteur documente une limite importante : cette estimation couvre les scènes typiques, mais **une image très bruitée peut dépasser la taille réservée**.[2](https://github.com/umeiko/PicoCamera/blob/6c558bdbc6c73d2f17f99eaa2452e26d400f3405/docs/user_guide.md) Le JPEG rend donc les grandes définitions possibles avec beaucoup moins de RAM, mais une sortie de taille variable ne devient pas pour autant parfaitement prévisible.

## Compatible, avec conditions

L’autre partie de notre audit était plus simple : vérifier que « compatible RP2040 / RP2350 » ne signifie pas seulement que les noms apparaissent dans un README.

Au commit `6c558bd`, la CI upstream compile quatre exemples principaux sous **RP2040, RP2350 ARM, RP2350 RISC-V et un environnement RP2350 avec le chemin PSRAM activé**, avec warnings transformés en erreurs. Le même commit passe également un build séparé de l’exemple CMake utilisant directement le Pico SDK.[4](https://github.com/umeiko/PicoCamera/actions/runs/32113283023)

Cela valide la compilation des exemples, pas une caméra physique branchée à chaque matrice. Pour le matériel, le dépôt indique avoir vérifié OV2640, OV3660 et OV7670, sans publier de campagne de mesure de débit ou de framerate couvrant toutes les résolutions.[1](https://github.com/umeiko/PicoCamera/tree/6c558bdbc6c73d2f17f99eaa2452e26d400f3405)

La librairie reste aussi synchrone : `pico_camera_fb_get()` déclenche une capture bloquante. Le `grab_mode` de `esp32-camera` n’est pas implémenté et la documentation n’en fait pas mystère.[2](https://github.com/umeiko/PicoCamera/blob/6c558bdbc6c73d2f17f99eaa2452e26d400f3405/docs/user_guide.md)

## Une API ne crée pas de RAM

Adafruit a relayé PicoCamera comme une bibliothèque Arduino-compatible destinée aux RP2040 et RP2350.[6](https://blog.adafruit.com/2026/08/19/picocamera-an-arduino-compatible-camera-library-for-the-rp2040-rp2350/) C’est exact, mais la partie la plus utile du projet se trouve peut-être dans les restrictions qu’il expose au lieu de les cacher.

Huit GPIO consécutifs pour les données. Une SCCB contrainte par le multiplexage I2C. Un capteur sans JPEG qui refuse le JPEG. Un framebuffer qui échoue s’il ne tient pas. Une PSRAM disponible seulement sur les cartes qui en possèdent réellement.

Ce sont ces détails qui rendent l’API crédible. Elle rapproche le geste de programmation de `esp32-camera` sans prétendre que le RP2040 est devenu un ESP32 doté de mémoire externe.

Pour un maker, la décision se résume alors beaucoup mieux : **choisir d’abord ce que l’image doit devenir, puis seulement sa définition**. Une analyse locale en QVGA brut, une photo JPEG plus grande envoyée ailleurs et un flux VGA RGB565 n’imposent pas du tout la même architecture.

Le capteur peut voir grand. Le framebuffer, lui, vous rappelle combien coûte chaque pixel.

## References

1. [umeiko, PicoCamera 0.4.0, commit 6c558bd](https://github.com/umeiko/PicoCamera/tree/6c558bdbc6c73d2f17f99eaa2452e26d400f3405)
2. [PicoCamera, guide utilisateur](https://github.com/umeiko/PicoCamera/blob/6c558bdbc6c73d2f17f99eaa2452e26d400f3405/docs/user_guide.md)
3. [PicoCamera, moteur d’allocation des framebuffers](https://github.com/umeiko/PicoCamera/blob/6c558bdbc6c73d2f17f99eaa2452e26d400f3405/src/pico_camera.cpp)
4. [PicoCamera, CI multi-architecture](https://github.com/umeiko/PicoCamera/actions/runs/32113283023)
5. [Raspberry Pi, Pico microcontroller boards](https://www.raspberrypi.com/documentation/microcontrollers/pico-series.html)
6. [Adafruit, PicoCamera: an Arduino-compatible camera library for the RP2040 / RP2350](https://blog.adafruit.com/2026/08/19/picocamera-an-arduino-compatible-camera-library-for-the-rp2040-rp2350/)
