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

时间:2017-01-24 03:48:00

标签: python raspberry-pi gpio raspberry-pi3

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

我如何删除非数字字符,以便我坚持使用int?当我执行它时,我得到了这个:

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

注意:某些导入的模块尚未使用,这就是它们存在的原因。

1 个答案:

答案 0 :(得分: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 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)访问它。

现在让我们把它放在一起。此外,当您的代码没有达到预期效果时,非常有助于包含一些“调试打印”,如下所示:

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)附近波动,您将会快速找到您的代码以打开/关闭风扇。向系统添加一点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)