
V3 placed
ameesme/little-camera
A small black-and-white camera that posts to its own tiny blog, and everything around it.

A small black-and-white camera that posts to its own tiny blog, and everything around it.
V2 reference is an open-source printed circuit board by ameesme, from the ameesme/little-camera repository on GitHub, published under the MIT licence. It is a 4-layer board of 63.8 × 50.8 mm with 85 parts on 60 nets, routed with 787 tracks and 159 vias.
It is built around the ESP32-S3-WROOM-1-N16R8, TPS61222DCK and AP2112K-3.3, with the 74LVC1G14Z, ME6211C12M5G-N and ME6211C28M5G-N among its other parts. Its parts include 34 resistors, 23 capacitors, 8 ICs, 5 connectors and 4 diodes. It belongs with the ESP32 boards of this library.
A small black-and-white camera that posts to its own tiny blog, and everything around it.
firmware/ ESP32-S3 firmware (PlatformIO). Viewfinder, gallery, flash storage, BLE sync and update.
hardware/ The board it runs on: KiCad schematic + PCB, written by Python.
app/ios/ Bridge app (SwiftUI + CoreBluetooth). Carries photos off the camera and firmware back to it.
server/ Micro-blog + API (TypeScript, Hono, SQLite). One subdomain per owner.
deploy/ Docker Compose + Caddy (wildcard TLS) for a VPS.
site/ The lttl.cam teaser, static on Vercel.
packages/ Shared TypeScript: PBM parsing, PNG encoding, short codes.
docs/ protocol.md (the contract), flows.md (who does what), mood.md (the camera as a small creature).The service is lttl.cam, and a blog is one label under it (mees.lttl.cam). The landing page owns lttl.cam/, and everything the server answers on that domain sits under /api for machines or /app for people, so a proxy can tell the two apart.
Everything is black and white. Where a grey is unavoidable it is a 2 px checker.
Do this before you flash anything from here. It reads the flash and writes nothing:
cd firmware/tools/export
python3 -m venv .venv && .venv/bin/pip install -r requirements.txt
.venv/bin/python dump_flash.py --port /dev/cu.usbmodem* # backup/<timestamp>/NNNN.pbm + .pngThe partition table and file format are unchanged, so flashing keeps the photos on the device too, and the first sync uploads them all.
cd firmware
pio run -e v3q -t upload -t monitor
cd tools/preview && make scenes # the UI without hardware, BMPs in out/Read firmware/AGENTS.md before anything hardware-facing.
Press = shoot. Hold 0.7 s in the viewfinder = gallery (press = next, hold = back). On the review screen press = save, hold 1.5 s = trash. Asleep: hold 1 s to wake, a tap only chirps.
The camera has a mood (docs/mood.md): it sleeps with a smile after a photo, loses it over a week, and chirps for attention. The sounds are composed, not recorded, and cd firmware/tools/chirp && make bands renders them to WAV.
New firmware can also come over Bluetooth from the app (docs/protocol.md §3.7). It is written to the slot the camera is not running from, and the bootloader only points at it once every byte has arrived and the SHA-256 matches, so a failed update costs time and nothing else. ota revert on the USB console is the way back after you flash over the wire.
v3q, 62.8 × 42.82 mm, four layers, 80 parts, KiCad 10. Schematic hardware/pcb/little_camera.kicad_sch, board hardware/pcb/little_camera.kicad_pcb, and little_camera_2d_view.svg next to them if you have no KiCad. Neither is drawn by hand: hardware/pcb/gen/design.py holds every part and connection and the rest of gen/ builds, places and routes from it. See hardware/README.md.
Pins are shared with the firmware and written down in firmware/AGENTS.md. Change them in both places.
pnpm install
pnpm dev # http://localhost:3000/app, blogs at http://<handle>.localhost:3000
pnpm test
pnpm seed # demo blog at http://mees.localhost:3000Without SMTP settings every email lands in /app/dev/mailbox. server/README.md has the environment variables and the fake camera; server/deploy/ has production, including how a firmware release is published.
cd app/ios && xcodegen generate && open LittleCamera.xcodeprojNeeds a real device, because Bluetooth. Set the server URL on first launch. The app never signs in: it identifies as the camera it is paired with.
Make the blog in the app, confirm the address from the link it emails you, then photograph the QR the app draws and press send: the app uploads it, the server binds the camera to your blog, and every photo you send from then on lands on https://<handle>.lttl.cam. Friends join with their email and get one link per batch of new pictures. The web only ever shows pictures — everything else is the app. Step by step in docs/flows.md.
| Qty | Value | Footprint | References |
|---|---|---|---|
| 6 | 100k | Resistor_SMD:R_0402_1005Metric | R3, R8, R12, R18, R28, R31 |
| 6 | 100nF | Capacitor_SMD:C_0402_1005Metric | C6, C7, C14, C19, C20, C24 |
| 6 | 1uF | Capacitor_SMD:C_0402_1005Metric | C4, C8, C10, C12, C22, C23 |
| 5 | 10k | Resistor_SMD:R_0402_1005Metric | R13, R14, R20, R21, R26 |
| 4 | 1M | Resistor_SMD:R_0402_1005Metric | R4, R19, R34, R35 |
| 4 | 330R | Resistor_SMD:R_0402_1005Metric | R22, R23, R24, R25 |
| 4 | 4.7k | Resistor_SMD:R_0402_1005Metric | R10, R11, R15, R16 |
| 4 | MountingHole_1.8mm | lc:MountingHole_1.8mm | MH1, MH2, MH3, MH4 |
| 3 | 10uF | Capacitor_SMD:C_0603_1608Metric | C16, C17, C21 |
| 3 | 2.2uF | Capacitor_SMD:C_0603_1608Metric | C9, C11, C13 |
| 2 | 1k | Resistor_SMD:R_0402_1005Metric | R6, R27 |
| 2 | 200k | Resistor_SMD:R_0402_1005Metric | R9, R33 |
| 2 | 4.7uF | Capacitor_SMD:C_0603_1608Metric | C1, C2 |
| 2 | 5.1k | Resistor_SMD:R_0402_1005Metric | R1, R2 |
| 2 | AP2112K-3.3 | Package_TO_SOT_SMD:SOT-23-5 | U4, U10 |
| 1 | 0R | Resistor_SMD:R_0402_1005Metric | R29 |
| 1 | 10uF | Capacitor_SMD:C_0805_2012Metric | C5 |
| 1 | 1N4148W | Diode_SMD:D_SOD-123 | D4 |
| 1 | 1uF | Capacitor_SMD:C_0603_1608Metric | C18 |
| 1 | 2.2k | Resistor_SMD:R_0402_1005Metric | R17 |
| 1 | 22uF | Capacitor_SMD:C_0805_2012Metric | C3 |
| 1 | 2N7002 | Package_TO_SOT_SMD:SOT-23 | Q2 |
| 1 | 3.3k | Resistor_SMD:R_0402_1005Metric | R5 |
| 1 | 4.7uH | Inductor_SMD:L_0805_2012Metric | L1 |
| 1 | 47k | Resistor_SMD:R_0402_1005Metric | R7 |
| 1 | 74LVC1G14 | Package_TO_SOT_SMD:SOT-23-5 | U8 |
| 1 | AO3401A | Package_TO_SOT_SMD:SOT-23 | Q1 |
| 1 | B5819W | Diode_SMD:D_SOD-123 | D1 |
| 1 | BAT | lc:BAT_Pads_1x02 | J5 |
| 1 | BOOT | Button_Switch_SMD:SW_SPST_TS-1088-xR020 | SW2 |
| 1 | CAM ON | LED_SMD:LED_0603_1608Metric | D3 |
| 1 | CHG | LED_SMD:LED_0603_1608Metric | D2 |
| 1 | D2F-01-A | lc:SW_Omron_D2F-A_RightAngle | SW1 |
| 1 | DNP | Resistor_SMD:R_0402_1005Metric | R30 |
| 1 | ESP32-S3-WROOM-1-N16R8 | lc:ESP32-S3-WROOM-1 | U1 |
| 1 | LS027B7DH01 | lc:FPC_BXCONN_FC-05B10P21H20 | J3 |
| 1 | ME6211C12M5G | Package_TO_SOT_SMD:SOT-23-5 | U6 |
| 1 | ME6211C28M5G | Package_TO_SOT_SMD:SOT-23-5 | U5 |
| 1 | MLT-5020 | lc:Buzzer_SMD_MLT5020 | BZ1 |
| 1 | OV2640 DVP | lc:FPC_BXCONN_FC-05B24P21H20 | J2 |
| 1 | RESET | Button_Switch_SMD:SW_SPST_TS-1088-xR020 | SW3 |
| 1 | SPARE IO | lc:IO_Breakout_1x06 | J4 |
| 1 | TP4054 | Package_TO_SOT_SMD:SOT-23-5 | U2 |
| 1 | TPS61222 | Package_TO_SOT_SMD:SOT-363_SC-70-6 | U7 |
| 1 | USB-C | lc:USB_C_Kinghelm_KH-TYPE-C-W-SMT-16P | J1 |

ameesme/little-camera
A small black-and-white camera that posts to its own tiny blog, and everything around it.

ameesme/little-camera
A small black-and-white camera that posts to its own tiny blog, and everything around it.

ameesme/little-camera
A small black-and-white camera that posts to its own tiny blog, and everything around it.

Guilleloma/Furby-GPT
This project transforms a 1998 Furby into an interactive and advanced desktop assistant using a Raspberry Pi W. It incorporates OpenAI and Whisper for natural language processing, primarily relying on Google Cloud Text…

HeyPCB/iris-cortex
Iris Cortex: head controller of the Iris robot head. ESP32-S3 (16 MB flash, 8 MB PSRAM), OV2640 eye-camera FPC, iris-ring LED drivers, harness hub.

PHS-SMCS/falcon-core
Lightest ESP32-based blimp controller with the works; 9-DoF, ToF altimetry, motor drivers, and Wi-Fi enabled camera streaming, all on a single 300mAh LiPo. >1hr of battery life.




calperxd/tangnano9k-kr260-hat
FPGA HAT for the AMD Kria KR260 based on the Tang Nano 9K (Gowin GW1NR-9, FT2232H, 16-bit parallel link on J21): KiCad 10 schematic, 4-layer PCB and JLCPCB production files

timex-sinclair-projects/TS-2068-Megabank
Battery-backed 4 MB expansion-bank RAM board for the Timex Sinclair 2068 (TS-Pico v3)
It measures 63.8 × 50.8 mm and has 4 copper layers, 1.6 mm thick.
85 parts, built around the ESP32-S3-WROOM-1-N16R8, TPS61222DCK, AP2112K-3.3 and 74LVC1G14Z. 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.
From the ameesme/little-camera repository on GitHub, at the commit this page was made from: the board is hardware/pcb/gen/v2_reference.kicad_pcb and its schematic hardware/pcb/gen/v3q_pre_dock.kicad_sch. PCBKit opens the board in the browser, with nothing to install.
Its repository publishes it under the MIT licence: you may reuse it on that licence's terms (keep the author's notice, and for a copyleft licence share your changes alike).