我是初级python开发人员,主要是后端Django。我在树莓派上编写程序的第一个任务是将状态设置为LOW
,然后在5秒钟后将状态设置为HIGH
。
似乎不是问题,但是....我认为等待5秒更改为HIGH
的正确方法不是通过time.sleep()
,而是通过threading.Timer
(我在stackoverflow上发现了)...它将通过Web套接字连接,所以我认为一个线程必须侦听而另一个线程必须更改状态
我的问题是一半pythonic,一半raspberrian ...这是我的代码:
import RPi.GPIO as GPIO
from threading import Timer
from time import sleep
pin = 22
GPIO.setmode(GPIO.BCM)
GPIO.setup(pin, GPIO.OUT)
def set_high():
GPIO.output(pin, GPIO.HIGH)
def web_socket_loop():
GPIO.output(pin, GPIO.LOW)
t = Timer(5, set_high(GPIO))
t.start()
web_socket_loop()
GPIO.cleanup()
运行此代码时,状态发生了变化,但是几秒钟后,我也收到了错误消息:
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/local/lib/python3.7/threading.py", line 917, in _bootstrap_inner
self.run()
File "/usr/local/lib/python3.7/threading.py", line 1158, in run
self.function(*self.args, **self.kwargs)
TypeError: 'NoneType' object is not callable
我在堆栈上发现必须执行以下操作:(但无法正常工作):; /
t = Timer(5, set_high, args=[GPIO])
它确实修复了有关NoneType的错误...但是我遇到了另一个错误:
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/local/lib/python3.7/threading.py", line 917, in _bootstrap_inner
self.run()
File "/usr/local/lib/python3.7/threading.py", line 1158, in run
self.function(*self.args, **self.kwargs)
RuntimeError: Please set pin numbering mode using GPIO.setmode(GPIO.BOARD) or GPIO.setmode(GPIO.BCM)
我可能知道为什么会出现此错误,但不知道如何处理。我认为在另一个线程RPi.GPIO
上没有配置(GPIO.setmode(GPIO.BCM), GPIO.setup(pin, GPIO.OUT))
这就是为什么我将GPIO
作为变量传递给函数set_high(GPIO)
,而没有在另一个线程上传递它的原因,它认为RPi
没有配置……传递此变量很酷,但是。 ..我遇到了NoneType
错误...; /
当我尝试使用Timer(5, set_high, args=[GPIO])
进行第二种方法时,NoneType
错误消失了,但又出现了另一种(RuntimeError with info about pin setup
)...这是我未通过{时遇到的错误{1}}到这样的功能:
GPIO
将GPIO变量传递到另一个线程的正确方法是什么?这样才能正确识别此变量并将引脚22设置为HIGH。
或者,也许您建议尝试其他方法?也许睡眠更好?但是它将通过Web套接字连接,所以我认为一个人必须收听,而另一个必须更改状态?
感谢您的帮助!
答案 0 :(得分:0)
您的第一个问题和第三个问题确实无关紧要,因为您已经正确解决了它们。
当您调用137 received temperature: 18.74616
Client giving another request
Client giving another request
Client giving another request
Client giving another request
Client giving another request
Client giving another request
Client giving another request
Client giving another request
137 complete
137 received temperature: 20.03226
Client giving another request
Client giving another request
Client giving another request
Client giving another request
Client giving another request
Client giving another request
Client giving another request
Client giving another request
Client giving another request
Client giving another request
137 complete
137 received temperature: 21.4471
时,它会立即调用Timer(5, set_high(GPIO))
,并将返回的任何内容作为目标函数传递给set_high(GPIO)
进行调用。由于它会在5秒后返回Timer
,因此您的None
会尝试调用Timer
作为函数,因此会调用None
。
此修复程序正是您已经完成的操作:
TypeError
现在,一旦解决此问题,请仔细考虑您所要求的控制流程。
首先,您要执行以下操作:
Timer(5, set_high, [GPIO])
然后您呼叫GPIO.setmode(GPIO.BCM)
GPIO.setup(pin, GPIO.OUT)
,它会这样做:
web_socket_loop
然后它创建并启动GPIO.output(pin, GPIO.LOW)
,然后返回。然后执行此操作:
Timer
然后,五秒钟后,计时器关闭并调用您的GPIO.cleanup()
函数,该函数将执行以下操作:
set_high
清理完GPIO后,无法将引脚设置为高电平。
该错误消息有点令人误解:
GPIO.output(pin, GPIO.HIGH)
这是因为状态后清理与状态预初始化相同,因此它假定您的问题是尚未通过调用RuntimeError: Please set pin numbering mode using GPIO.setmode(GPIO.BOARD) or GPIO.setmode(GPIO.BCM)
来初始化事物。
您该如何解决?完成操作后,主线程才应该尝试清理。
通常,您还有其他要做的主线程工作。这就是为什么您使用setmode
或Timer
或某种其他形式的并发的原因。但是当您这样做时,您需要给主线程某种方式来等待该后台工作完成,或者您需要找到某种方式进行链接,以使Thread
仅在最后一个线程是使用GPIO完成。
添加用于处理通过Websocket通信的代码时,您需要执行其中一项操作。但是不可能在不知道如何计划组织代码的情况下向您展示您应该做什么。
同时,您实际上只需要等待5秒钟即可完成其他工作,因此不需要任何并发性。只是cleanup
:
sleep