Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save Paraphraser/17fb6320d0e896c6446fb886e1207c7e to your computer and use it in GitHub Desktop.
Save Paraphraser/17fb6320d0e896c6446fb886e1207c7e 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. One easy way to ensure that the line-endings are correct is to use the dos2unix command.

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.

@FedericoHeichou
Copy link

I think I would pay more attention to the "under-voltage has occurred since last reboot" because that tells you it is still happening.

Is this a Pi3 or 4 or Zero or ... ?

In my case, the Pi3 was obviously "bad". I can't say whether it was always bad or just went bad over time. Whatever the cause, the power supply was not to blame. More likely the on-board regulator (a guess).

If you have a "genuine" power supply or can borrow one to test with and the problem goes away then you can probably conclude your "unofficial" supply has gone bad. If the problem doesn't go away then I think that makes your Pi going bad the more likely explanation.

Sure I have to check, probably it is. Now the message in syslog appears one time per hour, not fixed because obviously it's not a software problem, but at least now should work longer

@Bagunceiro
Copy link

Bagunceiro commented Feb 22, 2023

Very useful thanks. Used a lot of this once I found out how to convert DOS to Unix. Notepad++ to the rescue

dos2unix (or unix2dos if you want to go the other way) on the pi (or any Unix like) is your friend here.

@Paraphraser
Copy link
Author

Paraphraser commented Feb 22, 2023

Glad it helped. Agree on dos2unix as a handy tool. And, as of 2024-11-13 I've done what I should've done ages ago and added a hint about dos2unix to the main gist.

@aeberbach
Copy link

Nice explanation. I have a Pi 4 running from a lab power supply, voltage measured at the Pi (not at the supply) is 5.0V. Still endless "Undervoltage detected!" - I can dig in further with this information.

@Paraphraser
Copy link
Author

I'd be really interested in what you find.

I've only ever seen this on a 3B+ so if Pi 4 models can be affected by this same problem, it's scary.

I've got half a dozen 4s, all running the under_voltage_check.sh script via cron every hour. Never had a single MQTT message from any of them.

How old is your Pi? If it's new-ish, I think I'd be complaining to the supplier. A supplier would be pretty hard pressed to argue against the Pi itself being faulty if you should show the problem with both an official PSU and a lab supply - and it was the Pi itself reporting via vcgencmd.

In the case of my 3B+ (which has now gone to recycling), by the time I figured this out it was years down the track so it was pointless going back to the supplier and saying "hey". Also, the supplier was AliExpress and I really had no idea whether the unit was genuine or otherwise. Lesson learned!

@jouellnyc
Copy link

+1 - Google brought me here with a new pi zero. Tremendous.

@nImEHuntet
Copy link

First and foremost, I'd like to thank you for the excellent documentation and the explanation you provided on this topic.
True, it is not always the wall wart, but neither is it always the RPI.
In my case, I narrowly avoided throwing away my RPI 4B by simply changing the power cable.
And voilà! The issue was resolved.

@Paraphraser
Copy link
Author

That's a very good point. I've also suddenly had Ethernet cables go bad. You glare at the cable and think, "but it's cable-tied in place and never moves so how can it possibly go bad?" But they do.

And then there was the time an Ethernet switch went all stupid - forwarding at 1gbps in one direction, 5kbps the other. That went to the great eRecycling bin in the sky.

Meanwhile, I have a Pi4 that was working mostly OK in a passive-cooled aluminium case but would occasionally heat throttle so I decided to move it into an active-cooled case. Heat throttling issues disappeared but it started moaning about insufficient voltage. Take it out of the case, problem gone. Back in the case problem recurs. Switch power supplies. No difference. Give it a Pi5 PSU (plenty Watts). No difference. Doesn't matter whether the temp is high enough to trigger the fan or cool enough the fan is idle. It was strictly a boot-time issue with the "problem happening now" never showing up at runtime even if I manually triggered the fan. No signs of anything wonky on the practical test of, "is it actually doing the data-processing job being asked of it?" In the end I just turned off the voltage checking and ignored it.

It's always something!

@adamantivm
Copy link

This post and thread is a masterclass in explanation. @Paraphraser it's 25 years too late for me but I wish you were my computer science teacher.
I'm in the middle of a wild goose chase of the root cuase of the infamous "undervoltage detected" issue which is hanging my beloved home assistant RPI 3b+ randomly. This gives me what I need to stay entertained trying to catch the issue a bit longer before giving up and moving to a RPI 4.
Thanks truly.

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