Skip to content

Power Supply

1. Overview

1.1 Voltage domains

A robot is composed of several subsystems that require different supply voltages. This robot uses a battery voltage domain and two regulated voltage rails.

  • 5 V: Raspberry Pi 5, Raspberry Pi Pico 2, LED ring, sensors and low-power actuators
  • 6 V: servo driver board, which supplies the 5 SCS0009 head servos and converts to 5 V for the XIAO RP2350 mounted on it
  • Battery bus: Arduino Nano Every, STS3215-C018 servomotors, SimpleFOC Mini and the fan

The system therefore needs two 5 V buck converters and one 6 V converter.

Naming convention: the switched output of the Pololu 2813 is called the 12 V rail throughout this document. It is not regulated and follows the pack voltage; the name refers to the nominal pack voltage, not to a regulated 12 V.

1.2 Consumer requirements

Current consumption is also an important design constraint. The main consumers are listed below.

Component Supply voltage Nominal current Peak current Notes
SimpleFOC Mini + GM3506 gimbal motors (2) Battery 700 mA 4 A Total for both motors
Raspberry Pi 5 5 V 800 mA 5 A 800 mA typical bare-board current; 5 V / 5 A supply recommended
Feetech 12 V STS3215-C018 servomotors (2) Battery 900 mA 5 A Total current at stall
Raspberry Pi Pico 2 5 V 55 mA 100 mA Design estimate; measure with final firmware and peripherals
NeoPixel 7 leds ring 5 V 126 mA 126 mA $7 \times 18\ \mathrm{mA}$ at full brightness
SCS0009 servomotors (5) 6 V 750 mA 5 A Total for the five head servos; 150 mA no-load and 1 A stall each
Seeed Studio XIAO RP2350 5 V 55 mA 100 mA Supplied at 5 V by the servo driver board, which also acts as a converter from its 6 V input; design estimate, to be measured
12 V fan Battery bus 10 mA 10 mA Driven from the battery bus through a MOSFET; verify operation at 9.6 V

1.3 Power tree

flowchart TB
    bat["3S Battery<br>8.4 (BMS cutoff) to 12.6 V"] --> bms["3S BMS<br>25 A continuous"]
    bms --> xt30["XT30"]
    xt30 --> fus15["15 A slow-blow"]
    fus15 --> sw["Pololu 2813<br>cuts the + side, 16 A"] & nano["Arduino Nano Every"]
    sw --> shunt["INA226"]
    shunt --> bus["12 V bus<br>1000 µF / 25 V low-ESR"]
    btn["Push button<br>ON signal"] -.-> nano
    nano -. OFF (shutdown) .-> sw
    bus --> foc["2× SimpleFOC<br>470 µF each"] & feetech["Feetech 12 V STS3215-C018<br>×2, legs"] & mosfet["Grove Mosfet"] & d24["Pololu D24V50F5<br>5 V, 5 A"] & dfr["DFR0831<br>5 V, 4 A"] & lm["LM2596<br>6 V, fixed setting"]
    mosfet --> fan["12 V fan"]
    dfr --> neo["Torso actuators (NeoPixel 7 leds ring)"] & amp["1 speaker driver 98357A<br>"] & pico["Raspberry Pi Pico 2<br>VSYS"] & n1["Head actuators (vibration motor, leds)"]
    lm --> servocard["Servo driver board<br>6 V terminal block"]
    servocard --> scs["5× SCS0009<br>head servos"] & n3@{ label: "<span style=\"color:\">XIAO</span><br style=\"--tw-border-spacing-y:\"><span style=\"color:\">RP2350, 5 V</span>" }
    d24 --> n2@{ label: "<span style=\"color:\">Raspberry Pi 5</span><br style=\"--tw-border-spacing-y:\"><span style=\"color:\">GPIO 2,4,6</span>" }

    nano@{ shape: rounded}
    pico@{ shape: rounded}
    n1@{ shape: rect}
    n3@{ shape: rounded}
    n2@{ shape: rounded}
     bat:::yellow
     bms:::yellow
     xt30:::yellow
     fus15:::yellow
     sw:::control
     nano:::mcu12
     shunt:::measure
     bus:::rail
     btn:::control
     foc:::motors
     feetech:::motors
     mosfet:::motors
     d24:::regulators
     dfr:::regulators
     lm:::regulators
     fan:::motors
     neo:::pink
     amp:::pink
     pico:::pi5
     n1:::pink
     servocard:::servo6
     scs:::head
     n3:::pi5
     n2:::pi5
    classDef yellow fill:#e3c800,stroke:#B09500,color:#000000
    classDef control fill:#FAEEDA,stroke:#854F0B,color:#633806
    classDef measure fill:#E1F5EE,stroke:#0F6E56,color:#085041
    classDef rail fill:#F1EFE8,stroke:#5F5E5A,color:#444441
    classDef mcu12 fill:#FAECE7,stroke:#993C1D,color:#712B13
    classDef regulators fill:#bac8d3,stroke:#23445d,color:#000000
    classDef servo6 fill:#EEEDFE,stroke:#534AB7,color:#3C3489
    classDef motors fill:#0050ef, stroke:#001DBC, color:#ffffff
    classDef head fill:#E6F1FB, stroke:#185FA5, color:#0C447C
    classDef pink fill:#e6d0de, stroke:#996185, color:#000000
    classDef pi5 fill:#fad7ac, stroke:#b46504, color:#000000
    classDef Aqua stroke-width:1px, stroke-dasharray:none, stroke:#46EDC8, fill:#DEFFF8, color:#378E7A
    style sw fill:#e3c800
    style nano fill:#E1BEE7
    style shunt fill:#e6e6e6,stroke:#757575
    style foc fill:#BBDEFB,color:#000000
    style feetech fill:#BBDEFB,color:#000000
    style mosfet fill:#BBDEFB,color:#000000
    style fan fill:#BBDEFB,color:#000000
    style pico fill:#FFE0B2
    style scs fill:#EEEDFE

The tree reads from the battery at the top down to the individual consumers.

Input stage. The 3S pack goes through its BMS, an XT30 connector and a 15 A slow-blow fuse. This protected input then splits in two: the Pololu 2813 switch, and the Arduino Nano Every which stays powered whatever the switch state.

Switched bus. Downstream of the switch, the current passes through the INA226 shunt and reaches the 12 V bus, backed by 1000 µF of low-ESR bulk capacitance. Everything below this node loses power when the Nano Every opens the switch.

Direct battery loads. Three branches take the bus voltage as is: the two SimpleFOC Mini controllers, the two STS3215-C018 leg servos, and the fan through its Grove MOSFET.

Converted branches. Three converters share the same bus. The Pololu D24V50F5 supplies the Raspberry Pi 5 alone. The DFR0831 supplies the Pico 2, the LED ring, the speaker driver and the head actuators. The LM2596 supplies the servo driver board, which drives the five SCS0009 head servos and converts to 5 V for the XIAO RP2350 mounted on it.

Dashed links are signals, not power: the push button toward the Nano Every, and the Nano Every toward the switch.

2. Input stage and protections

flowchart LR
    bat["3S Battery<br>8.4 (BMS cutoff) to 12.6 V"] --> bms["3S BMS<br>25 A continuous"]
    bms --> xt30["XT30"]
    xt30 --> fus15["15 A slow-blow"]

     bat:::yellow
     bms:::yellow
     xt30:::yellow
     fus15:::yellow
    classDef yellow fill:#e3c800,stroke:#B09500,color:#000000
    classDef control fill:#FAEEDA,stroke:#854F0B,color:#633806
    classDef measure fill:#E1F5EE,stroke:#0F6E56,color:#085041
    classDef rail fill:#F1EFE8,stroke:#5F5E5A,color:#444441
    classDef mcu12 fill:#FAECE7,stroke:#993C1D,color:#712B13
    classDef regulators fill:#bac8d3,stroke:#23445d,color:#000000
    classDef servo6 fill:#EEEDFE,stroke:#534AB7,color:#3C3489
    classDef motors fill:#0050ef, stroke:#001DBC, color:#ffffff
    classDef head fill:#E6F1FB, stroke:#185FA5, color:#0C447C
    classDef pink fill:#e6d0de, stroke:#996185, color:#000000
    classDef pi5 fill:#fad7ac, stroke:#b46504, color:#000000
    classDef Aqua stroke-width:1px, stroke-dasharray:none, stroke:#46EDC8, fill:#DEFFF8, color:#378E7A

2.1 3S battery and BMS

The battery and BMS provide a voltage between 8.4V and 12.6V and a current of 25A. To discover more about this part, check the battery section

2.2 Connector and reverse polarity

To connect the battery with the robot or the charger, I chose a XT30 connector, a compact low budget and simple to use connector. The specifications meet the requirements, featuring a 15 A rated current and a polarization feature for the connection orientation.

2.3 Main 15 A fuse

A 15A fuse is used to protect all the components against high current draw. Currently, an automotive fuse is used because of it's dimensions and availability.

3. Power switching

3.1 Principle

flowchart TB
    bat["3S Battery<br>8.4 (BMS cutoff) to 12.6 V"] --> bms["3S BMS<br>25 A continuous"]
    bms --> xt30["XT30"]
    xt30 --> fus15["15 A slow-blow"]
    fus15 --> sw["Pololu 2813<br>cuts the + side, 16 A"] & nano["Arduino Nano Every"]
    sw --> shunt["12 V rail"]
    btn["Push button<br>ON signal"] -.-> nano
    nano -. OFF (shutdown) .-> sw

    nano@{ shape: rounded}
     bat:::yellow
     bms:::yellow
     xt30:::yellow
     fus15:::yellow
     sw:::control
     nano:::mcu12
     shunt:::measure
     btn:::control
    classDef yellow fill:#e3c800,stroke:#B09500,color:#000000
    classDef control fill:#FAEEDA,stroke:#854F0B,color:#633806
    classDef measure fill:#E1F5EE,stroke:#0F6E56,color:#085041
    classDef rail fill:#F1EFE8,stroke:#5F5E5A,color:#444441
    classDef mcu12 fill:#FAECE7,stroke:#993C1D,color:#712B13
    classDef regulators fill:#bac8d3,stroke:#23445d,color:#000000
    classDef servo6 fill:#EEEDFE,stroke:#534AB7,color:#3C3489
    classDef motors fill:#0050ef, stroke:#001DBC, color:#ffffff
    classDef head fill:#E6F1FB, stroke:#185FA5, color:#0C447C
    classDef pink fill:#e6d0de, stroke:#996185, color:#000000
    classDef pi5 fill:#fad7ac, stroke:#b46504, color:#000000
    classDef Aqua stroke-width:1px, stroke-dasharray:none, stroke:#46EDC8, fill:#DEFFF8, color:#378E7A
    style sw fill:#e3c800
    style nano fill:#E1BEE7
    style shunt fill:#e6e6e6,stroke:#757575
The battery input (8.4 to 12.6 V, 15 A) feeds two branches in parallel: the Pololu 2813 switch and the Arduino Nano Every. The Nano Every is therefore connected upstream of the switch, and stays powered whatever the switch state.

The two domains do not have the same voltage range. Upstream of the switch, nothing stops the pack from discharging below 9.6 V: the BMS cutoff at 8.4 V is the only limit, so the XT30 connector, the fuse and the Nano Every must be rated for 8.4 to 12.6 V. The Nano Every VIN input accepts 7 to 21 V and covers this range. Downstream, the 9.6 V software threshold opens the switch, so the switched rail only operates between 9.6 and 12.6 V.

The Pololu 2813 cuts the + side and is rated 16 A. Its output is the 12 V rail, unregulated and following the pack voltage.

Two dashed links carry signals rather than power: the push button sends the ON signal to the Nano Every, and the Nano Every commands the switch to open on shutdown.

3.2 Nano permanently powered

The Arduino Nano Every is connected upstream of the Pololu 2813, directly to the fused battery input. It stays powered whatever the state of the switch, which allows it to detect the ON press while the rest of the system is off.

The pack voltage is read through the INA226, which is located downstream of the switch. Voltage monitoring is therefore only available while the system is running; once the switch is open, the Nano Every has no measurement available. See Future improvements for low-battery restart lockout.

3.3 Power-on

A press on the push button is signalled to the Nano Every, which closes the Pololu 2813. The 12 V rail comes up and the Raspberry Pi 5, the XIAO RP2350 and the Pico 2 boot.

3.4 Clean shutdown

Three mutually exclusive events can start a shutdown: a 3-second press on the push button, a pack voltage below 9.6 V detected by the Nano Every itself, or a command sent by the Pi 5 over I2C.

At T0, the Nano Every notifies the Pi 5 over I2C. The Pi 5 forwards the notice to the XIAO RP2350 over I2C and to the Pico 2 over UART; no acknowledgement is returned.

At T0 + 5 s, the Nano Every sends the halt request to the Pi 5, over I2C or GPIO. The Pi replies with a confirmation, or the Nano falls back on a timeout.

The Nano Every then opens the switch once two conditions are met: the confirmation (or its timeout) has been received, and at least 25 seconds have elapsed since the halt request. This minimum delay gives the XIAO RP2350 and the Pico 2 time to stop their motors and run any end-of-run checks, and leaves room for such tasks to be added later.

3.5 Sequence diagram

sequenceDiagram
    participant B as Push button
    participant N as Nano Every
    participant S as Pololu 2813
    participant Pi as Raspberry Pi 5
    participant X as XIAO RP2350
    participant P as Pico 2
    autonumber

    Note over N: permanently powered

    B->>N: press (ON)
    N->>S: close the switch
    S-->>Pi: rails powered, boot
    S-->>X: rails powered, boot
    S-->>P: rails powered, boot

    alt long press (user OFF)
        B->>N: press 3 s
    else low battery
        N->>N: V < 9.6 V detected
    else software request
        Pi->>N: shutdown command (I2C)
    end

    N->>Pi: T0 — shutdown notice (I2C)
    par peripherals notified by the Pi
        Pi->>X: shutdown notice (I2C)
    and
        Pi->>P: shutdown notice (UART)
    end

    Note over N,Pi: T0 + 5 s
    N->>Pi: halt request (I2C or GPIO)
    Pi-->>N: confirmation or timeout

    Note over N: wait for confirmation (or timeout)<br/>AND at least 25 s since halt request
    N->>S: open the switch

Power sequencing and clean shutdown

The Nano Every is permanently powered and supervises the power path. The Raspberry Pi 5, the XIAO RP2350 and the Pico 2 are all supplied through the Pololu 2813 switch.

Power-up. A press on the push button is detected by the Nano Every, which closes the Pololu 2813. The rails come up and the three boards boot.

Shutdown triggers. Three mutually exclusive events can start a shutdown: a 3-second press on the push button, a pack voltage below 9.6 V detected by the Nano Every itself, or a command sent by the Pi 5 over I2C.

Notification (T0). The Nano Every notifies the Pi 5 over I2C. The Pi 5 forwards the notice to the XIAO RP2350 over I2C and to the Pico 2 over UART. No acknowledgement is returned.

Halt request (T0 + 5 s). The Nano Every sends the halt request to the Pi 5 over I2C or GPIO. The Pi replies with a confirmation, or the Nano falls back on a timeout.

Cut-off. The Nano Every opens the switch once two conditions are met: the confirmation (or its timeout) has been received, and at least 25 seconds have elapsed since the halt request. This minimum delay gives the XIAO RP2350 and the Pico 2 time to stop their motors and run any end-of-run checks, and leaves room for such tasks to be added later.

4. Measurement and thresholds

4.1 INA226

4.1 INA226

The INA226 measures the bus voltage and the current drawn on the switched battery bus. It is placed between the Pololu 2813 output and the 12 V bus, so it covers all downstream consumers but not the Nano Every.

The Nano Every reads it over I2C. The bus voltage is compared against the 9.6 V software threshold to trigger the clean shutdown sequence described in section 3.4.

Parameter Value
Position Between the Pololu 2813 output and the 12 V bus
Measured range 0 to 36 V, up to 25 A
Shunt resistor To define
I2C address To define
Read by Arduino Nano Every by software I2C

4.2 Voltage thresholds

Threshold Level Actor Action
9.6 V Software Nano Every Clean shutdown: Raspberry Pi shutdown, then switch opening
8.4 V Hardware BMS Hard battery cutoff as a last-resort safety net

Two thresholds protect the pack. The software threshold at 9.6 V, or 3.2 V per cell, is handled by the Nano Every and triggers the clean shutdown sequence. The hardware threshold at 8.4 V, or 2.8 V per cell, is enforced by the BMS, which opens the circuit as a last-resort safety net if the discharge continues.

4.2.1 Battery voltage levels

Level Pack voltage Meaning Action
Full charge 12.6 V Battery fully charged Charging complete, no alert
Normal operation 11.8–12.6 V Nominal operation Robot operating normally
Medium charge 10.5–11.8 V Acceptable level Robot operating normally
Low battery 9.6–10.5 V Low voltage Warning, reduce activities
Critical threshold 9.6 V Software safety threshold Request clean shutdown to Raspberry Pi
Last-resort hardware cutoff 8.4 V Emergency cutoff BMS opens circuit to protect battery

When the 9.6 V threshold is crossed, the Nano initiates a clean shutdown sequence (see section 3.5)

5. Rails and converters

5.1 Battery bus

5.1 Battery bus

The battery bus is the switched output of the Pololu 2813. It is not regulated: its voltage follows the pack and ranges from 9.6 V, where the software threshold opens the switch, up to 12.6 V at full charge. It is called the 12 V rail throughout this document, after the nominal pack voltage.

  • Input: fused battery input through the Pololu 2813 and the INA226
  • Voltage: 9.6 to 12.6 V, unregulated
  • Direct consumers: 2 SimpleFOC Mini, 2 STS3215-C018 leg servos, and the fan through its Grove MOSFET
  • Converters supplied: Pololu D24V50F5 (5 V), DFR0831 (5 V) and LM2596 (6 V)

Any consumer connected here must tolerate the full 9.6 to 12.6 V range. This is why the fan operation has to be verified at 9.6 V.

5.2 Raspberry Pi 5, 5 V - Pololu D24V50F5

  • Input: battery bus
  • Output: 5 V / 5 A
  • Consumers: Raspberry Pi 5 only

5.3 Auxiliary 5 V - DFR0831

  • Input: battery bus
  • Output: 5 V / 4 A
  • Consumers: Pico 2, LED ring, speaker driver and head actuators

5.4 Head servos, 6 V - LM2596

  • Input: battery bus
  • Output: 6 V fixed
  • Consumers: servo driver board, then 5 x SCS0009 and the XIAO RP2350 (supplied at 5 V by the board)

5.5 Fan - Grove MOSFET

  • Input: battery bus via Grove MOSFET
  • Consumer: 12 V fan

This is a temporary solution, the final solution will be integrated in a homemade PCB.

5.6 Branch sizing

Size each physical branch in the power tree, rather than summing all devices that use the same nominal voltage.

Branch Peak load to budget Installed converter / required rating Consumers
Battery bus At least 9 A from the known direct loads, plus the input current of all buck converters BMS: 25 A continuous; main fuse: 15 A SimpleFOC motors (4 A), leg servos (5 A), Nano Every, converters and fan
Raspberry Pi 5, 5 V 5 A Pololu D24V50F5: 5 V / 5 A Raspberry Pi 5 only; do not add loads to this branch without reducing the USB power budget
Auxiliary 5 V At least 226 mA known load, plus amplifier, vibration motor, LEDs and sensors DFR0831: 5 V / 4 A Pico 2 (100 mA), LED ring (126 mA), speaker driver and head actuators
Head servos, 6 V 5 A Select a 6 V converter rated for at least 6 A continuous 5 x SCS0009, 1 A stall current each, plus the XIAO RP2350 (100 mA) supplied at 5 V by the servo driver board; the LM2596 must be replaced if it is a standard 3 A module
Fan 10 mA No converter: connected directly to the 9.6-12.6 V battery bus 12 V fan; verify operation at 9.6 V battery voltage

The peak values above are per-branch worst cases and are not simultaneous. Summing the 9 A of direct battery loads with the input current of all buck converters exceeds the 15 A fuse, but the leg servos stalling, the gimbal motors at peak and every converter at full load do not occur at the same time. The slow-blow fuse also tolerates transients above its rating. The sizing relies on this non-simultaneity assumption.

6. Wiring and cross-cutting rules

6.1 Grounds and star point

All rails share a common battery return, connected at one star point close to the battery negative terminal. Motor and servo return wires must return directly to this point; they must not pass through the logic ground wiring.

7. Future improvements

  • Low-battery restart lockout. The INA226 sits downstream of the Pololu 2813, so the Nano Every has no voltage reading while the switch is open. Nothing currently stops a restart on a pack left below 9.6 V; a lockout would need either a second, always-on voltage sense upstream of the switch, or the Nano Every remembering the last shutdown cause.