Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pmoranga/c33363a14301dbb6a38224dc95d81a3a to your computer and use it in GitHub Desktop.
Save pmoranga/c33363a14301dbb6a38224dc95d81a3a to your computer and use it in GitHub Desktop.
Checking your Raspberry Pi's view of its power supply (sometimes it's not the wall-wart)

Checking your Raspberry Pi's view of its power supply

Sometimes it seems like the first (and sometimes only) advice you get offered for almost any problem with a Raspberry Pi is "check your power supply". You think something like:

"hey, I'm using an official power supply sold as being matched with my Pi so how can there be any problem?"

You look up the specs then stick a controlled load across your supply and confirm that it can deliver the required number of Watts.

Yet your problems persist…

The problem might be power but it might not be your "wall-wart" power supply. It's a subtle but important distinction.

Background

I've worked in I.T. for almost 50 years but I'm a late-comer to the Raspberry Pi world, beginning my journey with a Raspberry Pi 3B+ purchased in early 2019, both to get my feet wet and to run Octopi. The thing never worked right, usually stopping part way through a print job when it seemed to lose its USB connection to my 3D printer. I gave up and went back to transporting GCODE files via "sneakernet" using an SD card.

Then I came across PiHole. I dusted off the 3B+ and gave it another whirl. Still didn't work right - random network interface freezes which are pretty much the last thing you need from a DNS server. I installed PiHole on a MacMini and the 3B+ went back on the shelf.

Sometime later I was introduced to the wonders of Docker, took the plunge with a new Raspberry Pi 4B, and never looked back. I now have four Raspberry Pi 4Bs doing different things. They are rock solid, running for months at a time between occasional reboots, and they never ever give me a single moment's trouble.

The problematic Pi

But, back to the problematic Raspberry Pi 3B+. For the purposes of this gist:

  • Boots from SD and runs current 32-bit Bullseye.
  • Ethernet and WiFi both enabled.
  • Runs headless (SSH).
  • No peripherals. No keyboard. No screen. Nothing connected to USB ports.
  • Air-cooled (ie not running a fan).

Power supplies

According to the specs, a Raspberry Pi 3B+ needs a power supply capable of delivering 5.1 volts DC at 2.5 amps: 12.75 Watts.

I have a number of power supplies that meet this requirement. Some are "official" (with the Raspberry Pi Foundation logo), some are "third party". Here are some examples:

Symbol Type Sold for Volts Amps Watts Connector
A Official Zero2W 5.1 2.5 12.75 μ-USB
B Official 3B+ 5.1 2.5 12.75 μ-USB
C Official 4B 5.1 3.0 15.30 USB-C
D Third Party 3B+ 5.0 3.0 15.00 μ-USB

I connected each of those to an Atorch DL24P controlled load test unit, set to constant power mode drawing 12.8W (the DL24P only works to 1 decimal place so I rounded up to be conservative). Here are the results.

PSU Tests - Constant Power - 12.8W

Interpretation:

  • With no load, the official supplies offer 5.2V while the third party unit offers 5.0V.
  • Under load, the official supplies drop to 4.9V while the third party unit drops to 4.5V.
  • All PSUs can sustain a constant power test of 12.8 Watts.

Powering the Raspberry Pi 3B+

I connected each of the power supplies to the Raspberry Pi 3B+, with an Atorch USB tester placed inline to measure voltage and current draw. Each test started with the Pi switched off, then waited until the boot cycle was complete. Here are the results.

PSU Tests - Boot 3B+

Interpretation:

  • The official supplies stay over 5.0 volts while the third-party supply hovers around 4.9V.
  • The maximum current draw for any supply is the third-party unit: 1.01 amps (5.2 Watts max).

Whichever way you look at it, all four PSUs have demonstrated the capacity to deliver more than double the observed load presented by the Pi. There is plenty of head-room. Whatever ails the 3B+, it ain't any of these PSUs.

The problems

When I connect each of these supplies to my Raspberry Pi 3B+, the Pi seems to boot OK (I can login via SSH connecting to the Ethernet port) yet it exhibits weird problems with its WiFi interface bouncing.

Aside from connectivity issues, how do I know WiFi is misbehaving? See Do your Raspberry Pi's Network Interfaces freeze?. The isc-dhcp-fix.sh script running on this Pi keeps logging:

mmm dd hh:mm:ss hostname root: isc-dhcp-fix resetting wlan0

Why? Well, it turns out that the Pi is actually complaining about its power. How do I know that?

The vcgencmd_power_report.sh script

Sometimes, even though your power supply is proven to be within spec, there's a power problem within the Pi itself. The Pi actually knows about the problem but it's a little hard to get the Pi to tell you about it.

Enter the vcgencmd_power_report.sh script:

#!/usr/bin/env bash

SCRIPT=$(basename "$0")

# fetch status
STATUS=$(vcgencmd get_throttled | cut -d "=" -f 2)

# decode - https://www.raspberrypi.com/documentation/computers/os.html#get_throttled
echo "vcgencmd get_throttled ($STATUS)"
IFS=","
for BITMAP in \
   00,"currently under-voltage" \
   01,"ARM frequency currently capped" \
   02,"currently throttled" \
   03,"soft temperature limit reached" \
   16,"under-voltage has occurred since last reboot" \
   17,"ARM frequency capping has occurred since last reboot" \
   18,"throttling has occurred since last reboot" \
   19,"soft temperature reached since last reboot"
do set -- $BITMAP
   if [ $(($STATUS & 1 << $1)) -ne 0 ] ; then echo "  $2" ; fi
done

echo "vcgencmd measure_volts:"
for S in core sdram_c sdram_i sdram_p ; do printf '%9s %s\n' "$S" "$(vcgencmd measure_volts $S)" ; done

echo "Temperature: $(vcgencmd measure_temp)"

If you're reading this on a Windows machine, please remember to be careful when copying-and-pasting scripts. Unless you take precautions, Windows will add its CR+LF line-endings. If those extra CRs are still in the script when it gets onto your Pi, they will cause problems.

Example output:

  • The pattern when there are no voltage problems:

     $ vcgencmd_power_report.sh 
     vcgencmd get_throttled (0x0)
     vcgencmd measure_volts:
          core volt=1.3000V
       sdram_c volt=1.2500V
       sdram_i volt=1.2500V
       sdram_p volt=1.2250V
     Temperature: temp=36.5'C
    
  • The problem when a voltage problem is present at the moment when the script is run (quite rare to see this):

     $ vcgencmd_power_report 
     vcgencmd get_throttled (0x50005)
       currently under-voltage
       currently throttled
       under-voltage has occurred since last reboot
       throttling has occurred since last reboot
     vcgencmd measure_volts:
          core volt=1.2000V
       sdram_c volt=1.2500V
       sdram_i volt=1.2500V
       sdram_p volt=1.2250V
     Temperature: temp=35.9'C
    
  • The pattern when an historical voltage problem is being reported:

     $ vcgencmd_power_report.sh 
     vcgencmd get_throttled (0x50000)
       under-voltage has occurred since last reboot
       throttling has occurred since last reboot
     vcgencmd measure_volts:
          core volt=1.3000V
       sdram_c volt=1.2500V
       sdram_i volt=1.2500V
       sdram_p volt=1.2250V
     Temperature: temp=33.2'C
    

Either "currently under-voltage" or "under-voltage has occurred since last reboot" are the Pi complaining about its power supply.

The actual mechanism is the "currently under-voltage" flag is raised any time there's a voltage problem "now". That flag clears as soon as the voltage problem goes away. In my experience voltage problems are transient so it is quite rare to see that flag raised when you run this script.

The "under-voltage has occurred since last reboot" flag is set if the "currently under-voltage" flag has been raised at least once since the last reboot. It doesn't tell you when "currently under-voltage" was raised, nor how long the condition persisted, nor whether it was a single isolated incident or if voltage is constantly falling below the acceptable threshold.

The "currently throttled" and "throttling has occurred since last reboot" flags just seem to be a side-effects.

Drilling further

Power problems get logged in the system log so, once you become aware that your Pi is moaning about its power, you can drill down:

$ grep -a -e "hwmon" /var/log/syslog
Jun 13 12:04:44 octopi kernel: [   14.890311] hwmon hwmon1: Undervoltage detected!
Jun 13 12:05:04 octopi kernel: [   23.210275] hwmon hwmon1: Voltage normalised
Jun 13 12:06:04 octopi kernel: [   14.880886] hwmon hwmon1: Undervoltage detected!
Jun 13 12:06:08 octopi kernel: [   19.030895] hwmon hwmon1: Voltage normalised
Jun 13 12:06:39 octopi kernel: [   21.111151] hwmon hwmon1: Undervoltage detected!
Jun 13 12:06:43 octopi kernel: [   25.270833] hwmon hwmon1: Voltage normalised
Jun 13 12:15:57 octopi kernel: [   14.870727] hwmon hwmon1: Undervoltage detected!
Jun 13 12:16:19 octopi kernel: [   25.270719] hwmon hwmon1: Voltage normalised
Jun 13 12:23:58 octopi kernel: [   15.190883] hwmon hwmon1: Undervoltage detected!
Jun 13 12:24:02 octopi kernel: [   19.360622] hwmon hwmon1: Voltage normalised
Jun 13 12:32:14 octopi kernel: [   14.950919] hwmon hwmon1: Undervoltage detected!
Jun 13 12:32:30 octopi kernel: [   19.110952] hwmon hwmon1: Voltage normalised
Jun 13 12:32:32 octopi kernel: [   21.191212] hwmon hwmon1: Undervoltage detected!
Jun 13 12:32:36 octopi kernel: [   25.350996] hwmon hwmon1: Voltage normalised
Jun 13 12:40:58 octopi kernel: [   14.800489] hwmon hwmon1: Undervoltage detected!
Jun 13 12:41:13 octopi kernel: [   18.950614] hwmon hwmon1: Voltage normalised
Jun 13 12:41:19 octopi kernel: [   25.190489] hwmon hwmon1: Undervoltage detected!
Jun 13 12:41:23 octopi kernel: [   29.350686] hwmon hwmon1: Voltage normalised
Jun 13 12:51:23 octopi kernel: [   14.810334] hwmon hwmon1: Undervoltage detected!
Jun 13 12:51:27 octopi kernel: [   18.980349] hwmon hwmon1: Voltage normalised

Monitoring the power situation

Two more scripts on a similar theme:

  1. A watchdog that will log any under-voltage events via MQTT. This is more a set-and-forget solution for all your Pis. With this in place, you'll be alerted to possible power problems when they occur:

    • sample crontab entry:

       */60 *    *    *    *    under_voltage_check.sh
      
    • script named under_voltage_check.sh in PATH:

       #!/usr/bin/env bash
      
       SCRIPT=$(basename "$0")
       BROKER="mqtt.domain.com"
       TOPIC="/raspberrypi/status"
      
       # fetch status
       STATUS=$(vcgencmd get_throttled | cut -d "=" -f 2)
      
       # redirect output to a log file
       LOGS="$HOME/Logs"
       LOGFILE="$LOGS/$SCRIPT.log"
       mkdir -p "$LOGS"
       touch "$LOGFILE"
       exec >> "$LOGFILE"
       exec 2>> "$LOGFILE"
      
       # has the undervoltage condition occurred since last reboot?
       if [ $(($STATUS & 1 << 16)) -ne 0 ] ; then
          mosquitto_pub -h "$BROKER" -t "$TOPIC" -m "{\"host\": \"$HOSTNAME\", \"underVoltage\": \"historical\"}"
       fi
      

      Edit the script so the BROKER variable points to your Mosquitto broker. If the Pi has noticed an under-voltage condition, this script will send an MQTT message to your broker. You can subscribe to the topic in Node-RED and use the event to trigger a notification.

      Keep in mind that the "under-voltage has occurred since last reboot" persists so, once one under-voltage condition has been noted, you'll get another MQTT message every hour (or however often you run this script from cron).

  2. A "live" watchdog will help you figure out the conditions under which power is an issue:

    • add this line to ~/.profile:

       watch_under_voltage.sh &
      
    • script named watch_under_voltage.sh in PATH:

       #!/usr/bin/env bash
      
       SCRIPT=$(basename "$0")
      
       while : ; do
      
          # fetch status
          STATUS=$(vcgencmd get_throttled | cut -d "=" -f 2)
      
          # is the pi sensing undervoltage right now?
          if [ $(($STATUS & 1 << 00)) -ne 0 ] ; then
             echo "reporting under-voltage NOW"
          fi
      
          sleep 1
      
       done
      
    • example:

       $ cd ~/IOTstack
       $ docker-compose up -d
       [+] Running 1/3
       [+] Running 2/3tack_default  Created 0.4s
       [+] Running 1/3tack_default  Created 0.4s
       [+] Running 1/3tack_default  Created 0.4s
       [+] Running 1/3tack_default  Created 0.4s
       [+] Running 3/3tack_default  Created 0.4s
        ⠿ Network iotstack_default  Created 0.4s
        ⠿ Container octoprint       Started 5.3s
        ⠿ Container portainer-ce    Started 5.3s
       reporting under-voltage NOW
       reporting under-voltage NOW
       reporting under-voltage NOW
       reporting under-voltage NOW
       reporting under-voltage NOW
       reporting under-voltage NOW
       reporting under-voltage NOW
       reporting under-voltage NOW
       reporting under-voltage NOW
       reporting under-voltage NOW
       reporting under-voltage NOW
       reporting under-voltage NOW
       reporting under-voltage NOW
       reporting under-voltage NOW
       reporting under-voltage NOW
       reporting under-voltage NOW
       reporting under-voltage NOW
       reporting under-voltage NOW
       $ docker-compose down
       [+] Running 0/0
       [+] Running 0/2toprint     Stopping 0.1s
       [+] Running 1/2toprint     Stopping 1.1s
       [+] Running 1/2toprint     Stopping 2.1s
       [+] Running 3/3toprint     Stopping 4.2s
        ⠿ Container octoprint       Removed 4.7s
        ⠿ Container portainer-ce    Removed 1.1s
        ⠿ Network iotstack_default  Removed 0.4s
       reporting under-voltage NOW
       reporting under-voltage NOW
      

      Clearly, bringing up Docker containers puts sufficient load on the 3B+ as to cause it to grizzle about lack of power.

      Bottom line: This 3B+ doesn't like running OctoPi or PiHole "native", and doesn't like running a couple of containers. Other than being an excellent test vehicle while writing this gist, it's really not all that much use.

Conclusion

The conventional one-size-fits-all wisdom that "it's yer dodgy power supply" might have a grain of truth but, sometimes, there might be a bit more to it. Your PSU might be fine. It could just be that you have a dodgy Raspberry Pi with an internal regulator that isn't up to the job being asked of it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment