FixTheRobot Explore Robotics / Systems Engineering / Design & Selection / Module 03

Design & Selection · Module 03

Selecting a battery and BMS

Voltage comes from the number of cells in series, capacity from the number in parallel, and the battery management system keeps every cell inside its limits.

  • Intermediate
  • Module 03: Actuators, Motors, Electrical & Power Integration
  • Written for ROS 2 Jazzy where ROS 2 is used
  • Sources checked 2026-11-05

Assumptions: Numbers in the examples are illustrative and the code is executed by the site’s tests. Type and characteristic summaries are general engineering knowledge; always confirm values on the datasheet of the part you use.

1. Engineering problem

The battery sets the supply voltage range, the runtime and the peak current the robot can draw. A pack that sags under motor current resets the computer; a pack outside its cell limits is damaged or unsafe.

2. When is this needed?

  • After the power budget gives energy and peak power.
  • When choosing between NMC and LFP.
  • When publishing battery state to ROS 2.

3. Selection and design decisions

Cell voltages from Battery University BU-205: lithium nickel manganese cobalt oxide (NMC) is 3.60 V nominal and works between 3.0 and 4.2 V per cell; lithium iron phosphate (LFP) is 3.20 or 3.30 V nominal and works between 2.5 and 3.65 V per cell. The C-rate (BU-402) expresses current relative to capacity: 1C is a one-hour discharge, 0.5C two hours, 2C 30 minutes.

Overview
PropertyNMCLFP
Nominal voltage per cell (BU-205)3.60 V3.20 / 3.30 V
Voltage range per cell (BU-205)3.0–4.2 V2.5–3.65 V
Typical robot-level consequenceHigher energy per mass (general knowledge)Flatter voltage; many robot makers prefer it for safety margin and cycle life (general knowledge, check the cell datasheet)

4. Advantages and disadvantages

  • Energy density vs thermal robustness: choose per the cell datasheet and the ODD.
  • More cells in series lowers current for the same power, so lighter cables, but needs equipment rated for the higher voltage.
  • More cells in parallel increases capacity and the available current at a given C-rate.

5. Requirements and constraints

  • Pack minimum voltage (at end of discharge and under load) stays above every consumer’s minimum input.
  • Pack maximum voltage (fully charged) stays below every consumer’s maximum input.
  • Maximum continuous current ≤ C-rate limit × capacity, from the cell datasheet.
  • A battery management system (BMS) provides cell balancing, over- and under-voltage, over-current and temperature protection.

6. Architecture

cells (S in series × P in parallel) ─▶ BMS (protection, balancing, fuel gauge) ─▶ main fuse ─▶ power distribution
BMS ─▶ computer (sensor_msgs/BatteryState)

7. Implementation

  1. From the power budget, get the energy required (Wh) and the peak current.
  2. Choose the chemistry and read the per-cell voltages and C-rate limits from the cell datasheet.
  3. Choose the series count so that pack minimum and maximum voltage fit the consumers (compute below).
  4. Choose the parallel count from capacity and current: Ah = P × cell Ah, current limit = C-rate × Ah.
  5. Choose a BMS with the pack’s cell count, current rating and the protection and communication you need.
  6. Publish the state to ROS 2 as sensor_msgs/BatteryState.
def pack(chem, cells_series, cells_parallel, cell_ah):
    nominal, lo, hi = {"NMC": (3.60, 3.0, 4.2), "LFP": (3.20, 2.5, 3.65)}[chem]
    return {"nominal V": round(cells_series * nominal, 2), "min V": round(cells_series * lo, 2), "max V": round(cells_series * hi, 2), "Ah": cells_parallel * cell_ah, "Wh": round(cells_series * nominal * cells_parallel * cell_ah, 1)}
print("7S2P NMC", pack("NMC", 7, 2, 3.0))
print("8S2P LFP", pack("LFP", 8, 2, 3.0))

Printed (checked by the site’s tests):

7S2P NMC {'nominal V': 25.2, 'min V': 21.0, 'max V': 29.4, 'Ah': 6.0, 'Wh': 151.2}
8S2P LFP {'nominal V': 25.6, 'min V': 20.0, 'max V': 29.2, 'Ah': 6.0, 'Wh': 153.6}

Reading it: seven NMC cells in series give 25.2 V nominal and swing between 21.0 and 29.4 V; eight LFP cells give about 25.6 V nominal and swing between 20.0 and 29.2 V. Both are similar in nominal voltage, so a 24 V system can use either, but the end-of-discharge voltage and the energy differ. The cell capacity (3.0 Ah) is an illustrative figure; use the datasheet value.

ROS 2 (jazzy) sensor_msgs/BatteryState carries voltage, temperature, current (negative when discharging), charge, capacity, design_capacity, percentage (0 to 1), power_supply_status, health and technology, present, cell_voltage[], cell_temperature[], location and serial_number.

8. Real examples

  • 24 V AMR: 7S NMC or 8S LFP pack with a BMS that reports cell voltages over CAN, converted to BatteryState by a driver node.
  • Small indoor robot: 4S LFP (12.8 V nominal) pack.

9. Failure scenarios

  • The charger or the pack’s full voltage exceeds a DC-DC converter’s input limit.
  • Voltage sag under motor acceleration resets the computer.
  • Fuel-gauge percentage derived from voltage alone drifts with load and temperature.
  • Cells of different age mixed in one pack.

10. Troubleshooting

  1. If the robot resets under acceleration, log pack voltage and current at 100 Hz or faster during the event.
  2. If runtime is shorter than computed, compare usable capacity at the discharge rate and temperature with the datasheet curves.
  3. If percentage jumps, check how the BMS computes it.

11. Validation

  • The example prints the values above (executed by the site tests).
  • Minimum pack voltage under peak load is above every consumer’s minimum input.
  • Measured runtime matches the estimate from the power budget within the stated margin.

12. Engineering checklist

13. Further references

Related on FixTheRobot