Skip to the content
PCBKitNew board
2 layers25 × 23.9 mmRpi camera led, the printed circuit board in 3D

Interposer for the Raspberry Pi camera flex cable: passes the 15-way CSI bus straight through and adds I2C-controlled camera GPIO, PWM illumination LEDs and an ambient light sensor, driven by a CH32V003.

Size
25 × 23.9 mm
Copper layers
2
Thickness
1.6 mm
Parts
24
Nets
22
Pads
94
Tracks, vias
37, 0
Pours
2
Routed
Yes
KiCad
KiCad 9.0 (file 20241229)
Created
3 Sep 2026
Updated
5 Sep 2026

Overview

Rpi camera led is an open-source printed circuit board by mithro, from the mithro/rpi-camera-led repository on GitHub, published under the Apache-2.0 licence. It is a 2-layer board of 25 × 23.9 mm with 24 parts on 22 nets, routed with 37 tracks and 0 vias.

It is built around the CH32V003A4M6 and AO3400A. Its parts include 9 resistors, 4 connectors, 2 capacitors, 2 diodes and 2 transistors. It belongs with the RISC-V boards of this library.

Main components

2

README

README.md

RPi Camera LED

An interposer for the Raspberry Pi camera flex cable (15 pin, 1.0 mm pitch FPC). It sits in the middle of the cable, passes all fifteen camera signals straight through, and adds a CH32V003A4M6 that gives the Pi I2C-controlled camera GPIO, PWM illumination LEDs and an ambient light reading.

Hardware

KiCad schematic · PDF · board

Board: 15-way FFC camera interposer

3D render, top3D render, bottomLayout (copper, silk, outline)
Interposer, front sideInterposer, back sideInterposer copper layout

25.0 × 23.9 mm, two layers, everything on the front. J1 (left) faces the Raspberry Pi and J2 (right) faces the camera; they sit 180° apart so the two cable segments leave opposite edges and the board drops into an existing cable run in line. The MCU is the SOIC-16 in the middle, the two white illumination LEDs and the phototransistor are along the top edge.

The outline is the Camera Module 2 board: 25.000 × 23.862 mm with 2.0 mm corner radii, and the same four Ø2.2 mm mounting holes, so the interposer takes the camera's screws. Those come straight off the official mechanical drawing (RP-008149-DS, RPI-CAM-V2_1): "4x 2.2mm diameter holes", 2 mm in from each end of the 25 mm axis — a 21.0 mm pitch — and 12.5 mm apart on the other. check_pcb.py now verifies pitch and drill, because these went missing once already without anyone noticing.

The layout is in progress. Eleven of the twenty footprints — C1, C2, J3, J4, Q1, R1–R4, R8 and R9 — are still parked outside the board outline, which is why they float around the board in the renders. The fifteen-way pass-through bus is routed; the rest is not. DRC reports 21 violations and 34 unconnected items.

Four of those violations are the mounting holes, and they are a real conflict rather than noise. All four holes land underneath a connector housing. On the camera the 21.0 mm pitch runs between two edges that carry nothing, and its single FFC connector sits on a third; this board has a connector on both ends of that axis, each housing 5.30 mm deep, so the holes — 2 mm in from each end — sit under them. Nothing on the board is wrong in isolation; the camera's mounting pattern and two edge-mounted connectors simply cannot both fit on a 25 mm span. Resolving it means giving something up: a longer board, connectors on the 25 mm edges instead, or mounting holes that no longer match the camera.

How the cables run

With cables fittedIsometric
Interposer with FFC cables in both connectorsIsometric view of the interposer with cables

Both cables enter from the outside edges and run away from the board in opposite directions, so the interposer drops into an existing cable run in line. That follows from where the cable entry is on this connector: the manufacturer's Section A‑A shows the solder tail stepping down and out at one end while the cable channel opens at the other, and the top view labels Terminal at one end and Latch at the other with the 5.30 mm housing between them. It is also the only way a slide lock can work — you pull the slider, insert the cable and push it back, all at the same end. So the cable entry is at the latch end, away from the pads, and with each connector's housing flush against its board edge that entry points outward.

The two cable stubs are drawn different ways up, and that is the point. J1 is bottom contact, so its cable presents bared copper downwards and shows you the blue backing; J2 is top contact, so its cable is the other way up and shows you the conductors. That flip is the whole reason for pairing an F part with an E part, and it is what lets both segments be ordinary Raspberry Pi camera cables — the same flip you can see in a real cable, blue stiffener on one face at one end, bared conductors on the other face at the other.

The stubs are illustrative and are not part of the board: they exist only in a throwaway copy that the render script builds and deletes. Their 16.00 × 0.30 mm section is the drawing's recommended FFC dimension. The bared conductors and the backing are drawn a little longer than the 4 mm insertion depth so that a few millimetres of each stay visible outside the connector — otherwise the orientation they exist to show would be buried inside it.

Regenerate the images with uv run hardware/tools/render_board.py, and the connector models with uv run hardware/tools/gen_connector_model.py. The render script refills the copper zones first, via the pcbnew Python module inside the KiCad snap, because kicad-cli has no zone-fill command and a stale pour renders as authoritatively as a fresh one — when this was first wired up the stored B.Cu pour was less than half its true area, and refilling it dropped DRC from 116 violations to 17.

Connectors, and which cables fit

J1 and J2 are not the same part, and that is deliberate:

partcontactsmates with
J1 → Raspberry PiJUSHUO AFA07-S15FCA-00 (LCSC C262721)bottom — cable copper faces the boarda standard Pi camera cable
J2 → cameraJUSHUO AFA07-S15ECA-00 (LCSC C262742)top — cable copper faces awaya standard Pi camera cable

The reason is cable parity. A Raspberry Pi camera cable is an opposite-side FFC — "type 2", contacts on one face at one end and the other face at the other — because the Pi's CSI socket is top-contact and the camera module's is bottom-contact. Cutting one continuous cable anywhere yields one same-side half and one opposite-side half, so an interposer whose two connectors want the copper on the same face forces one odd, hard-to-buy cable. One that wants it on opposite faces absorbs the asymmetry, and both segments become ordinary Raspberry Pi camera cables. Bottom-contact at J1 plus top-contact at J2 is that pairing.

The two variants share one land pattern — verified against both JUSHUO drawings — so nothing on the board moves between them. Since only the contact side differs, and it is invisible on an assembled board, the distinction is called out in each symbol's value, in the MPN, and as a BOTTOM CONTACT / TOP CONTACT marker on the fab layer.

Both footprints and their 3D models live in this repository, in hardware/rpi-camera-led.pretty and hardware/rpi-camera-led.3dshapes. KiCad's stock footprint references a STEP file for the JUSHUO AFA07 series that does not exist — not in the KiCad distribution and not in kicad-packages3D upstream, which ships no JUSHUO models at all. Third-party libraries have one, but under terms that forbid redistribution, so hardware/tools/gen_connector_model.py builds it from the manufacturer's published drawing instead: a 22.00 × 6.95 × 2.50 mm envelope matching the drawing's DIM D, the F.Fab outline and the side view's height, with the housing and latch coloured as the drawing's notes specify. Both STEP and WRL are generated, the latter in the 0.1-inch units KiCad expects.

The pass-through bus is wired J1 pin k ↔ J2 pin 16−k. That looks reversed but is exactly right: the two connectors are 180° apart, so J1 pad k physically faces J2 pad 16−k, and joining the pads that face each other is both the straight route and the electrically transparent one — the board behaves as a splice in the middle of one continuous cable. check_pcb.py measures that facing alignment as a number, because losing it to a stray drag puts a dogleg in all fifteen nets and is invisible by eye.

Verifying

text
uv run hardware/tools/check_schematic.py   # ERC + netlist vs design intent
uv run hardware/tools/check_pcb.py         # connector alignment + DRC parity

check_schematic.py currently fails: its expected-netlist table still describes the older pin-for-pin bus, and four issues from the last eeschema session are open — U1 pin 13 is unconnected, SWIO and CAM_IO1 have been merged onto one net, I2C is landed on pins that cannot carry it on this package (the CH32V003 SOP-16 reaches the peripheral only on pins 1 and 2, since both AFIO remaps need PD0 or PC5 and the package bonds out neither), and four no-connect flags dangle.

The schematic is maintained by hand in eeschema — connections between adjacent parts are drawn as wires rather than left implicit in matching global labels. hardware/tools/gen_schematic.py is the generator that bootstrapped it, but running it overwrites the schematic and would discard that manual wiring.

Firmware

CH32V003 firmware: a fail-safe I2C bootloader plus an application exposing camera GPIO control, RPi-side GPIO readback, GPIO pass-through, LED brightness (hardware PWM) and an ambient light reading over a Linux-friendly SMBus register map at address 0x42. Builds with riscv64-unknown-elf-gcc and ch32v003fun (git submodule update --init, then make in firmware/bootloader and firmware/app).

The firmware still targets the older pin map and needs updating to match the current schematic.

Research

Part availability research comparing JLCPCB's PCBA parts library and NextPCB's Rev0 service (which sources components from HQ Online's 600k+ in-stock inventory):

License

Apache 2.0 — see LICENSE.

Parts

24
QtyValueFootprintReferences
4MountingHole_2.2mm_M2MountingHole_2.2mm_M2H1, H2, H3, H4
20Resistor_SMD:R_0402_1005MetricR6, R7
210RResistor_SMD:R_0603_1608MetricR3, R4
24.7kResistor_SMD:R_0402_1005MetricR1, R2
2White LEDLED_SMD:LED_0805_2012MetricD1, D2
1100RResistor_SMD:R_0402_1005MetricR5
1100nFCapacitor_SMD:C_0402_1005MetricC1
110kResistor_SMD:R_0402_1005MetricR8
11uFCapacitor_SMD:C_0402_1005MetricC2
147kResistor_SMD:R_0402_1005MetricR9
1AO3400APackage_TO_SOT_SMD:SOT-23Q1
1CH32V003A4M6Package_SO:SOIC-16_3.9x9.9mm_P1.27mmU1
1FFC 15P 1.0mm bottom contact (to Raspberry Pi)rpi-camera-led:JUSHUO_AFA07-S15FCA-00_1x15-1MP_P1.0mm_HorizontalJ1
1FFC 15P 1.0mm top contact (to camera)rpi-camera-led:JUSHUO_AFA07-S15ECA-00_1x15-1MP_P1.0mm_HorizontalJ2
1PhototransistorLED_SMD:LED_0805_2012MetricQ2
1Qwiic (JST SH 1.0mm)Connector_JST:JST_SH_SM04B-SRSS-TB_1x04-1MP_P1.00mm_HorizontalJ3
1SWD program header 2.54mmConnector_PinHeader_2.54mm:PinHeader_1x03_P2.54mm_VerticalJ4

Questions

How big is the Rpi camera led PCB?

It measures 25 × 23.9 mm and has 2 copper layers, 1.6 mm thick.

What parts does the Rpi camera led use?

24 parts, built around the CH32V003A4M6 and AO3400A. The full list of its parts is on this page, with links to each part's symbol and footprint where PCBKit's library has them.

Where can I download the Rpi camera led KiCad files?

From the mithro/rpi-camera-led repository on GitHub, at the commit this page was made from: the board is hardware/rpi-camera-led.kicad_pcb and its schematic hardware/rpi-camera-led.kicad_sch. PCBKit opens the board in the browser, with nothing to install.

Can I use the Rpi camera led design in my own project?

Its repository publishes it under the Apache-2.0 licence: you may reuse it on that licence's terms (keep the author's notice, and for a copyleft licence share your changes alike).

Similar boards

  • 2 layers34.5 × 24 mmFDXB, the printed circuit board in 3D

    FDXB

    BogdanTheGeek/ch32v003_fdxb

    FDX-B Reader based on the ch32v003

    26 parts3MIT
  • 2 layers43.9 × 54.1 mmXmas tree, the printed circuit board in 3D

    Xmas tree

    BogdanTheGeek/xmas-tree

    Charlieplexed RGB Christmas Tree

    27 parts3MIT
  • 2 layers213.7 × 144.8 mmUV Curing Box, the printed circuit board in 3D

    UV Curing Box

    koko69420/UV-Curing-Box

    UV PCB resin curing box controller using WCH CH32V003 RISC-V MCU, 4x4 keypad, TM1637 display, and KiCad PCB

    151 parts
  • 2 layers45 × 49.8 mmCCCCPPPS MkI, the printed circuit board in 3D

    CCCCPPPS MkI

    BogdanTheGeek/CCCCPPPS

    Cheap Crappy Constant Current Portable Programmable Power Supply

    26 parts12MIT
  • 4 layersSUNNY C1-HEAD, the printed circuit board in 3D

    SUNNY C1-HEAD

    RSXLX/sunny-the-growing-sunflower-lamp

    SUNNY — The Growing Sunflower Lamp | A personal lamp with customizable exteriors, traceable fabrication, and a local creative workspace.

    55 parts
  • 2 layers48 × 36.5 mmOsillyscope etchable, the printed circuit board in 3D

    Osillyscope etchable

    tvlad1234/osillyscope

    Low cost, low part count CH32V003-based oscilloscope

    31 parts30MIT
  • 2 layers24.1 × 21.6 mmCh32v003a4m6-breakout, the printed circuit board in 3D

    Ch32v003a4m6-breakout

    mverdon/ch32v003a4m6-breakout

    Breakout board for prototyping with the CH32V003 MCU

    4 partsCERN-OHL-P-2.0
  • 2 layers19 × 36.8 mmCh32 8 i2c, the printed circuit board in 3D

    Ch32 8 i2c

    ruenahcmohr/ch32-expanded

    uno-sized ch32 board with 8 bit i2c expander.

    18 parts