Skip to the content
PCBKitNew board
2 layersEphemerkey, the printed circuit board in 3D

The consumer half of the ephemerkey system, and the second PCB in this repo (alongside hardware/ephemerkey/, sharing the same scripts/kschgen.py engine, Makefile, and lib tables — the multi-project layout used by…

Copper layers
2
Thickness
1.6 mm
Parts
70
Nets
238
Pads
287
Tracks, vias
0, 0
Routed
Not yet
KiCad
KiCad 10.0 (file 20260206)
Created
21 Jun 2026
Updated
21 Jul 2026

Overview

Ephemerkey is an open-source printed circuit board by ephemerkey, from the ephemerkey/ephemerkey repository on GitHub. It is a 2-layer board with 70 parts on 238 nets.

It is built around the STM32U083KCU6, MAX-M10S-00B and TPS63900DSKR, with the MCP73831T-2ACI/OT-HXY, USBLC6-2SC6 and 1N4148W among its other parts. Its parts include 24 capacitors, 16 resistors, 5 ICs, 5 diodes and 5 connectors. It belongs with the STM32 boards of this library.

Main components

12

README

hardware/lock/README.md

lock — companion TOTP lock board

The consumer half of the ephemerkey system, and the second PCB in this repo (alongside hardware/ephemerkey/, sharing the same scripts/kschgen.py engine, Makefile, and lib tables — the multi-project layout used by reefvolt-sensorbuddy). ephemerkey generates an authenticated unlock; this board verifies it and drives the actuator.

text
make gen-lock      # regenerate the schematic from scripts/lock.schgen.py (placed, not wired)
make check-lock    # component/footprint/dup-ref/ERC tally
make render-lock   # per-sheet PNGs

The schematic is generated from a manifest (scripts/lock.schgen.py), like ephemerkey. Components are placed, not wired — each sheet carries an on-canvas note that is the wiring spec for the eeschema phase. Regenerate before wiring (regen reassigns UUIDs).

What it does

  1. Sleeps at ~0.1 µA (ATtiny1616 power-down). Coil de-energized, 12 V rail off.
  2. ephemerkey starts an I2C transaction; the first START wakes the MCU (wake-on-I2C).
  3. Authenticated challenge-response over I2C proves the request is genuine (HMAC-SHA1, shared secret in flash — see Firmware plan).
  4. On success: enable the boost, run the peak-and-hold solenoid profile, then drop the rail and go back to sleep.

Everything (MCU + boost + driver) is powered from ephemerkey over the I2C connector (J2.2 = VSYS, ephemerkey's ~3.0–4.7 V battery/system rail). The lock carries no local battery (J1 removed). See the current caveat under the interface section — a 12 V solenoid pull-in draws several amps through that cable.

Architecture

text
 VSYS from ephemerkey ──┬─────────────────────────────► U1 ATtiny1616 VCC   (direct, NO LDO; ~0.1µA sleep)
   (J2.2, I2C connector) │                            │  PA5 SOL_PWM ─┐   PB0/PB1 I2C ── J2 (target; key=master)
                           │                            │  PA6 SOL_BOOST_EN  wake-on-I2C: SCL START (no wake line)
                           │   SOL_BOOST_EN ──► EN       │  PA0 UPDI ─────── J4 (program)
                           └─► U2 MT3608 boost ──► +12V (VSOL) ─┬─ C5 220µF + C6 22µF  (reservoir)
                               L1 10µH · D2 SS34               │
                               FB: R3 200k / R4 10k ≈ 12.6V    ▼
                                                          ┌─ SOLENOID ─┐  (J3 JST-PH)
                                                  D3 SS34 │            │
                                                  flyback └─────┬──────┘
                                                                │ SOL_DRV (drain)
                                                  SOL_PWM ─[R5 100R]─┤ Q1 AO3400A (low-side)
                                                              [R6 100k]│
                                                                    GND┘

Sheets: MCU (mcu.kicad_sch) · PWR (psu.kicad_sch) · DRV (drv.kicad_sch).

BOM (all JLCPCB / LCSC)

RefPartValueLCSCJLCFootprint
U1ATtiny1616tinyAVR-1, runs 1.8–5.5 VC507118extQFN-20 3×3 0.4 mm
U2MT3608boost, ~2 A switchC84817extSOT-23-6
Q1,Q2,Q4,Q5AO3400AN-FET (solenoid LS, FB switch, servo logic, interlock)C20917BasicSOT-23
Q3AO3401AP-FET (servo high-side load switch)C15127BasicSOT-23
D2,D3SS34Schottky 40 V/3 AC8678BasicSMA
L1FNR6045S100MT10 µH power inductorC168076ext6×6 mm
C5,C8220 µF 25 Vreservoir / VSERVO bulk (electrolytic)C4747974extØ6.3×7.7
C4,C622 µF 25 Vboost out / VSOL bypassC12891Basic1206
C310 µF 25 Vboost inC15850Basic0805
C1,C2,C7,C9,C10100 nF / 1 µF / 1 nFdecouple / hall debounce / snubber(DNP)C1525/C29266Basic0402
R3200 kFB topC25764Basic0402
R422 kFB base → 6 V defaultC25768Basic0402
R1720 kFB switch → 12 V (Q2)C25765Basic0402
R2,R6,R18,R19,R20100 kpulldowns / P-FET gate pull-upC25741Basic0402
R16,R21,R22,R23,R2510 kservo pulldowns/series, hall pull-upsC25744Basic0402
R5100 Ωgate seriesC106232ext*0402
R1,R15,R241 kstatus LED / servo signal seriesC11702Basic0402
D1LED greenstatus (driven by PC3)C160479ext0402
J3JST-PH 2-pinsolenoidC173752extPH 2.0
J2JST-PH 4-pin RA (S4B-PH-K)I2C link (right-angle)C157926extPH 2.0 RA
J4pin header 1×3UPDI program——1×3
J5,J8pin header 1×3servo outputs (S/V+/GND), DNP unless servo build——1×3
R13,R140 ΩVSERVO source select (fit one)C17168Basic0402
J6,J7JST-PH 3-pin RA (S3B-PH-K)door / bolt hall sensorsC157929extPH 2.0 RA

* jlcsearch under-reports Basic flags; verify in JLCPCB's BOM tool at order time.

Every footprint is a KiCad-bundled package, so all parts carry 3D models — the board is clearance-checkable in KiCad's 3D viewer once it's laid out.

Boost + reservoir sizing (read before ordering)

12 V × up to 1 A ≈ 12 W ≈ ~3.8 A from the cell — heavy. The design splits it:

  • The MT3608 is sized for the hold current (~0.3 A @ 12 V ≈ within its ~0.5 A @ 12 V capability) plus recharging the reservoir between actuations.
  • The reservoir (C5) supplies the brief pull-in surge. Sizing: ΔV ≈ I_pull · t_pull / C. A 1 A, 30 ms pull-in pulls 30 mC; with 220 µF that sags the rail a lot, so 220 µF is the baseline for ≤ ~500 mA / short pull-ins. For a true sustained 1 A @ 12 V pull-in, either grow C5 into the multi-thousand-µF range or swap the MT3608 for a TPS61088-class boost that can source the full 12 W directly. Pin this down against the actual solenoid's pull-in current × time and re-fire rate.

Set Vout exactly with the FB divider: Vout = 0.6·(1 + R3/R4). 200 k/10 k ≈ 12.6 V; trim R3 toward 12.0 V if desired.

Servo variant + firmware actuator control

The board drives a 12 V solenoid or a 6 V RC servo. Because the boost voltage and the servo power are both firmware-controlled, one fully-populated board can carry both and switch between them (one actuator active at a time — a single boost = a single voltage). Firmware drives three lines:

  • BOOST_VSEL (PA1) — picks the rail: low/default 6 V (servo-safe), high 12 V (solenoid). NMOS Q2 switches R17 across the FB divider.
  • SERVO_PWR_EN (PA2) — high-side P-FET (Q3) load switch on VSERVO. Servo power comes on only when firmware asserts it and the boost is at 6 V: a hardware interlock (Q5, gated by BOOST_VSEL) forces servo power OFF at 12 V regardless of firmware, so a 12 V solenoid pulse can never reach a 6 V servo.
  • SERVO_SIG (PB2 / TCA0) — 50 Hz position pulse, via R15 (1 k) + R16 (10 k idle pulldown) so the servo can't twitch at boot.
ModeBOOST_VSELSERVO_PWR_ENActuator
Solenoid12 Voff (interlock-forced)Q1/D3/J3 peak-and-hold
Servo, 6 V6 VonJ5 servo, VSERVO ← VSOL (R13, populated)
Servo, directboost offonJ5 servo, VSERVO ← VSYS (R14, DNP alt)
  • J5 / J8 — two 3-pin RC-servo outputs (1=SIG, 2=V+ (VSERVO), 3=GND), e.g. a dual-latch lock. SERVO_SIG (PB2/TCA0) and SERVO_SIG2 (PB4, software-timed); both share the VSERVO rail and the load-switch/interlock. MT3608 ~1 A @ 6 V — drive them sequentially, or upsize C5/C8 for simultaneous travel.
  • VSERVO source — fit exactly one 0 Ω: R13 = VSOL (6 V from the boost — the populated default) or R14 = VSYS (servo direct off the connector rail, ~3–4.7 V). Never both. C8 (220 µF) buffers servo inrush.
  • SERVO_SIG is VSYS-level logic (~3–4.7 V), accepted by typical servos, GND-referenced.

Authenticated digital interface + Firmware plan

The ephemerkey↔lock link is an authenticated I2C bus — ephemerkey is the master, this lock is the target — on a right-angle 4-pin JST-PH (S4B-PH-K, a standard 4-pin I2C cable, straight-through):

Pinlock (this board, target)ephemerkey (key, master)
1GND (+ actuation return)GND
2VCC ← powers the lock (VSYS in)VSYS (battery/system rail out)
3SDA ↔ PB1LOCK_SDA (PA6, I2C3)
4SCL → PB0 (clock + wake)LOCK_SCL (PA7, I2C3)

The lock has no local battery — its VCC (and the boost/actuator draw) comes in on J2.2 from ephemerkey's VSYS rail. Current caveat: a 12 V solenoid pull-in is ~3–4 A from VSYS, beyond a JST-PH contact (~2 A) and ephemerkey's load-share path — favor the 6 V servo / low-duty buffered by C5/C8, or run a heavier dedicated feed. The I2C pull-ups live on ephemerkey at +3V3 (do not pull the bus to VSYS — the STM32 pins are 3.3 V-domain). The lock (running at VSYS) reads the 3.3 V idle level fine across the discharge curve. The lock is the target at addr 0x60 with no separate wake line — it wakes from power-down on the first I2C START (a pin-change interrupt on SCL), so we don't mix a discrete "button"-style input with the bus.

Authentication is firmware HMAC — no secure element. A pairing secret lives in flash on both boards (separate from ephemerkey's TOTP secret).

I2C register/command map (lock = target @ 0x60). The master reads status/nonce and writes authenticated commands:

RegAccessContents
0x00 STATUSreadbit0 DOOR_CLOSED · bit1 BOLT_LOCKED · bit2 ACTUATOR (0=solenoid,1=servo) · bit3 RAIL_12V · bit4 BUSY · bit5 LAST_CMD_OK
0x01 NONCEreada fresh 16-byte random nonce; reading arms it (consumed by the next COMMAND)
0x10 COMMANDwrite[cmd] ‖ HMAC-SHA1(secret, nonce ‖ cmd ‖ code) — cmd 0x01=UNLOCK, 0x02=LOCK

Probe lid/door state (unauthenticated read — status only): the I2C START wakes the lock; the master reads STATUS. DOOR_CLOSED / BOLT_LOCKED report the J6/J7 hall sensors; ACTUATOR tells the key whether a servo is fitted.

Lock / unlock (authenticated challenge-response, anti-replay):

  1. Master reads NONCE (0x01).
  2. Master writes COMMAND = cmd ‖ HMAC-SHA1(secret, nonce ‖ cmd ‖ code).
  3. Lock recomputes, constant-time compares against the armed nonce (then clears it → replay-proof), and only then drives the actuator:
    • UNLOCK (0x01): solenoid → peak-and-hold release; servo → unlock angle.
    • LOCK (0x02): servo → lock angle (a servo holds position). For a momentary solenoid, LOCK is a no-op — it re-latches mechanically (fail-secure).
  4. Master may re-read STATUS to confirm BOLT_LOCKED flipped.

code may be the ephemerkey TOTP digits, binding the action to a fresh in-fence code. Optionally fold a monotonic counter (EEPROM) into the HMAC so a weak RNG can't be exploited.

Lock firmware (ATtiny1616 — megaTinyCore or bare AVR):

  • State machine: SLEEP(power-down) → (I2C START wakes it) → service TWI as target → SLEEP; a verified COMMAND branches to ACTUATE. In SLEEP: TWI/boost off, R6 holds Q1 off, R2 holds boost off; SCL (PB0) pin-change wakes it (wake-on-I2C).
  • STATUS read → pulse HALL_PWR (PA4) high, settle ~1 ms, sample HALL_DOOR (PA7) + HALL_BOLT (PB3), drop HALL_PWR, return the bits (~0 µA between reads).
  • ACTUATE:
    • Solenoid — the peak-and-hold economizer: SOL_BOOST_EN=1 → wait VSOL → SOL_PWM 100 % pull-in (~20–50 ms) → reduce duty for hold → release. PWM = TCB0 (PA5).
    • Servo — BOOST_VSEL=6 V, SERVO_PWR_EN=on, drive SERVO_SIG (PB2/TCA0) to the lock/unlock angle, wait for travel, then cut servo power. The hardware interlock keeps servo power off whenever BOOST_VSEL=12 V.
  • HMAC-SHA1 (reuse smalltotp, portable C → compiles for AVR) fits in 16 KB/2 KB. Secret in USERROW/flash; disable UPDI / set lockbits in production.

Key firmware (ephemerkey STM32U083 — add to its superloop):

  • Probe the lid: wake the lock (I2C START) and read STATUS — surface door open/closed + bolt locked/unlocked (e.g. on the OLED); no auth needed.
  • Lock / unlock: on a request (button + in-fence + fresh, valid TOTP), read NONCE, compute HMAC-SHA1(secret, nonce ‖ cmd ‖ code), write COMMAND with cmd = UNLOCK or LOCK. (Send a dummy/wake byte first and retry — the just-woken target NACKs the first.) Re-read STATUS to confirm.
  • Use the same HMAC-SHA1 as the lock — smalltotp ships it, so both reuse it.
  • The pairing secret is provisioned over USB during pairing.

Programming

J4 UPDI header: 1 = UPDI (PA0), 2 = VCC (BAT), 3 = GND. One-wire UPDI via pymcuprog, a serial-UPDI adapter, megaTinyCore, or Atmel-ICE/PICkit.

Bring-up checklist

  1. Power from a current-limited 1S cell; confirm the MCU enumerates over UPDI and sleeps at ~µA with the I2C bus idle.
  2. Pulse SOL_BOOST_EN; scope VSOL → should reach ~12.6 V; trim R3 if needed.
  3. With a solenoid fitted, tune the pull-in time and hold duty; add the R9/C7 snubber (DNP) only if drain ringing is high.
  4. Bring up the I2C challenge-response against ephemerkey (confirm wake-on-I2C + the dummy-then-retry handshake); verify a wrong/late response never actuates.

Parts

70
QtyValueFootprintReferences
11100nFCapacitor_SMD:C_0402_1005MetricC3, C4, C5, C8, C9, C17, C20, C21, C22, C23, C24
910uFCapacitor_SMD:C_0805_2012MetricC6, C10, C11, C12, C13, C14, C15, C16, C19
54.7kResistor_SMD:R_0402_1005MetricR6, R9, R10, R11, R12
45.1kResistor_SMD:R_0402_1005MetricR4, R5, R15, R16
31kResistor_SMD:R_0402_1005MetricR2, R3, R8
2100kResistor_SMD:R_0402_1005MetricR7, R14
212pFCapacitor_SMD:C_0402_1005MetricC1, C2
10RResistor_SMD:R_0402_1005MetricRm1
11.8pFCapacitor_SMD:C_0402_1005MetricCm2
1100RResistor_SMD:R_0402_1005MetricR13
110kResistor_SMD:R_0402_1005MetricR1
110pFCapacitor_SMD:C_0402_1005MetricC18
11N4148WDiode_SMD:D_SOD-123D5
11uFCapacitor_SMD:C_0402_1005MetricC7
12.2uHInductor_SMD:L_Changjiang_FNR3015SL1
132.768kHzCrystal:Crystal_SMD_3215-2Pin_3.2x1.5mmY1
1AO3400APackage_TO_SOT_SMD:SOT-23Q2
1AO3401APackage_TO_SOT_SMD:SOT-23Q1
1B5819WDiode_SMD:D_SOD-123D3
1BAT 1S Li-ionConnector_JST:JST_PH_S2B-PH-K_1x02_P2.00mm_HorizontalJ4
1CHGLED_SMD:LED_0402_1005MetricD4
1DNPCapacitor_SMD:C_0402_1005MetricCm3
1FB 600R@100MHzInductor_SMD:L_0402_1005MetricL2
1GRNLED_SMD:LED_0402_1005MetricD1
1LIS3DHTRPackage_LGA:LGA-16_3x3mm_P0.5mmU5
1LOCK IF (I2C JST-PH)Connector_JST:JST_PH_S4B-PH-K_1x04_P2.00mm_HorizontalJ2
1MAX-M10S-00Bephemerkey:ublox_MAXMD1
1MCP73831-2-OTPackage_TO_SOT_SMD:SOT-23-5U4
1MLT-8530Buzzer_Beeper:MagneticBuzzer_CUI_CMT-8504-100-SMTLS1
1OLED 128x32 I2CConnector_PinSocket_2.54mm:PinSocket_1x04_P2.54mm_VerticalDS1
1REDLED_SMD:LED_0402_1005MetricD2
1STM32U083KCU6ephemerkey:UFQFPN-32-1EP_5x5mm_P0.5mm_EP3.5x3.5mmU1
1SWD TC2030-NLConnector:Tag-Connect_TC2030-IDC-NL_2x03_P1.27mm_VerticalJ1
1TPS63900DSKRPackage_SON:WSON-10-1EP_2.5x2.5mm_P0.5mm_EP1.2x2mmU2
1USB-CConnector_USB:USB_C_Receptacle_GCT_USB4105-xx-A_16P_TopMnt_HorizontalJ3
1USB-C (vert)Connector_USB:USB_C_Receptacle_G-Switch_GT-USB-7051xJ5
1USBLC6-2SC6Package_TO_SOT_SMD:SOT-23-6U3
1USER1ephemerkey:SW_Push_1P1T_XKB_TS-1187ASW1
1USER2ephemerkey:SW_Push_1P1T_XKB_TS-1187ASW2
1USER3/DFUephemerkey:SW_Push_1P1T_XKB_TS-1187ASW3
1W3011ARF_Antenna:Pulse_W3011AE1

Questions

What parts does the Ephemerkey use?

70 parts, built around the STM32U083KCU6, MAX-M10S-00B, TPS63900DSKR and MCP73831T-2ACI/OT-HXY. 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 Ephemerkey KiCad files?

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

Can I use the Ephemerkey design in my own project?

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

More from ephemerkey/ephemerkey

1
  • 2 layers64 × 23 mmLock, the printed circuit board in 3D

    Lock

    ephemerkey/ephemerkey

    The consumer half of the ephemerkey system, and the second PCB in this repo (alongside hardware/ephemerkey/, sharing the same scripts/kschgen.py engine, Makefile, and lib tables — the multi-project layout used by…

    50 parts

Similar boards

  • 6 layers34 × 40 mmESPWatchS3, the printed circuit board in 3D

    ESPWatchS3

    Ilikemining1/ESPWatchS3

    ESP32-S3 based smartwatch with CrystalFontz 240x240 1.3in LCD.

    126 parts2
  • 2 layers56 × 75 mmSurvivornode, the printed circuit board in 3D

    Survivornode

    aneeshlingala/FirstResponderSystem

    reverie hacks submission

    16 parts
  • 2 layers44 × 72 mmEda, the printed circuit board in 3D

    Eda

    rcyaon/funbbit

    open hardware clone of sony's 1998 dancing headphone pet

    86 parts
  • 8 layers22.3 × 77.5 mmTinker mantis, the printed circuit board in 3D

    Tinker mantis

    Tinkerbug-Robotics/TinkerRocket

    Model rocket flight computer, ground station, iOS app, and simulation

    279 parts1GPL-3.0
  • 10 layers95.3 × 71.4 mmZynq soc board v1, the printed circuit board in 3D

    Zynq soc board v1

    findasifrahman/zynq_soc_board_v1

    449 parts
  • 4 layers75 × 17 mmNref batterypack, the printed circuit board in 3D

    Nref batterypack

    cetola/reform-next-mirror

    The original Open Hardware laptop, reloaded.

    91 parts
  • 4 layers117.5 × 30 mm4reel ee, the printed circuit board in 3D

    4reel ee

    o7-machinehum/4reel

    Stereo machine vision camera for outdoor mobile robotics.

    179 parts34MIT
  • 8 layersFIRM v1.1, the printed circuit board in 3D

    FIRM v1.1

    NCSU-High-Powered-Rocketry-Club/FIRM-KiCad

    Full and open hardware design for FIRM

    108 parts1MIT