La placa en números
Fork del diseño abierto esp-rs/esp-rust-board (CERN-OHL-P), migrado a KiCad 10 y reducido a lo que necesita el llavero.
Diagrama de bloques
Con USB, el power path alimenta desde 5 V y el MCP73831 carga la batería. Sin USB, Q1 pasa la batería al buck. El ESP32-C3 usa su USB nativo (IO18/19), sin puente USB-serial.
flowchart LR USB["USB-C J1
5 V + D+/D- + ESD"] --> PP["Power path
Q1 AO3401A, D4/D6 B5819W"] PP --> CHG["Cargador U6
MCP73831, ~213 mA"] CHG --> BAT["LiPo 602530
J3"] BAT --> PP PP --> BUCK["Buck U5
SY8088 → 3.316 V"] BUCK --> MCU["ESP32-C3-MINI-1
antena PCB"] USB -. "D+/D-" .-> MCU MCU <-->|"I2C IO8/IO10"| ACC["LIS3DH U7
0x19, INT1→IO3"] MCU <-->|"I2C"| OLED["OLED SSD1306
J2"] BTN["SW2 / SW3
IO9 / IO5"] --> MCU BAT -. "VBAT/2 → IO1" .-> MCU
Layout
Arriba la antena del ESP32 (lado de la argolla). Derecha el USB-C. Izquierda los pulsadores laterales. Abajo el buck, el acelerómetro, los test pads y J2.

Render de KiCad de la cara superior (F). Todos los componentes SMD van de este lado.
Reglas de cobre
- Ruteo con Freerouting 2.5; USB y buck reajustados en la revisión 2.
- Plano de GND sólido en B.Cu.
- 18 vías de GND, 8 de ellas de costura agregadas en la revisión 2.
- Sin cobre bajo ni alrededor de la antena del ESP32-C3-MINI-1.
- Pista mínima 0.102 mm, separación mínima medida en USB 0.154 mm.
- Envolvente de batería en F.Fab: x 2.0 a 32.0, y 6.7 a 31.7 mm.
Lista de materiales
Exactamente lo que va en keychain-pet-bom.csv. J2, J3 y TP1 a TP7 no se ensamblan en fábrica.
| Ref | Cant | Fabricante | MPN | Valor | Footprint | LCSC |
|---|
GPIO y conector de la pantalla
IO8 e IO9 son pines de arranque del ESP32-C3 y deben quedar con pull-up. IO3 puede despertar al chip del deep sleep con una sacudida.
| GPIO | Función |
|---|---|
| IO1 | VBAT/2 al ADC (divisor 220k / 220k + 100 nF) |
| IO2 | Sin uso, pin de arranque con pull-up 10k |
| IO3 | LIS3DH INT1, despertar por movimiento |
| IO4 | LIS3DH INT2 (tap) |
| IO5 | Botón B (SW3) |
| IO7 | Libre (sin motor en v1) |
| IO8 | I2C SCL, pull-up 10k |
| IO9 | Botón A (SW2) y BOOT |
| IO10 | I2C SDA |
| IO18 / 19 | USB D- / D+ |
| IO20 / 21 | UART en test pads |
J2: módulo OLED 0.96" SSD1306
Header de 2.54 mm en la cara inferior. El módulo va girado 180°, así que el firmware rota la imagen.
Verificado contra el módulo comprado. Su serigrafía dice VCC GND SCL SDA. La primera versión de la placa tenía VCC y GND invertidos y habría alimentado la pantalla al revés.
Test pads para jig de pogo pins
3V3, GND, VBAT, EN, IO9, TX, RX
USB y lazo del regulador
Los dos puntos que la revisión interna marcó y que se rehicieron en la rev 2. Números medidos sobre la placa, antes y después.
Par diferencial USB
| Medida | Antes | Rev 2 |
|---|---|---|
| Largo D+ | 15.126 mm | 7.901 mm |
| Largo D- | 8.072 mm | 7.901 mm |
| Vías D+ | 2 | 0 |
| Vías D- | 0 | 0 |
Pistas de 0.15 a 0.20 mm en F.Cu sobre el plano de GND. Pistas más anchas violaban el espacio entre los pads de 0.5 mm del conector y los ESD.
Pendiente: 90 Ω no está garantizado. Hace falta el stackup real de la fábrica. Es USB 2.0 full speed (12 Mbit/s).
Lazo del SY8088 (distancia centro a centro)
| Conexión | Antes | Rev 2 |
|---|---|---|
| C5 VIN a U5 VIN | 4.666 | 2.198 |
| C5 GND a U5 GND | 4.213 | 2.916 |
| U5 SW a L1 | 4.199 | 3.279 |
| L1 a C7 + | 5.074 | 3.168 |
| C7 GND a U5 GND | 4.336 | 5.349 |
Valores en mm. C7 GND vuelve por una vía local a 1.0 mm de su pad directo al plano, en lugar de una pista larga. Sigue las recomendaciones de layout del datasheet de Silergy.
Cómo se apila y dónde están los botones
La carcasa se generó a partir del STEP de esta placa y se verificó pieza por pieza: 0 mm³ de interferencia.
Pila en Z (desde el frente)
Componente más alto bajo la batería: carcasa del USB-C, a 4.31 mm sobre el cobre. Despeje a la batería: 1.30 mm.
Pulsadores laterales GT-TC172A-H035-L1
| Cara del actuador | x = -0.55 mm |
| Centro SW2 / SW3 | y = 13.6 / 20.0 mm |
| Altura sobre F.Cu | 2.45 ± 0.2 mm |
| Recorrido | 0.15 ± 0.05 mm |
| Fuerza (datasheet) | 180 gf |
| Abertura en la carcasa | 2.4 x 2.4 mm |
| Juego tapa / pre-gap / tope | 0.20 / 0.03 / 0.13 mm |
Para ensamblaje: el modelo 3D del pulsador solo existe en VRML y no sale en el STEP, así que la alineación con la carcasa depende de estas cotas del datasheet.
Todo sale de la impresora
Cierre a presión con 4 ganchos, sin tornillos. Ventana de la pantalla abierta; el lente de acrílico es opcional. Se imprime sin soportes en K2, K2 Pro y SPARKX i7.
| Pieza | Por equipo | Material | Orientación | Por placa de impresión |
|---|---|---|---|---|
| Frente (front_bezel) | 1 | PLA o PETG | Cara de la pantalla abajo | 30 |
| Tapa trasera (back_cover) | 1 | PETG (ganchos) | Cara exterior abajo | 36 |
| Botones (button_caps_plate) | 2 | PETG | Pestaña interior abajo | par por equipo |
| Guía de luz (light_pipe) | 1 | PETG o PLA transparente | De pie, faceta arriba | n/a |
Impresión
- Boquilla 0.4 mm, capa 0.2 mm
- 3 paredes, 5 capas arriba y abajo, gyroid 20%
- Sin soportes ni brim
- Parámetros editables en case.py; el script falla si hay interferencia
Ajustes medidos
- 36 x 36 x 19.25 mm, 45 mm con la argolla
- PCB a costillas: 0.20 mm por lado
- Vidrio OLED hundido 1.15 mm; abertura USB-C 12.9 x 7.0 mm
- Ganchos: 1.0% de deformación (límite PETG 3.5%)
Secuencia de armado
Lo único que se suelda a mano es J2 (4 pines) y J3 (2 cables).
- Soldar el módulo OLED en J2, cara inferior, girado 180°. Cortar los pines a 1.2 mm o menos del lado del vidrio y 1.5 mm o menos del lado F.
- Meter cada botón impreso desde adentro del frente, con la cara hacia afuera, hasta que la pestaña interior asiente.
- Soldar la batería en J3 (rojo a +, negro a -) y ubicarla sobre el contorno F.Fab, x 2.0 a 32.0 y y 6.7 a 31.7 mm.
- Colocar la placa en el frente, pantalla primero. Asienta sobre las costillas y el USB-C queda alineado con su abertura.
- Insertar la guía de luz desde afuera, con la faceta hacia el LED. Una gota de UV o CA la fija.
- Cerrar la tapa (4 clics) y comprobar que ambos botones hacen clic y vuelven.
Chequeos que ya pasa
Preguntas abiertas
¿Qué ancho y separación dan 90 Ω con tu stackup de 1.0 mm? ¿Hace falta para full speed?
La batería y la argolla metálica quedan cerca de la antena. ¿Ves riesgo de RF?
¿Cambiamos los pads de J3 por un JST pequeño soldado en fábrica? Elimina 2 soldaduras manuales por equipo.
Para el lote de 30: ¿OLED suelta con FPC y conector en la placa en vez del módulo con pines? Requiere sumar los componentes de soporte de la pantalla.
El cargador disipa unos 0.6 W en el peor caso (estimación, no medición). ¿Basta el cobre actual?
¿Panel, acabado o máscara más baratos sin arriesgar los LGA (LIS3DH y módulo ESP32)?
Archivos
Todo está en el repo del proyecto, carpeta hardware/.
| Archivo | Contenido |
|---|---|
| fab/pcbway/keychain-pet-gerbers.zip | Gerbers y taladros |
| fab/pcbway/keychain-pet-bom.csv | BOM con fabricante, MPN y LCSC |
| fab/pcbway/keychain-pet-centroid.csv | Posiciones para pick and place |
| pcb/keychain-pet.kicad_pcb / .kicad_sch | Proyecto KiCad 10 editable |
| SPEC.md, REVISION_REPORT.md | Especificación y cambios de la rev 2 |
| case/out/*.stl, *.step | Piezas de la carcasa y ensamble |
| scripts/build_board.py, route_board.py, make_fab.py | Generan la placa y el paquete de fabricación |