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
6 changes: 3 additions & 3 deletions docs/hardware/interfaces.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ Bring-up configuration in [`src/main.cpp`](../../src/main.cpp):

Firmware writes identical samples to both stereo slots. MAX98357A is mono. On the main control board, gain is the solder jumper next to the amplifier ([board README](../../hardware/boards/main-control-board/README.md)). On the advanced breakout, **GAIN** and **SD** stay unwired (GAIN floating ≈ 9 dB, SD pulled up ≈ left channel) — [wiring.md](wiring.md).

Amp **Vin** = USB **5V**. I2S wires are 3.3 V logic. Speaker connects to **SPK+** / **SPK−** — [main-control-board.md](main-control-board.md).
On the main control board, amp **Vin** is **AUDIO_5V** (net-tied from **SERVO_5V** after the eFuse), not raw USB **+5V** — [power.md](power.md). On the advanced breakout, amp **Vin** is the shared USB **5V** rail — [wiring.md](wiring.md). I2S wires are 3.3 V logic. Speaker connects to **SPK+** / **SPK−** — [main-control-board.md](main-control-board.md).

> [!WARNING]
> MAX98357A SPK- is not ground.
Expand Down Expand Up @@ -69,9 +69,9 @@ Default on (`PCA9685_OE_WIRED = true` in [`include/pins.h`](../../include/pins.h

Single USB-C on the robot: the **main control board**.

| Net | Board USB-C | ESP32 |
| Net | Board USB-C | ESP32 / loads |
| --- | --- | --- |
| VBUS | +5V rail | **5V** pad |
| VBUS | through fuse → **+5V** | ESP32 **5V** pad; eFuse input → **SERVO_5V** (servos + amp) |
| GND | common GND | **GND** |
| D− | data | **GPIO18** |
| D+ | data | **GPIO19** |
Expand Down
55 changes: 49 additions & 6 deletions docs/hardware/pinout.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Logic level: **3.3 V**.

| GPIO | Status | Reason |
| --- | --- | --- |
| GPIO9 | **Reserved** | BOOT button / strapping. Do not pick casually for peripherals |
| GPIO9 | **Reserved** | BOOT / strapping. On the main control board it is also on **J4** (extension only) — do not pull low at reset (download mode). Do not pick casually for peripherals |
| GPIO10 | **Occupied** | Onboard WS2812 |
| GPIO12–GPIO17 | **Unavailable** | Stacked flash, not brought out |
| GPIO18 | **Reserved** | Native USB D− (main control board USB-C; advanced path: [5993](wiring.md#usb-connector-5993)) |
Expand All @@ -30,14 +30,57 @@ Logic level: **3.3 V**.

| GPIO | Status | Notes |
| --- | --- | --- |
| GPIO6 | Free | Unused |
| GPIO7 | Free | Unused |
| GPIO8 | Free | Unused |
| GPIO20 | Default UART0 RX | Silkscreen RX. Free for other use only if USB CDC remains the console (`ARDUINO_USB_CDC_ON_BOOT=1`) |
| GPIO21 | Default UART0 TX | Silkscreen TX. Same caveat as GPIO20 |
| GPIO6 | Free | Brought out on **J4** (main control board) |
| GPIO7 | Free | Brought out on **J4** |
| GPIO8 | Free | Brought out on **J4**; strapping — do not pull low at reset |
| GPIO20 | Default UART0 RX | Silkscreen RX; also on **J4**. Free for other use only if USB CDC remains the console (`ARDUINO_USB_CDC_ON_BOOT=1`) |
| GPIO21 | Default UART0 TX | Silkscreen TX; also on **J4**. Same caveat as GPIO20 |

Power pads (not GPIO): **5V**, **GND**, **3V3**.

## Main control board headers

Pin order matches the KiCad board and [`expected-nets.yml`](../../hardware/boards/main-control-board/expected-nets.yml). Board overview: [board README](../../hardware/boards/main-control-board/README.md).

### J2 — OLED (`Conn_OLED`)

| Pin | Net |
| --- | --- |
| 1 | **+3.3V** |
| 2 | **GND** |
| 3 | **I2C SDA** |
| 4 | **I2C SCL** |

### J3 — I2C extension (`Conn_extension`, JST)

Same bus as J2 / PCA9685. **Pin order is not the same as J2** (GND and 3.3 V are swapped).

| Pin | Net |
| --- | --- |
| 1 | **GND** |
| 2 | **+3.3V** |
| 3 | **I2C SDA** |
| 4 | **I2C SCL** |

### J4 — 12-pin extension (`Conn_02x06_Odd_Even`)

| Pin | Net |
| --- | --- |
| 1 | **SERVO_5V** |
| 2 | **GP21** (default UART0 TX) |
| 3 | **GND** |
| 4 | **GP20** (default UART0 RX) |
| 5 | **GND** |
| 6 | **GP9** (strapping / BOOT — do not pull low at reset) |
Comment thread
coderabbitai[bot] marked this conversation as resolved.
| 7 | **+3.3V** |
| 8 | **GP8** (strapping — do not pull low at reset) |
| 9 | **I2S BCLK** |
| 10 | **GP7** |
| 11 | **I2S LRC** |
| 12 | **GP6** |

I2S **DIN** is not on J4 (ESP32 → amp only). **SERVO_5V** is the eFuse-protected rail — [power.md](power.md).

## PCA9685 channels (not ESP32 GPIO)

| PCA9685 channel | Firmware | Mechanism |
Expand Down
14 changes: 9 additions & 5 deletions docs/hardware/power.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,25 @@

## Architecture

One common **nominal 5 V** rail feeds the robot.
USB-C brings in a **nominal 5 V**. On the [main control board](../../hardware/boards/main-control-board/README.md) that splits into a logic/host rail and a protected servo (and amp) rail.

| Net | Source | Loads |
| --- | --- | --- |
| **+5V** | Main control board USB-C **VBUS** | ESP32 **5V**, PCA9685 **5V**, MAX98357A **Vin**; servos from PCA9685 **V+** |
| **3V3** | ESP32 onboard LDO, from the 5 V input | ESP32 core/GPIO, PCA9685 **VCC**, OLED **VCC** |
| **+5V** | USB-C **VBUS** → 3 A PPTC fuse | ESP32 **5V**, 5 V indicator, eFuse input |
| **SERVO_5V** | TPS259571 eFuse out of **+5V** (~2 A via `R14`) | Servo header 5 V pins, bulk capacitor; amp supply via net tie |
| **AUDIO_5V** | Net-tied from **SERVO_5V** (not raw **+5V**) | MAX98357A **Vin** |
| **3V3** | ESP32 onboard LDO, from the 5 V input | ESP32 core/GPIO, PCA9685 **VCC** / **VDD**, OLED **VCC**, I2C pull-ups |
| **GND** | Board USB-C GND + ESP32 GND | Everything |

ESP32 internally runs at 3.3 V logic. Servo power **does not** pass through the ESP32 3.3 V regulator. USB **5V** → PCA9685 **5V**; PCA9685 **V+** → servo **5V**; PCA9685 **VCC** ← ESP32 **3V3**. The advanced breakout harness draws the same nets — [wiring.md](wiring.md).
ESP32 internally runs at 3.3 V logic. Servo power **does not** pass through the ESP32 3.3 V regulator. On the main control board: **+5V** feeds the module **5V** pad; **SERVO_5V** feeds the servo plugs; PCA9685 **VDD** ← **3V3**. The chip has no package “V+” pin — servo 5 V is a board distribution net to the connector (same idea as Adafruit breakout **V+**). The advanced breakout harness draws equivalent nets without the board eFuse — [wiring.md](wiring.md).

> [!WARNING]
> Never power the servos from the ESP32 3.3 V regulator.

Waveshare documents the C3-Zero LDO as ME6217C33M5G (hundreds of mA class). That is enough for logic + OLED + PCA9685 digital. It is **not** a servo supply.

Multi-servo stall can hit the eFuse’s ~2 A limit before the 3 A resettable fuse trips. Use a **5 V / ≥ 2 A** supply; expect occasional **SERVO_5V** (and amp) cutouts under heavy load, then auto-retry.

## Servo current (worst case)

Datasheet stall currents for PowerHD HD-1370A:
Expand All @@ -40,7 +44,7 @@ This **excludes**:

## USB supply

Power and data enter on the **main control board USB-C** (one cable). Nets: VBUS → +5V, GND, D− → GPIO18, D+ → GPIO19. Details: [interfaces.md](interfaces.md).
Power and data enter on the **main control board USB-C** (one cable). Nets: VBUS → fuse → **+5V**, GND, D− → GPIO18, D+ → GPIO19. Servos and the amp sit behind the eFuse on **SERVO_5V** / **AUDIO_5V**. Details: [interfaces.md](interfaces.md).

Two 5.1 kΩ CC resistors on the board mark it as a USB device. The charger decides how much current arrives. Use a **5 V / ≥ 2 A** source, with extra margin if several servos move **while audio plays**. The connector is **not** USB-PD voltage conversion. Feed it 5 V USB.

Expand Down
6 changes: 4 additions & 2 deletions hardware/boards/main-control-board/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ This board drives the robot's servos and speaker. Power and USB data come in on
- **Built:** not manufactured
- **Tested:** not tested

![Main Control Board](./main-control-board-rev-2-preview.jpg)
![Main Control Board](./main-control-board-rev-3-preview.jpg)

## Soldered on the board

Expand All @@ -21,7 +21,9 @@ The servo driver, the speaker amplifier, and the USB-C connector are parts on th
- A **TPS259571** eFuse (`U4`) sits between that 5 V rail and servo 5 V. Current limit is set by `R14` (1 kΩ ≈ 2 A). On fault the device auto-retries.
- **OLED header** is for the SSD1306 display. Pin order, from pin 1: 3.3 V, ground, SDA, SCL.
- A second header shares that I2C bus. Its pin order is different: ground, 3.3 V, SDA, SCL.
- A spare 4-pin header is on the board for later use.
- A **12-pin extension port** (`J4`) breaks out `SERVO_5V`, two grounds, `+3.3V`, I2S BCLK/LRC, and GPIOs GP6–GP9 / GP20 / GP21.
- GP8 and GP9 are ESP32-C3 strapping pins. Do not pull them low at reset; GP9 low enters download mode.
- GP20 and GP21 are the default UART0 RX/TX. Boot log output appears on GP21 at power-up.

A solder jumper next to the amplifier is marked as a 6 dB gain limit.

Expand Down
37 changes: 35 additions & 2 deletions hardware/boards/main-control-board/expected-nets.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
# Net classes = KiCad netlist `class` list, effective class first.
# Compare with: kicad-cli sch export netlist
# See docs/pcb.md#expected-nets-yml
#
# J4 = 12-pin extension port (SERVO_5V, GND×2, +3.3V, I2S BCLK/LRC, GP6–GP9, GP20, GP21).

netclasses:
"+5V":
Expand Down Expand Up @@ -31,6 +33,16 @@ netclasses:
- Default
"/ESP32/GP6":
- Default
"/ESP32/GP7":
- Default
"/ESP32/GP8":
- Default
"/ESP32/GP9":
- Default
"/ESP32/GP20":
- Default
"/ESP32/GP21":
- Default
"/I2S_BCLK":
- Default
"/I2S_LRC":
Expand Down Expand Up @@ -77,9 +89,10 @@ nets:
- U4.5:OUT
"+3.3V":
- C1.2:2
- C7.1:1
- J2.1:Pin_1
- J3.2:Pin_2
- J4.2:Pin_2
- J4.7:Pin_7
- J7.3:Pin_3
- R3.1:1
- R4.1:1
Expand All @@ -92,11 +105,14 @@ nets:
- C3.1:1
- C4.1:1
- C5.1:1
- C6.2:2
- C7.2:2
- D1.1:K
- D2.1:K
- J2.2:Pin_2
- J3.1:Pin_1
- J4.3:Pin_3
- J4.5:Pin_5
- J7.2:Pin_2
- R1.1:1
- R2.1:1
Expand Down Expand Up @@ -141,12 +157,29 @@ nets:
- R3.2:2
- U1.23:~{OE}
"/ESP32/GP6":
- J4.4:Pin_4
- J4.12:Pin_12
- J8.1:Pin_1
"/ESP32/GP7":
- J4.10:Pin_10
- J8.2:Pin_2
"/ESP32/GP8":
- J4.8:Pin_8
- J8.3:Pin_3
"/ESP32/GP9":
- J4.6:Pin_6
- J8.4:Pin_4
"/ESP32/GP20":
- J4.4:Pin_4
- J8.8:Pin_8
"/ESP32/GP21":
- J4.2:Pin_2
- J8.9:Pin_9
"/I2S_BCLK":
- J4.9:Pin_9
- J7.6:Pin_6
- U3.16:BCLK
"/I2S_LRC":
- J4.11:Pin_11
- J7.7:Pin_7
- U3.14:LRCLK
"/I2S_DIN":
Expand Down
Loading
Loading