首页 文章

如何使用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

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

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

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

1 回答

  • 4

    你很近 . 这两行是有问题的:

    temp = os.popen('vcgencmd measure_temp').readline()
    
    if temp > 65:
    

    这里, temp 是一个字符串 . 在尝试将 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) 访问它 .


    让's put it together now. Also, when your code isn' t做你期望的,包含一些"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)附近波动,您将会快速找到您的代码以打开/关闭风扇 . 向系统添加一点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)
    

相关问题