Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions PCB/battery.kicad_sch
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@
)
)
)
(property "Value" "JST-PH_2Pin_Battery"
(property "Value" "JST-PH_2Pin_Battery_RightAngle_Horizontal"
(at 148.59 100.33 0)
(show_name no)
(do_not_autoplace no)
Expand Down Expand Up @@ -262,7 +262,7 @@
)
)
)
(property "Description" "Generic connector, single row, 01x02, script generated (kicad-library-utils/schlib/autogen/connector/)"
(property "Description" "JST PH-series 2-pin THT connector -- RIGHT-ANGLE / HORIZONTAL mount only, cable exits parallel to the PCB. Do NOT substitute a vertical/straight variant. MPN: S2B-PH-K(LF)(SN)"
(at 148.59 105.41 0)
(show_name no)
(do_not_autoplace no)
Expand Down
59 changes: 45 additions & 14 deletions PCB/diagrams/power_control_layout.html

Large diffs are not rendered by default.

25 changes: 15 additions & 10 deletions PCB/diagrams/power_control_layout.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,36 @@

Q_PWR1 carries the entire board's current — every milliamp the ESP32, XBee, OLED, and everything else draws passes through one SOT-23 PMOS. But the layout-driving constraint here isn't electrical at all: SW_PWR1 is a physical button that has to land under a hole in your enclosure.

**Source:** `PCB/power_control.kicad_sch`  ·  **Nets:** VSYS → PWR_EN  ·  **Package:** SOT-23 ×2, SOD-123 ×2
**Source:** `PCB/power_control.kicad_sch`  ·  **Nets:** VSYS → PWR_EN  ·  **Package:** SOT-23 ×3, SOD-123 ×2

## What's on this sheet

A press-to-start, software-held latch: the button turns the board on, the MCU has to grab the hold line before the button is released, and either side of a diode-OR can keep power on.
A press-to-start, software-held latch: the button turns the board on, the MCU has to grab the hold line before the button is released, and either side of a diode-OR can keep power on. A small transistor inverter (R_INV_BASE1 / Q_INV1 / R_INV_PU1) sits between the button and that diode-OR — see callout F for why it can't just tap the button's sense line directly.

| Ref | Value | Footprint | Role |
|---|---|---|---|
| Q_PWR1 | DMG2305UX | SOT-23 | Main power switch — VSYS to PWR_EN, carries full system current |
| Q_LATCH1 | 2N7002 | SOT-23 | Pulls Q_PWR1's gate low to turn it on |
| D_OR1 / D_OR2 | 1N4148W | SOD-123 | Diode-OR: button press or MCU hold, either one latches power on |
| D_OR1 / D_OR2 | 1N4148W | SOD-123 | Diode-OR: `PWR_BTN_TRIGGER` (actual button press, via the inverter) or MCU hold, either one latches power on |
| R_GATE1 | 100kΩ | 0402 | Q_PWR1 gate pull-up — off by default |
| R_LATCH_G1 | 10kΩ | 0402 | Q_LATCH1 gate pull-down — off by default |
| R_BTN_PU1 / R_PWR_SENSE1 | 100kΩ / 100kΩ | 0402 | Button sense divider — MCU reads pressed (0V) vs idle (½VSYS) |
| R_BTN_PU1 | 100kΩ | 0402 | Button sense pull-up — MCU reads pressed (0V) vs idle (VSYS) |
| R_INV_BASE1 | 10kΩ | 0402 | Inverter base resistor, from `PWR_BTN_SENSE` |
| Q_INV1 | MMBT3904 | SOT-23 | Inverter: idle (button up) holds `PWR_BTN_TRIGGER` low; pressed lets `R_INV_PU1` pull it high |
| R_INV_PU1 | 100kΩ | 0402 | `PWR_BTN_TRIGGER` pull-up to VSYS — the inverter's collector load |
| C_DBNC1 | 100nF | 0402 | Button debounce, right at the switch |
| SW_PWR1 | Alps SKRTLAE010 | SMD tactile | Physical power button — must reach the enclosure surface |

## Suggested floorplan

Top copper layer. The VSYS→PWR_EN path runs straight across the top as one thick lane; the latch logic hangs underneath it as a compact, low-current block; the button sits wherever your enclosure needs it to.
Top copper layer. The VSYS→PWR_EN path runs straight across the top as one thick lane; the latch logic hangs underneath it as a compact, low-current block; the inverter sits just below the button's sense line, on the way to the diode-OR; the button sits wherever your enclosure needs it to.

![Top-down PCB floorplan for the soft-latch power switch, showing VSYS entering the PMOS source and exiting the drain as PWR_EN in one straight lane across the top, the NMOS latch and diode-OR logic clustered in a compact low-current block beneath it, and the physical power button placed near the board edge with its debounce capacitor right at its pins.](power_control_layout.svg)
![Top-down PCB floorplan for the soft-latch power switch, showing VSYS entering the PMOS source and exiting the drain as PWR_EN in one straight lane across the top, the NMOS latch and diode-OR logic clustered in a compact low-current block beneath it, a small transistor inverter between the button's sense line and the diode-OR so only an actual press (not the button's idle level) can trigger the latch, and the physical power button placed near the board edge with its debounce capacitor right at its pins.](power_control_layout.svg)

*Top-layer placement for the soft-latch switch. **Gold copper** is the VSYS→PWR_EN power path; **pale blue** is the low-current gate-drive, sense, and control logic; rings mark vias to the ground plane.*
*Top-layer placement for the soft-latch switch. **Gold copper** is the VSYS→PWR_EN power path; **pale blue** is the low-current gate-drive, sense, inverter, and control logic; rings mark vias to the ground plane.*

- 🟨 Power copper (VSYS, PWR_EN)
- 🟦 Gate-drive / sense / control
- 🟦 Gate-drive / sense / inverter / control
- ⚪ Via to GND plane

## Why it's arranged this way
Expand All @@ -42,6 +45,7 @@ Top copper layer. The VSYS→PWR_EN path runs straight across the top as one thi
| **C** | **C_DBNC1 sits right on the switch's own pins.** Same principle as the charger's pushbutton guidance in its own datasheet: the debounce cap does its job by being close to the contact bounce it's filtering, not by being close to anything else. |
| **D** | **The diode-OR and its pull-down are one compact decision node.** D_OR1, D_OR2, R_LATCH_G1, and Q_LATCH1's gate all meet at PWR_LATCH_G — keeping that cluster tight matters less for noise than for just keeping the logic legible on the board. |
| **E** | **PWR_HOLD arriving late is a hard failure, not a glitch.** Per this project's own GPIO notes, pin 36 (PWR_HOLD) must go high as the MCU's very first instruction — release the button before that happens and R_LATCH_G1's pull-down turns everything back off. Not a layout fix, but it's the reason D_OR2's path exists at all. |
| **F** | **D_OR1 can't read `PWR_BTN_SENSE` directly — found the hard way, on real hardware.** The original design had `R_BTN_PU1` (to VSYS) and a since-removed `R_PWR_SENSE1` (to GND) both on that node, dividing it to roughly half VSYS at idle — comfortably above a diode's ~0.6V forward threshold, so `D_OR1` was forward-biased (and the board powered on) the instant a battery was plugged in, button or no button. The inverter fixes this properly instead of just retuning the divider: idle, `Q_INV1` is on and holds `PWR_BTN_TRIGGER` at GND; pressed, it turns off and `R_INV_PU1` pulls `PWR_BTN_TRIGGER` to VSYS. Only a real press can forward-bias `D_OR1` now. Keep this block close to `D_OR1` — it's three parts serving one signal, not worth spreading out. |

## Routing priority

Expand All @@ -51,9 +55,10 @@ The button's position is fixed by the enclosure before you start — everything
2. Put C_DBNC1 directly on SW_PWR1's sense pin before routing anything else nearby.
3. Route the VSYS→Q_PWR1→PWR_EN lane as one straight, generously-wide path across the board.
4. Cluster Q_LATCH1, R_GATE1, R_LATCH_G1, D_OR1, and D_OR2 into one compact low-current block under the main lane.
5. Bring PWR_BTN_SENSE and PWR_HOLD in from wherever the MCU sheet actually sits — these are off-sheet nets, not local components.
5. Keep R_INV_BASE1, Q_INV1, and R_INV_PU1 together as their own small block, close to D_OR1 — they're a single-purpose inverter, not independent parts.
6. Bring PWR_BTN_SENSE and PWR_HOLD in from wherever the MCU sheet actually sits — these are off-sheet nets, not local components.

> **Checked, not just assumed:** DMG2305UX is rated for ~4A continuous with 35–50mΩ RDS(on) in this SOT-23 package — comfortably oversized for a handheld controller's sub-2A system budget, so this isn't a thermal risk the way the charger's WSON is. Nothing on this sheet needed correcting.
> **Checked, not just assumed:** DMG2305UX is rated for ~4A continuous with 35–50mΩ RDS(on) in this SOT-23 package — comfortably oversized for a handheld controller's sub-2A system budget, so this isn't a thermal risk the way the charger's WSON is. MMBT3904 is a general-purpose small-signal part switching microamps here (just enough to bias a diode) — nowhere near its ratings, no thermal consideration needed. Nothing on this sheet needed correcting beyond the divider/inverter fix in callout F.

---
*Generated from `PCB/power_control.kicad_sch` — a placement reference, not a manufacturing drawing. Model your actual footprints and DRC against your fab's rules. A richer standalone version with the full interactive design lives in [power_control_layout.html](power_control_layout.html).*
38 changes: 32 additions & 6 deletions PCB/diagrams/power_control_layout.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 changes: 14 additions & 14 deletions PCB/oled.kicad_sch
Original file line number Diff line number Diff line change
Expand Up @@ -374,16 +374,16 @@
)
(symbol "SSD1306_OLED_4pin_1_1"
(pin power_in line
(at -16.51 3.81 0)
(at -16.51 1.27 0)
(length 3.81)
(name "VCC"
(name "GND"
(effects
(font
(size 1.27 1.27)
)
)
)
(number "2"
(number "1"
(effects
(font
(size 1.27 1.27)
Expand All @@ -392,52 +392,52 @@
)
)
(pin power_in line
(at -16.51 1.27 0)
(at -16.51 3.81 0)
(length 3.81)
(name "GND"
(name "VCC"
(effects
(font
(size 1.27 1.27)
)
)
)
(number "1"
(number "2"
(effects
(font
(size 1.27 1.27)
)
)
)
)
(pin input line
(at -16.51 -1.27 0)
(pin bidirectional line
(at -16.51 -3.81 0)
(length 3.81)
(name "SCL"
(name "SDA"
(effects
(font
(size 1.27 1.27)
)
)
)
(number "4"
(number "3"
(effects
(font
(size 1.27 1.27)
)
)
)
)
(pin bidirectional line
(at -16.51 -3.81 0)
(pin input line
(at -16.51 -1.27 0)
(length 3.81)
(name "SDA"
(name "SCL"
(effects
(font
(size 1.27 1.27)
)
)
)
(number "3"
(number "4"
(effects
(font
(size 1.27 1.27)
Expand Down
Loading
Loading