树莓派用起来还是很方便的,不过因为电源适配器电压不足、额定电流不足、线损、PTC的压降 或者USB接口接触电阻等因素的影响,+5V电源输入电压不足时有发生。 当+5V电源输入电压不足时,显示屏的右上角会显示一个黄色的小闪电符号作为报警。 +5V电源输入电压不足会引起很多问题,比如运行不稳定,数据丢失,甚至会导致SD卡永久损坏。 使用一个优质的、足功率、足电压的电源适配器是必须的。但即使我们使用官方电源适配器,偶尔也会因为micro USB口长期反复插拔后,导致接触不良而引起接触电阻过高,使得树莓派+5V输入电压不足。 于是我们需要有能够实时监测树莓派电压不足(Under-voltage)的方法,以便能够在所开发的应用中及时报警,或者采取相应行动。
原理
Raspberry Pi OS 中的命令 vcgencmd get_throttled 会得到一个十六进制数,这个数字反映了和当前系统频率、输入电压等相关的状态信息
$ vcgencmd get_throttled
throttled=0x50005
这个数字转换为二进制后,其中的8位,代表了8个标志的状态,我们重点看其中的两位:
- 这个数字的第 0 位为 1 的话,表明当前发生了输入电压不足的情况;
- 这个数字的第 16 位为 1 的话,表明启动之后曾经发生过输入电压不足的情况;
那我们只要实时检测这两个标志位,就可以监测到树莓派输入电压不足的情况。
Python 的 vcgencmd
幸运的是,python的第三方库中,有现成的库可以用来访问上面的标志位,它就是 vcgencmd 库。
安装 vcgencmd 库
sudo pip3 install vcgencmd -i https://mirrors.aliyun.com/pypi/simple/
安装后,在python中尝试导入 vcgencmd 库,没有报错就对了。
pi@raspberrypi:~ $ python3
Python 3.7.3 (default, Jul 25 2020, 13:03:44)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from vcgencmd import Vcgencmd
代码
因为实现起来比较简单,直接上代码了:(可按需要根据如下代码调整优化后,用于实现自己的需求)
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# cython: language_level=3
#Flag Bits
UNDERVOLTED = '0'
CAPPED = '1'
THROTTLED = '2'
SOFT_TEMPLIMIT = '3'
HAS_UNDERVOLTED = '16'
HAS_CAPPED = '17'
HAS_THROTTLED = '18'
HAS_SOFT_TEMPLIMIT = '19'
from vcgencmd import Vcgencmd
from colorama import init
from colorama import Fore, Back, Style
import time
init(autoreset=True)
vcgm = Vcgencmd()
def print_log(flag, info):
if flag:
print(Fore.RED + Style.BRIGHT + info, end = ' ')
else:
print(Fore.GREEN + Style.DIM + info, end = ' ')
while True:
print('[{}] '.format(time.strftime('%M:%S')), end = '')
output = vcgm.get_throttled()
flag = output['breakdown'][UNDERVOLTED]
print_log(flag, 'UNDERVOLTED')
flag = output['breakdown'][CAPPED]
print_log(flag, 'CAPPED')
flag = output['breakdown'][THROTTLED]
print_log(flag, 'THROTTLED')
flag = output['breakdown'][SOFT_TEMPLIMIT]
print_log(flag, 'SOFT_TEMPLIMIT')
flag = output['breakdown'][HAS_UNDERVOLTED]
print_log(flag, 'HAS_UNDERVOLTED')
flag = output['breakdown'][HAS_CAPPED]
print_log(flag, 'HAS_CAPPED')
flag = output['breakdown'][HAS_THROTTLED]
print_log(flag, 'HAS_THROTTLED')
flag = output['breakdown'][HAS_SOFT_TEMPLIMIT]
print_log(flag, 'HAS_SOFT_TEMPLIMIT')
print()
time.sleep(1)
#EOF
测试
测试环境: 树莓派 3B + Raspbian Buster
在我的一个micro USB电源插座接触不良的树莓派3B上运行上面的脚本,得到如下结果:
其中,红色信息表明检测到相关标志位为1的情况。可以看到,红色的 UNDERVOLTED 说明输入电压过低了,红色的 THROTTLED 表明系统工作频率被强制降低了,而红色的 HAS_UNDERVOLTED 说明曾经检测到电压过低的情况,红色的 HAS_THROTTLED 说明曾经被降频。
于是我将 5.2V2.5A 电源直接跳过micro USB接口接到了40-pin插针的 第2脚 和 第6脚,然后测试,结果如下:
没有红色信息了,说明并没有检测到异常。 试验结束。
参考资料
https://pinout.xyz/
https://www.raspberrypi.org/documentation/raspbian/applications/vcgencmd.md
https://www.raspberrypi.org/documentation/hardware/raspberrypi/frequency-management.md
https://jamesachambers.com/measure-raspberry-pi-undervoltage-true-clock-speeds/
https://www.raspberrypi.org/forums/viewtopic.php?f=63&t=147781&start=50#p972790
https://rpi4cluster.com/scripts/undervoltage/
https://pypi.org/project/vcgencmd/
https://pypi.org/project/colorama/