如何使用Python在Raspberry Pi 3上通过GPIO控制风扇?

3

我正在尝试编写一个简单的脚本,它将告诉风扇(插在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)

当我运行这个命令时,它似乎已经在运行,但即使温度还远没有达到我设定的水平,风扇也不会停止运转,或者它告诉我该引脚已经被占用,但无论如何风扇仍然持续运转。

无论如何,风扇仍然会运转,而不考虑当前温度。

vgencmd 返回值如下: temp-37.0'C

我应该如何去掉非数字字符,以便只剩下一个整数?当我执行它时,得到的结果如下:

ValueError: invalid literal for int() with base 10: "temp=37.6'C\n"

注意:一些导入的模块目前还没有被使用,那就是它们存在的原因。

2
我不知道这是否会修复任何问题,但在比较之前,您需要将temp转换为int。尝试:if int(temp) > 65: 另外,您没有在循环中运行任何内容,因此它将执行一次并完成。尝试在while循环内执行最后5行(包括读取temp)并延迟约0.1秒。 - GRAYgoose124
1
这不是一个论坛,您不需要因为缺乏经验而道歉。我建议您简化您的问题,问您实际想要完成的任务,“如何在树莓派3上使用GPIO控制风扇”。 - Soviut
请查看我的更新,我添加了 measure_temp() - Jonathon Reinhart
1个回答

4

你很接近了。这两行代码有问题:

temp = os.popen('vcgencmd measure_temp').readline()

if temp > 65:

这里的temp是一个字符串。在尝试与整数进行比较之前,您需要将temp转换为整数。假设您正在读取的行仅是一个对应于某个温度的十进制字符串,您只需调用int(),如下所示:

temp = os.popen('vcgencmd measure_temp').readline()
temp = int(temp)

更新:鉴于你所发布的输出结果,我们可以使用正则表达式来匹配该输出结果。使用re 模块进行匹配。我们将把它放在一个函数中:

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)进行访问。
现在让我们把它放在一起。此外,当您的代码没有按预期工作时,包括一些“调试打印”非常有帮助,就像这样:
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)左右波动,你会发现你的代码会不断地开关风扇。为了解决这个问题,你可以在系统中添加一些滞后效应。例如,如果你将家用恒温器(加热)设置为 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)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接