Power Supply#

The unregulated supply voltage of the motor hat, nominally 12V, supplies the motors. A 5V switching regulator powers the Raspberry PI and the STM32. It also adds “bush-button on/off control”: pressing SW1 pulls the enable pin of the regulator high, starting Raspberry PI and the STM32.

If pressed again, SHUT_SN goes low. This bin is monitored by the Raspberry PI which initiates a shutdown under software control and instructs the STM32 to pull PWR_EN low, turning off the supply.


Fig. 24 Robot power supply. Note: although the maximum input voltage of the 5V regulator is 24V, the TB6612 motor controller (which shares the same input rail) is limited to 15V.#

Figure 24 shows the schematic diagram of the 5V power supply for the Raspberry PI and the STM32.

Power Up#

The 12V supply is always available when the Lithium battery is connected. Initially, the 5V output is off (0V). Pressing button SW1 pulls the enable input (pin 4) of the regulator high through R1. Its output raises to 5V. After releasing the button, the enable input is kept high through resistor R3.

Power Down#

Powering down the robot requires support from both the Raspberry PI and the STM32. The code is in file

!cat $IOT_PROJECTS/robot/code/rpi/shutdown_monitor.py
Hide code cell output
#!/usr/bin/env python

# monitor shutdown button (GPIO13)
# sudo halt & turn off power when pressed

from iot_device.pydevice import Pydevice
from gpiozero import Button
from serial import Serial
import os, requests, time

# sudo shutdown (supervisor call)
def shutdown():
    supervisor_ip = os.getenv("BALENA_SUPERVISOR_ADDRESS")
    api_key = os.getenv("BALENA_SUPERVISOR_API_KEY")
    url = f"{supervisor_ip}/v1/shutdown?apikey={api_key}"
    headers = { 'Content-Type': 'application/json' }
    requests.post(url=url, headers=headers)

# run code on stm32
def exec_no_follow(cmd, dev='/dev/ttyAMA1'):
    with Serial(dev, 115200, timeout=0.5, write_timeout=2, exclusive= True) as serial:
        pyd = Pydevice(serial)
        while serial.in_waiting:
            data = serial.read(serial.in_waiting)
                data = data.decode()
            print(f"*** MCU: {data}")

# monitor pi poweroff pin (AUX=GPIO16) and cut 5V supply when low
def stm32_shutdown_monitor():
from pyb import Pin
from time import sleep

# wait for pi to signal it's down
power_off = Pin('AUX', mode=Pin.IN, pull=Pin.PULL_NONE)
while power_off.value() == 1:

# just for good measure

# declaring as input first sets the initial value after configuring as output
shut_dn = Pin('PWR_EN', mode=Pin.IN, pull=Pin.PULL_UP)
shut_dn = Pin('PWR_EN', mode=Pin.OUT_OD)

# power is cut - we are dead!

# callback when shutdown button pressed
def shut_down_pi():

# wait for MOTOR_HAT power button press (GPIO13) to initiate shutdown
with Button(13, pull_up=True, bounce_time=0.1) as shut_dn:
    shut_dn.when_pressed = shut_down_pi
    # do this forever
    while True:
        # print("napping ...")

It works as follows: The Raspberry PI monitors SHUT_DN (GPIO13). Once a button press is detected, first starts a program on the STM32 and then shuts down Linux.

The STM32 is responsible for turning off power. Since shutting down Linux takes some time, it needs and indication from the Raspberry PI that it is off. The AUX pin (GPIO16) is configured (dtoverlay) to go when the Raspberry PI is off and monitored by the STM32. After the pin goes low, the STM32 waits for a brief period and then pulls PWR_EN low, disabling the 5V supply and consequently cutting power to the Raspberry PI and the STM32.

The TB6612 motor controller still has 12V power but is configured such that it won’t turn on the motors without inputs from the STM32. Hence power drain from the Lithium battery is minimal after disabling the 5V regulator.