Skip to the content
4 layers55 × 85 mmPokodoro, the printed circuit board in 3D

Poko: a phone-free MagSafe companion. nRF52840 + Zephyr, round display, haptic ring, voice memos, iPhone app, parametric CAD, KiCad.

Size
55 × 85 mm
Copper layers
4
Thickness
1.6 mm
Parts
52
Nets
58
Pads
207
Tracks, vias
356, 55
Pours
1
Routed
Yes
KiCad
KiCad 8.0 (file 20240108)
Created
15 Oct 2026
Updated
15 Oct 2026

Overview

Pokodoro is an open-source printed circuit board by justinjchae, from the justinjchae/poko repository on GitHub. It is a 4-layer board of 55 × 85 mm with 52 parts on 58 nets, routed with 356 tracks and 55 vias.

It is built around the ESP32-S3-WROOM-1-N4, 1N5819HW-7-F-01 and MCP73831T-2ACI/OT-HXY, with the MIC5219-3.3YM5-TR, B3F-4050 and BC817 among its other parts. Its parts include 15 capacitors, 12 resistors, 7 ICs, 5 switches and 4 connectors. It belongs with the radio and wireless and lEDs and displays boards and the ESP32 and nRF52 and nRF5x boards of this library.

Main components

9

README

README.md

Poko

A palm-sized, phone-free companion: the things you'd pick up your phone for, without picking up your phone.

A round 240×240 display, one rotating ring, a haptic motor, a microphone and BLE to an iPhone app. It snaps onto the back of the phone like a MagSafe accessory, or comes off and stands in for the phone at the gym, the library or on a walk.

nRF52840 · Zephyr / nRF Connect SDK · LVGL · BLE · MCUboot OTA · SwiftUI · Fusion 360 API · KiCad · JLCPCB


Poko prototype in hand, home screen on Voice Memos   The V1B prototype running Pomodoro, the workout logger, voice memos, Settings and Now Playing

Left: the V1B prototype in hand, home ring on Voice Memos. Right: Pomodoro → workout logging → recording and browsing memos → Now Playing, all from the thumb wheel (2× speed).


Contents


What it does

Use caseOn the deviceOn the phone
⏱Pomodoro focus timerRing sets the time, haptic ticks while turning, glanceable progress ring, silent vibration at the endnone
🏋️Workout trackerToday's exercises, the weight prefilled from last time with plates per side, rest timer, every set saved to flashRoutines are edited in the app and synced
🎙Voice memosHold to record from any screen; ADPCM to on-board flash; works offlinePulled over BLE, transcribed, titled and routed to Reminders, groceries or Calendar
🎵Now Playing (extra)Play/pause/skip and 16-step volume over Apple Media Servicenone
⌨️Desk keyboard (extra)USB/BLE HID: ring as a scroll wheel, voice-to-typingTranscription

What it won't do: show notifications, run feeds, or ask you to scroll. One hand, eyes-free, every action confirmed by vibration.


Requirements I've locked

These are the constraints every hardware and firmware decision is checked against. Full reasoning is in SPEC.md and the part-by-part tracker docs/hardware/LOCK.md.

Product

RequirementTarget
Form factorMagSafe-style accessory, 60 × 90 mm outline, half-round top
Thickness8–9 mm for production (the printed prototype is 18.8 mm; this is the hardest constraint)
InteractionOne hand, eyes-free. Turn moves focus, click commits; turning never silently changes a value
Navigation depthHome → app → one detail level, max. Apps live at fixed clock positions on the home ring
BatteryLasts a normal day; ~0.5 mA sleep-floor target
OfflineDevice works without the phone; the phone does the heavy lifting (transcription, sync)
ManufacturingEvery part sourceable at ~100 units, JLC-assemblable, no injection mold for the first run
Prototyping ruleInternals must be printable (PLA/TPU) or stock commodity parts; dimensions tunable by reprint
Access ruleEvery prototype breaks out spare GPIOs, 3V3/GND and an outside-reachable reset

Hardware decisions

SubsystemDecisionWhy
MCUnRF52840: XIAO Sense on a carrier board for the first batch, Raytac MDBT50Q module for productionBLE + battery life over the ESP32-S3 used in v0; the module is ~1.5–3 mm thinner and ~$6 cheaper than soldering down a dev board
Display1.28" round GC9A01 TFT, 240×240, 4-wire SPI, bare 16-pin FPC panelRound AMOLED was RFQ-only with ~1,000 MOQ; TFT has transparent low-volume pricing. Cost: the backlight dominates power, so it gets a discrete constant-current sink with PWM
InputRotating ring + mechanical select, AS5600 magnetic angle sensor on-axisEC11 encoders are too thick for 8 mm. Optical, magnetic strip, inductive PCB coil and capacitive were weighed, and the press-sensing options were tested on rigs (see Hardware)
HapticsLRA + DRV2605L; detents simulated in softwareOne actuator gives detents, clicks and alerts with no mechanical detent to wear out or add thickness
Power500 mAh 303450 LiPo (3.0 mm thick), single-cell linear chargerChosen to protect the thickness budget; battery life comes from backlight PWM and a low sleep floor
Storage16 MB QSPI NOR flash on the production board (memos + OTA slot), no SD cardAbout 31 minutes of memos alongside a full OTA image
FirmwareZephyr / nRF Connect SDKReal power management, MCUboot signed OTA, BLE stack. Arduino and CircuitPython were used only for bring-up
EnclosureMachined shell (quote pending) with 3D-printed internalsSmall batch; no mold until demand is proven

System architecture

mermaid
flowchart LR
    subgraph Device["Poko (nRF52840, Zephyr)"]
        Ring["Ring<br/>AS5600 / EC11"] --> Input["Input + detent engine"]
        Btn["Select button"] --> Input
        IMU["6-axis IMU"] --> Pickup["Pickup-to-wake<br/>auto-rotate"]
        Mic["PDM mic"] --> Rec["Recorder<br/>ADPCM"]
        Input --> Shell["App shell<br/>home ring + apps"]
        Pickup --> Shell
        Shell --> UI["LVGL UI"] --> LCD["GC9A01 240×240"]
        Shell --> Haptic["Haptic patterns"] --> LRA["DRV2605L + LRA"]
        Rec --> Flash["Flash<br/>memo store"]
        Shell --> BLE["BLE<br/>GATT · AMS · HID · SMP"]
        Flash --> BLE
        OTA["MCUboot<br/>signed OTA"] -.-> Flash
    end

    subgraph Phone["iPhone companion (SwiftUI)"]
        Sync["Memo sync"] --> STT["On-device<br/>transcription"]
        STT --> Route["Voice-action router"]
        Route --> Rem["Reminders /<br/>groceries"]
        Route --> Cal["Google Calendar"]
        Routines["Workout routines"]
    end

    BLE <--> Sync
    BLE <--> Routines

Hardware

Prototype progression

StageWhatStatus
Breadboard bring-upXIAO nRF52840 Sense + round GC9A01 module + EC11 encoder (detent removed, shaft cut down) + ERM motor. CircuitPython first, then ZephyrDone (Sept 2026)
Enclosure V1BTwo-part printed shell, 33 mm thumb wheel, display retainer, VHB-mounted XIAO, magnet in the back cover, support-free print orientations. 18.8 mm thickPrinted, carried daily to the gym and library
Enclosure V2 (inset)Parametric Fusion 360 model driven from Python (cad/enclosure_v2_inset.py): 8 mm stack, datum-based tolerance stack, pairwise interference checksModelled
Knob and ring test rigsPrinted rigs + an ESP32-S3 logger streaming AS5600 angle/AGC/magnitude at 100 Hz to a Web Serial visualizerBuilt and tested, see below
XIAO carrier PCBChin board carrying the display FPC, AS5600, DRV2605L/LRA, backlight sink, select-switch footprintsNext: floorplan → schematic → JLC order

V1B opened: cell, wiring, magnet in the back cover

Breadboard bring-up

Protoboard for the first enclosure

EC11 opened to remove the detent spring

Cutting the encoder shaft down

Ring input: what the rigs showed

The ring has to feel premium (the iPod click wheel is the reference) inside an 8 mm stack, so I built rigs and measured before committing:

  • Friction roller → AS5600: worked, but felt overcomplicated and thin. Set aside.
  • Whole-knob press detected from magnet field strength (AS5600 AGC): at a ~1 mm gap, rest AGC was 68–76 and a centre press dropped it to 32–37. A detector ("AGC drops ≥ 25 below the 3 s peak, held 150 ms, rotation < 4°") replayed 3/3 centre presses, 3/3 edge presses and 0 false triggers on turns.
  • Trackpad-style ring (≈0.05 mm travel, printed cantilever springs, 45° flare retention): the thumb's grip while only rotating (AGC 24–35) overlapped edge presses (25–29). One sensor couldn't separate them reliably.
  • Decision: AS5600 on-axis for rotation + a thin mechanical tact switch for select, with three switch footprints and spare I2C/GPIO on the carrier so the mechanism can change without a board respin.

Scripts: cad/as5600_knob_rig.py, cad/ring_rig.py, firmware/tools/as5600_rig/ (logger firmware + visualizer).

Electrical design notes

  • Backlight sink: AO3400A + TLV9001 constant-current loop, 2.2 Ω sense, PWM-derived reference, op-amp powered from a GPIO so it draws nothing in sleep, gate pull-down for the unpowered state.
  • Charger swap check: MCP73831 → TP4054. The check caught that the MCP73831's STAT pin drives ~4.6 V into a 3.0 V GPIO, and that the TP4054 PROG formula changes above 150 mA. Details in docs/hardware/LOCK.md.
  • Pin budget: all 11 XIAO pads allocated (SPI display, shared I2C for AS5600 + DRV2605L, select, backlight PWM/enable), one spare, with solder jumpers for optional lines (docs/hardware/pins.md).
  • Supply chain: JLC quoted the Raytac module at $15.69 vs. its own $7.73 list price and $6.50–7.13 at TME. At 100 units that gap is ~$840, so volume orders point to sourcing it elsewhere. Assembly-tier costs are in docs/hardware/jlc-cost.md.

Firmware

A Zephyr application split into a small OS layer and apps (source in a private repo; happy to walk through it):

  • os/: input (EC11 Gray-code decoder, AS5600 driver), detent and haptic engine, LVGL screen and widgets, power states (dim, sleep, pickup-to-wake from the IMU), battery ADC, PDM capture with ADPCM, NVS-backed memo store, BLE link (custom GATT, Apple Media Service, HID keyboard), USB HID, MCUboot OTA, crash capture.
  • apps/: Pomodoro, Gym (with synced routines), Voice memos, Now Playing, Desk keyboard, Settings.
  • Tooling: a bench build that measures frame time, a power-test app for current measurements, a memo-pull script, and a desktop LVGL simulator.

Each feature was specced as a numbered brief with acceptance criteria and an outcome write-up.


iPhone companion app

SwiftUI app (XcodeGen project, source in the same private repo): memo sync over BLE, on-device transcription, automatic titles, a voice-action router (to-dos, groceries, Google Calendar via OAuth PKCE), and workout routine editing. A routing eval harness scores the router against synthetic and real memo sets.


Measured results

WhatResultHow
Current, screen off / on / recording37.5 / 42.6 / 44.0 mAMultimeter in series with the battery, USB unplugged (power.md)
Backlight share of screen-on draw33.5 mA (~79%)Voltage across the module's 8.2 Ω backlight resistor. This is why the production board gets a PWM current sink
OTA over BLE561 KB in ~34 s, 42.5 s swapMCUboot. A battery pull mid-swap recovered, and all 105 stored memos kept matching CRCs (ota-checks.md)
Boot time53 s → 4.4 sTraced to a per-key NVS walk at boot, replaced with a single pass
Voice-to-text, release to typed5.9–6.3 s → ~3.0–3.7 sTiming marks on device and phone, 5–7 s utterances
Voice-action routing accuracy47/54 → 52/54 on real memosEval harness, Apple on-device model
Album-art decode65 ms avg / 167 ms maxMeasured, then cut: it made the UI lag

Design direction

Orbit UI inspiration

Inspiration: concentric orbits on black, like the iOS Solar System lock screen. They map naturally onto a round display and a ring you turn.

  • Black background, thin white line art, one accent colour
  • Thick arc progress rings for timers
  • Apps sit at fixed clock positions; only the focus moves, so you can go straight to one ("gym is at 2")
  • Cheap pixels: small objects move over static, rotationally symmetric backgrounds, with no full-screen redraws
  • Every turn and click confirmed by haptics, so it works without looking

Where it came from: Pokodoro (v0)

Poko is the second version of a device I started in 2024: Pokodoro, a portable Pomodoro timer that tells you a session is over with a vibration instead of a beep, so it works in a library or an office. I sketched it, prototyped it on protoboard, laid out a 4-layer board in KiCad, had it fabricated, hand-soldered it and designed the enclosure.


Assembled v0

Custom PCB (KiCad 3D)

Inside the enclosure

UI sketches

Enclosure sketches

Protoboard MVP

Board: ESP32-S3-WROOM-1, USB-C with a TVS ESD array, MCP73831 LiPo charger, Schottky OR-ing of USB and battery into a MIC5219 LDO, transistor-driven vibration motor and buzzer, SPI OLED header, two user buttons plus boot/reset. KiCad sources, Gerbers, BOM and placement files are in pokodoro/.

Schematic and copper layout
Pokodoro schematic

Pokodoro PCB top copper

What changed in Poko: the MCU went to nRF52840 for BLE and battery life, a round colour display replaced the 128×64 OLED, a haptic ring replaced the buttons, the firmware moved to Zephyr with OTA and a phone app, and the scope grew from a timer into something to carry every day.


Status and roadmap

Current goal: a lendable batch of 7 units, polished enough to hand to 3–5 people for two weeks of real use (Pomodoro, workouts, memos).

  • Firmware for all core apps running on the prototype, OTA proven
  • iPhone app: sync, transcription, routing, routines
  • Power measured, battery and backlight strategy set
  • Display, haptics and USB parts locked; samples ordered
  • Ring sensing decided after rig testing
  • Mechanical select-switch jig (force vs. grip)
  • XIAO carrier PCB: floorplan → schematic → layout → JLC assembly
  • Enclosure V2 ring area rework, machining quote for 7
  • Batch-1 build, lend, write up feedback
  • Then: Raytac custom board, 100-unit quotes, preorder

Repo map

text
SPEC.md                  concept, requirements, early BOM and power budget
docs/hardware/           part lock tracker, pins, power, haptics, OTA, tolerance stack, JLC cost
docs/images/             photos, demo GIF, KiCad exports
cad/                     parametric Fusion 360 scripts: enclosure, floorplan, test rigs, 3MF export
firmware/tools/as5600_rig/  ring-rig logger (ESP32-S3) + Web Serial visualizer and menu tests
pokodoro/                the v0 KiCad project (schematic, PCB, Gerbers, BOM)

Firmware (Zephyr, C) and the iPhone app (SwiftUI) are in a private repo and available on request.


How this was built

I'm the sole developer. I set the requirements, made the hardware and part decisions, sourced parts and talked to suppliers, and built, printed and bench-tested every prototype and rig. Pokodoro (v0) I designed end to end myself. For Poko, most of the firmware, iOS and CAD-script code was written with AI coding agents (Claude Code) working from feature briefs. I wrote each brief's requirements, tested the results on real hardware, and accepted or rejected them.

Parts

52
QtyValueFootprintReferences
70.1uFPokodoro_Footprints:CAP_CL10_SAMC3, C7, C8, C12, C13, C14, C15
610KPokodoro_Footprints:RC0603N_YAGR1, R5, R6, R7, R11, R12
610uFPokodoro_Footprints:CAP_CL10_SAMC2, C4, C5, C6, C9, C11
4MountingHoleMountingHole:MountingHole_3.2mm_M3H1, H2, H3, H4
31N5819HW-7-FPokodoro_Footprints:1N5819HW-7-F_DIOU2, U4, U6
21KPokodoro_Footprints:RC0603N_YAGR8, R9
2330Pokodoro_Footprints:RC0603N_YAGR4, R10
25K1Pokodoro_Footprints:RC0603N_YAGR2, R3
2B3F-4050Pokodoro_Footprints:B3F-4050SW3, SW4
2BC817Pokodoro_Footprints:BC817-40Q1, Q2
2PTS810SJG250SMTRLFSPokodoro_Footprints:PTS810SW1, SW2
2S2B-PH-K-SLFSNPokodoro_Footprints:S2B-PH-K-SJ2, J4
2WL-SMCW_0603Pokodoro_Footprints:WL-SMCW_0603D2, D3
11uFPokodoro_Footprints:CAP_CL10_SAMC1
12171790001Pokodoro_Footprints:USBC_MOLEX_2171790001J1
1470pFPokodoro_Footprints:G-188_MURC10
1CEM-120342Pokodoro_Footprints:CEM-120342U7
1DT1042-04SO-7Pokodoro_Footprints:DT1042-04SOD1
1EG1224Pokodoro_Footprints:EG1224S3
1ESP32-S3-WROOM-1-N4Pokodoro_Footprints:ESP32-S3-WROOM-1-N4U1
1MCP73831T-2ACI/OTPokodoro_Footprints:SOT-23-5_MC_MCHU3
1MIC5219-3.3YM5-TRPokodoro_Footprints:SOT-23-5_M5_MCHU5
1S7B-XH-A_LF__SN_Pokodoro_Footprints:S7B-XH-A-1J3

Similar boards

  • 2 layers155 × 93 mmMotorized faders, the printed circuit board in 3D

    Motorized faders

    Ilosariph/motorized-faders

    RP2040 board (Pico-clone with RTL8720DN WiFi — GP4/GP5 not exposed) + TB6612FNG motor drivers + Alps motorized faders.

    66 parts
  • 4 layers100 × 100 mmKvm switch, the printed circuit board in 3D

    Kvm switch

    Rithvik-Vadlamani/kvm-switch

    Four-layer HDMI/USB KVM design with STM32 firmware, supply supervision, and verification evidence

    170 parts
  • 2 layers102 × 45 mmChess clock pcb, the printed circuit board in 3D

    Chess clock pcb

    vekkuli/chess_clock

    This repo contains design and fabrication files for my DIY chess clock project. The main components in the design are

    16 partsMIT
  • 2 layers138.6 × 120 mmHexiLux v1, the printed circuit board in 3D

    HexiLux v1

    ZeusyBoy98/HexiLux

    A custom open-source smart lighting solution, using tiling hexagonal panels. Featuring music sync and home assistant compatibility.

    38 partsAGPL-3.0
  • 2 layers33.5 × 15 mmPanel, the printed circuit board in 3D

    Panel

    marqs85/ossc_pro_hw

    OSSC Pro HW files

    5 parts31CERN-OHL-P-2.0
  • 2 layers42 × 85 mmKasa remote, the printed circuit board in 3D

    Kasa remote

    Paumanok/kasa-remote

    An ESP32 based remote control device for manipulating and monitoring TPLink Kasa devices.

    47 parts
  • 4 layers52 × 25.4 mmStm32-kicad 1, the printed circuit board in 3D

    Stm32-kicad 1

    Shourov-Paul/stm32-Every

    49 parts1
  • 6 layers45.7 × 42.2 mmDev board, the printed circuit board in 3D

    Dev board

    ericpearson1313/tt_pump_out_chip

    60 Hz Liquid‑Pump Controller ASIC with Current‑Drop Shutoff

    40 partsApache-2.0

Questions

How big is the Pokodoro PCB?

It measures 55 × 85 mm and has 4 copper layers, 1.6 mm thick.

What parts does the Pokodoro use?

52 parts, built around the ESP32-S3-WROOM-1-N4, 1N5819HW-7-F-01, MCP73831T-2ACI/OT-HXY and MIC5219-3.3YM5-TR. 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 Pokodoro KiCad files?

From the justinjchae/poko repository on GitHub, at the commit this page was made from: the board is pokodoro/Pokodoro/Pokodoro.kicad_pcb and its schematic pokodoro/Pokodoro/Pokodoro.kicad_sch. PCBKit opens the board in the browser, with nothing to install.

Can I use the Pokodoro design in my own project?

Its repository states no licence, so its author keeps all rights: ask justinjchae before reusing the design.