如何使用 Python 在 Raspberry Pi 3 上通过 GPIO 控制风扇?
How can I control a fan with GPIO on a Raspberry Pi 3 using Python?
我正在尝试编写一个简单的脚本,告诉风扇(插入 GPIO 上的引脚 4)在特定温度下打开,如果温度更低,则关闭风扇。我从一些简单的东西开始,只是为了看看我是否可以根据温度控制风扇。这是我目前所拥有的:
import os
from time import sleep
import signal
import sys
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(4, GPIO.OUT)
temp = os.popen('vcgencmd measure_temp').readline()
if temp > 65:
GPIO.output(4, True)
else:
GPIO.output(4, False)
当我 运行 这个时,它要么看起来 运行 但是即使温度几乎没有达到我写的水平,风扇也没有关闭,或者它会告诉我该 pin 已在使用中,但它会继续使用。无论哪种方式,无论当前温度如何,风扇仍然 运行s。
vgencmd returns 为:
温度 37.0'C
如何删除非数字字符,使我只能使用 int?当我执行它时,我得到这个:
ValueError: invalid literal for int() with base 10: "temp=37.6'C\n"
注意:一些导入的模块尚未使用,这就是它们存在的原因。
你非常接近。这两行有问题:
temp = os.popen('vcgencmd measure_temp').readline()
if temp > 65:
这里,temp
是一个字符串。在尝试将其与整数进行比较之前,您需要将 temp
转换为整数。 假设您正在读取的行是只是一个对应于某个温度的十进制字符串,您只需调用int()
,如下所示:
temp = os.popen('vcgencmd measure_temp').readline()
temp = int(temp)
Update 由于您发布了您实际尝试解析的输出,我们可以使用正则表达式与 re
module 匹配输出。我们还将把它放在一个函数中:
def measure_temp():
raw = os.popen('vcgencmd measure_temp').readline()
m = re.match("temp=(\d+\.?\d*)'C", raw)
if not m:
raise ValueError("Unexpected temperature string: " + raw)
return float(m.group(1))
temp = measure_temp()
请注意,我在字符串中的实际温度小数点周围使用了 捕获组 ,并使用 m.group(1)
.
访问它
现在让我们把它放在一起。此外,当您的代码没有按照您的预期运行时,包含一些 "debug prints" 非常 非常 有帮助,例如:
def measure_temp():
raw = os.popen('vcgencmd measure_temp').readline()
m = re.match("temp=(\d+\.?\d*)'C", raw)
if not m:
raise ValueError("Unexpected temperature string: " + raw)
return float(m.group(1))
temp = measure_temp()
print 'Temperature from vcgencmd: {}'.format(temp)
if temp > 65:
print 'Turning on GPIO 4'
GPIO.output(4, True)
else:
print 'Turning off GPIO 4'
GPIO.output(4, False)
一旦掌握了基础知识,您还需要运行做一些其他事情:
您的脚本检查温度并切换 GPIO 一次。如果你想让这个东西像恒温器一样运行,你将需要使用 while
循环继续执行这些操作。
如果您的 while
循环 运行 非常快,并且温度在您的 设定值 (65) 附近波动,您会发现您的代码迅速转动风扇 on/off。向系统添加一点 hysteresis 可能会有所帮助。例如,如果您将家庭恒温器(暖气)设置为 70 度,它可能会在 69 度时打开,但会在 71 度时关闭。或者,如果它已经在最后 X 秒内改变了状态,它可能根本不会改变状态。
最简单的解决方案是 sleep()
在检查之间的短时间内:
while True: # Loop forever
# Read the current temperature
temp = os.popen('vcgencmd measure_temp').readline()
temp = int(temp)
print 'Temperature from vcgencmd: {}'.format(temp)
# Control the fan
if temp > 65:
print 'Turning on GPIO 4'
GPIO.output(4, True)
else:
print 'Turning off GPIO 4'
GPIO.output(4, False)
# Wait before the next iteration
time.sleep(5)
我正在尝试编写一个简单的脚本,告诉风扇(插入 GPIO 上的引脚 4)在特定温度下打开,如果温度更低,则关闭风扇。我从一些简单的东西开始,只是为了看看我是否可以根据温度控制风扇。这是我目前所拥有的:
import os
from time import sleep
import signal
import sys
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(4, GPIO.OUT)
temp = os.popen('vcgencmd measure_temp').readline()
if temp > 65:
GPIO.output(4, True)
else:
GPIO.output(4, False)
当我 运行 这个时,它要么看起来 运行 但是即使温度几乎没有达到我写的水平,风扇也没有关闭,或者它会告诉我该 pin 已在使用中,但它会继续使用。无论哪种方式,无论当前温度如何,风扇仍然 运行s。
vgencmd returns 为: 温度 37.0'C
如何删除非数字字符,使我只能使用 int?当我执行它时,我得到这个:
ValueError: invalid literal for int() with base 10: "temp=37.6'C\n"
注意:一些导入的模块尚未使用,这就是它们存在的原因。
你非常接近。这两行有问题:
temp = os.popen('vcgencmd measure_temp').readline()
if temp > 65:
这里,temp
是一个字符串。在尝试将其与整数进行比较之前,您需要将 temp
转换为整数。 假设您正在读取的行是只是一个对应于某个温度的十进制字符串,您只需调用int()
,如下所示:
temp = os.popen('vcgencmd measure_temp').readline()
temp = int(temp)
Update 由于您发布了您实际尝试解析的输出,我们可以使用正则表达式与 re
module 匹配输出。我们还将把它放在一个函数中:
def measure_temp():
raw = os.popen('vcgencmd measure_temp').readline()
m = re.match("temp=(\d+\.?\d*)'C", raw)
if not m:
raise ValueError("Unexpected temperature string: " + raw)
return float(m.group(1))
temp = measure_temp()
请注意,我在字符串中的实际温度小数点周围使用了 捕获组 ,并使用 m.group(1)
.
现在让我们把它放在一起。此外,当您的代码没有按照您的预期运行时,包含一些 "debug prints" 非常 非常 有帮助,例如:
def measure_temp():
raw = os.popen('vcgencmd measure_temp').readline()
m = re.match("temp=(\d+\.?\d*)'C", raw)
if not m:
raise ValueError("Unexpected temperature string: " + raw)
return float(m.group(1))
temp = measure_temp()
print 'Temperature from vcgencmd: {}'.format(temp)
if temp > 65:
print 'Turning on GPIO 4'
GPIO.output(4, True)
else:
print 'Turning off GPIO 4'
GPIO.output(4, False)
一旦掌握了基础知识,您还需要运行做一些其他事情:
您的脚本检查温度并切换 GPIO 一次。如果你想让这个东西像恒温器一样运行,你将需要使用 while
循环继续执行这些操作。
如果您的 while
循环 运行 非常快,并且温度在您的 设定值 (65) 附近波动,您会发现您的代码迅速转动风扇 on/off。向系统添加一点 hysteresis 可能会有所帮助。例如,如果您将家庭恒温器(暖气)设置为 70 度,它可能会在 69 度时打开,但会在 71 度时关闭。或者,如果它已经在最后 X 秒内改变了状态,它可能根本不会改变状态。
最简单的解决方案是 sleep()
在检查之间的短时间内:
while True: # Loop forever
# Read the current temperature
temp = os.popen('vcgencmd measure_temp').readline()
temp = int(temp)
print 'Temperature from vcgencmd: {}'.format(temp)
# Control the fan
if temp > 65:
print 'Turning on GPIO 4'
GPIO.output(4, True)
else:
print 'Turning off GPIO 4'
GPIO.output(4, False)
# Wait before the next iteration
time.sleep(5)