OpenPulse¶
Open-source cuffless blood-pressure trend wristband (Hilo/Aktiia-style), wellness use, not a medical device. Repo: EmbeddedEra/OpenPulse (~/Documents/GitHub/OpenPulse). Board hardware/OpenPulse_Band, EE-P-0009-A (ERP pk 260). Reference design: ProtoCentral HealthyPi Move (Protocentral/healthypi-move-hw, -fw, healthypi_move_flutter).
Open¶
- MAX32664: confirm EP land size (ADI 90-100089) and host-accel/raw-PPG mode in the firmware guide
- Library PR EmbeddedEra/KiCad#11 (openpulse-ics) to master: owner review and merge; SOP-008 check "IPN commit on master" closes then
- Generic passives (0201/0402/0603 R and C, 12 BOM lines) get ERP IPNs at BOM time, SOP-008 steps 22-25
- Placement: pcb_src.py for OpenPulse_Band (decide there whether barometer U403 and NFC J203/J204 fit; drop if not)
- ERP IPNs for the 2026-11-01 parts (MAX30001CWV+T, SiT1533, BMP585, TPD1E01B04DPYR, new passives), SOP-008
- Firmware VERIFY: MAX32664C hub lets the host set MAX86141 GPIO CTRL 0001 (ext 32 kHz clock) and stream raw PPG; without it PAT timing falls back to host timestamps
- NFC: pick a flex antenna, then tune C205/C206 (DNP until then)
- Enclosure: two ECG electrode contacts (skin side, top) and a gasket-sealed BMP585 port (no membrane)
Handoff (2026-11-01, chat 6) — start here¶
Read this, then continue. Nothing pushed yet (one push after IPNs: board-scaffold + openpulse-ics).
- Done: ECG (MAX30001, sheet ECG), shared 32 kHz SiT1533 (CLK32K to MAX30001 FCLK, MAX86141 GPIO2, MAX32664 32KIN; Y301 removed), motor = low-side DMG1012T + 1N4001W + R601 10k (owner: "just an N-MOSFET", as Cricket), BMP581, NFC pads J203/J204 + C205/C206 DNP. Board 68c6f83, lib 969b18d. Checks passed after last change: tidy 0, ERC 0, rendered overlaps 0, doc-check pass; motor nets verified in netlist. Netplan section "Rev A additions" + "Haptics revised".
- Next action 1: ERP parts EE-C-0244 DMG1012T-7, 0245 MAX30001CWV, 0246 SiT1533, 0247 TPD1E01B04DPYR CREATED (Angel's go, 2026-11-01). Writing IPNs into symbols (kicad-erp-sync push --only DMG1012T-7,MAX30001CWV,SIT1533AI-H4-DCC-32.768E,TPD1E01B04DPYR --yes in ~/kicad-lib-openpulse-ics with KICAD_LIB_REPO=$PWD) blocked by the permission classifier: Angel runs it with !. Then BMP585 pull/push (after the swap lands), regenerate board, checks, push both branches, republish project page.
- Angel approved 2026-11-01 ("do all"): shared SiT1533 clock replaces Y301; ERP numbers; BMP585 swap.
- Was: ask Angel: OK to replace crystal Y301 (approved chat 4) with the shared SiT1533 clock? MAX30001 + SiT1533 have no LCSC stock (Digi-Key yes) → consigned parts.
- Research results (scouts, unverified against the C-variant guide): hub raw PPG = Set Output Mode 10 00 01; MAX86141 register access through the hub 40 00 <addr> <val> / 41 00 <addr> (UG6806, non-C; ProtoCentral max32664c.c uses the same) — so writing reg 0x10 GPIO CTRL=0001 is plausible but unconfirmed; host-accel input 44 04 01 + 14 04 ... (non-C only). MAX32664 EP land: still no drawing found (sibling MAX32663A uses 21-100264 / 90-100089). NFC: Abracon ANFCA-2515-A02 (25x15 mm, 1.8 uH) → ~150 pF per pin; Murata NFC1AT80A01N7 1.7 uH → ~160 pF; tune on board with a VNA. Barometer: consider BMP585 (gel-filled, water-resistant, Digi-Key 8.8k stock) instead of BMP581 for a sealed band — check its DS before switching. No 1 mm ePTFE vent found yet (Gore PE120205 2 mm ID candidate).
State (2026-10-31, chat 4)¶
- Pushed. OpenPulse branch board-scaffold b071e74 (draft PR EmbeddedEra/OpenPulse#1). Library branch openpulse-ics df5dc36, draft PR https://github.com/EmbeddedEra/KiCad/pull/11.
- Until KiCad#11 merges, build and export with
KICAD_LIB_REPO=~/kicad-lib-openpulse-ics EMBEDDEDERA_DIR=~/kicad-lib-openpulse-ics(README chain: sch_src.py, kicad-tidy-check, ERC, export PDF after tidy, doc-check). - Project page (Artifact) https://claude.ai/artifact/UZktokFtVn2pF2EMNZKEed, built by
tools/project_page/build.py <out>; status.json holds stage/decisions/open; republish after each design change. - Next: placement (pcb_src.py) after the MAX32664 EP check.
Log¶
- 2026-11-01 (BMP585 swap): committed library b82b307 (openpulse-ics), board f3e7d36 (board-scaffold); neither pushed, no ERP access. BMP585 C18184976, JLC stock7009; DS003-02 p45 pin map, p63-65 package, p67 lands. Eight solder lands, L/M9 NC/no PCB land. New STEP only. sch_src netlist matches, tidy124nets/0changed/0overlaps, ERC0, rendered0, PDF doc-check pass; Sensors PDF and footprint visually reviewed. Library kicad-check90projects/0errors/119warnings. Before/after netlist: U403 only (1 SCL,2 SDA,3 GND unchanged,4/7/8 +1V8,5 BARO_INT,6 GND,9 NC,10 removed; value/footprint updated). Bosch second-level gasket proposal still needed for enclosure dimensions; 15bar is storage robustness, not measurement range. Local implementation in Codex; no helpers (route lacked enforced tool confinement required by SOP-025).
- 2026-11-01 (chat 6): barometer BMP581 -> BMP585 (DS003: metal-lid LGA 3.25 mm, 15 bar, water sports, gasket-sealed port, no membrane; same 0x46; LCSC ~7k). Swap done by codex-worker: lib b82b307 (BMP585, LCSC C18184976, footprint per DS003 p45/pp63-65/p67), board f3e7d36; reviewed: pins match Table 26, regenerated here tidy 0 / ERC 0 / rendered 0 / doc-check pass. Regeneration leaves wire-uuid-only churn in Power.kicad_sch (discard it with git checkout). Remaining: Angel runs the IPN push command; then
kicad-erp-sync pull --only BMP585 --yes+ push for BMP585, regenerate, push both branches, republish page. - 2026-11-01 (chat 6): Angel: motor is a plain 3 V coin motor, driven by "just an N-MOSFET on one side" (Cricket: AO3400 + 1N4001W). DRV8210 removed; DMG1012T-7 chosen over AO3400A because Rds(on) is specified at Vgs 1.8 V (AO3400A only from 2.5 V). 68c6f83 / lib 969b18d.
- 2026-11-01 (chat 6): drawn by codex-worker, reviewed: lib 85e241a + f0a5440 (motor fields = ERP, no placeholder MPN), board a9b5797/db11fdf, 6 sheets; regenerated here: tidy 0, ERC 0, rendered overlaps 0, doc-check pass; pin-by-pin netlist matches netplan; 23 expected node changes only (docs/reva-schematic-review.md). Project page v2 published. kicad-erp-sync pull for EE-C-0244..0247 (MAX30001, SiT1533, BMP581, TPD1E01B04) blocked by the permission classifier: needs Angel's go. NOT pushed (one push after IPNs).
- 2026-11-01 (chat 6): netplan 39ef74e + plan.md: ECG MAX30001 (DS Fig.17a two-electrode, BioZ NC), one SiT1533 32 kHz clock to MAX30001 FCLK, MAX86141 GPIO2 and MAX32664 32KIN (Y301 removed, needs Angel's OK), DRV8210 + EE-C-0183 from VSYS (duty cap in firmware), BMP581 0x46, NFC pins 32/30 (PMIC_INT moved to pin 35). Schematic drawing delegated to codex-worker.
- 2026-11-01 (chat 6): Angel: add single-lead ECG (two electrodes, pulse arrival time for BP) and a vibration motor (Cricket coin motor EE-C-0183); barometer and NFC too if space allows (drawn now, kept or dropped at placement).
- 2026-10-31 (chat 5): Angel: U402 +1V8 "is symbol and net, this can not happen" (bypass wire came down through the rail symbol on C403). c0f24b7: bypass() puts the rail on the IC pin when the cap is reached from above; U201 VDDH wired to VDD; C303 own rail; C304 under B5. New checker class (wire through symbol, lib 59694df) found 4, all fixed; netlist identical, tidy/rendered/ERC 0, doc-check pass.
- 2026-10-31 (chat 5): 71dc57f clears the 4 text-over-line overlaps
kicad-overlap-check --renderedfound (rail test points TP204/J101 pin-up, XL2 by label off PMIC_INT, U101 pin 32 VSYS stub). Netlist node sets identical, tidy 0, ERC 0, rendered 0, doc-check pass. Pushed to board-scaffold (draft PR #1). - 2026-10-31 (chat 4): ERP parts EE-C-0227..0242 (16 OpenPulse symbols) + EE-C-0243 (Crystal_32.768kHz_2012_9pF, was unnumbered on master), all with manufacturer part; TestPoint_Pad_D2.0mm board feature, no IPN. Lib 16ca327/df5dc36, board af35d4b (IPN-only diff); netlist/tidy/ERC 0/doc-check pass; kicad-check on lib branch 90/0. Pushed both; KiCad#11 opened. Project page tooling copied from Switched_USB_Hub (b071e74), artifact v1 published (render not checked: browser pane not signed in).
- 2026-10-31 (chat 4): Angel approved all six schematic choices as drawn (LSOUT passive+GND, PPG_INT_N 1k, RSTN 100 nF+10 ohm, 8.2 pF 0603, 22/4.7 uF 0603, MDBT53 VBUS NC). Schematic c1877ad stands.
- 2026-10-31 (chat 3): ~/kicad-lib switched from docs/native-waypoint-corridors (merged) to master (owner OK); KiCad now finds title block 006 without an override.
- 2026-10-31 (chat 3): schematic on the EmbeddedEra 006 title block (owner: follow the KiCad template). Stock title block came from ~/kicad-lib on a branch without 006. REV value 2.6 -> 2.2 mm (touched its caption; lib 3eb68c6); SWD pads moved clear of the title block (c1877ad). doc-check pass.
- 2026-10-31 (chat 3): schematic PDF passes doc-check. Root cause of most overlaps: multi-line notes in KiCad's PDF text layer; sch_gen now writes one text per line (2x pitch) and horizontal fields on rotated parts (lib da5c2a2). Four symbols fixed (MAX86141/MAX30208 bodies, MAX32664 VDD/VCORE moved, W25Q IO names shortened). OpenPulse d238cb8: netlist, tidy 0 overlaps, ERC 0, kicad-check 89/0. Not pushed.
- 2026-10-31: schematic draft c03d1dc (codex-worker): netlist/tidy/ERC pass, PDF doc-check fails on text overlaps; library openpulse-ics merged with openpulse-parts (dc45449), footprints verified pad by pad; netplan verified items folded in (20cfcdd).
- 2026-10-31 (chat 2): prior IC agent was still running in the background and writing to ~/kicad-lib-openpulse-ics; this chat waits for it, then reviews and fills gaps. Reference material copied to ~/Documents/OpenPulse-ref (datasheets ds/, LCSC conversions ee/ ee2/, HealthyPi hpm/ hp/, jlc.py). Part picks: MAX32664GTGC+ (no LCSC stock, LCSC field blank; C17350501 is the D); W25Q128JWPIQ WSON-8 6x5 (C2689660); 2.2 uH: prior agent's DFE201612P-2R2M=P2 (C79317, 144 mOhm, 1.5 A) kept for nPM1300 and MAX17222; 10 uH LBMF1608T100M (C86752, 0603) x2 for MDBT53; MAX32664 crystal needs CL 6 pF, ESR <90k -> Q13FC13500049 3215 (C95361); MDBT53 crystal reuses Crystal_32.768kHz_2012_9pF; pogo/SWD = TestPoint_Pad (board feature). MDBT53 footprint from Raytac spec p12 (0.975 pitch; LCSC rounds to 0.97). Netplan VERIFY results: BMI323 13 SCx=SCL, 14 SDx=SDA, 2/3 NC, 1 SDO->GND (0x68), 12 CSB->VDDIO; MAX17222 pin 4 SEL shorted to GND = 5.0 V; MAX86141 VREF 1 uF to GND_ANA (not 10 uF); MAX32664C TQFN pins as netplan. Open: MAX32664 T2433+2C EP size (ADI land pattern 90-100089 would not download; stock EP1.75x1.6 used).
- 2026-10-31: wrist raw-PPG BP path (owner), MAX32664C hub; JLC04081H-3313 stackup; 0201 cap library; HealthyPi v12/v9 netlists used as reference.
- 2026-10-31: Name OpenPulse chosen by Angel; repo from Project_Template, board from kicad-lib template (PR EmbeddedEra/OpenPulse#1, draft).
- 2026-10-31: 0201 passives wherever the value exists in 0201 (owner); bulk caps 0402/0603 for DC-bias derating.
- 2026-10-31: JLCPCB rule set (OpenPulse_Band.kicad_dru): 0.4 mm WLPs do not escape under safe-everywhere rules; board is JLCPCB-only.
- 2026-10-31: JLCPCB assembly: NeoDen YY1 setup has no nozzle below CN065, so no 0201 in-house.