我整天都在为此苦苦挣扎,我可以肯定这是一个线程问题,但我只是想不出什么问题。基本上,我的main.py创建了“ Neopixel”的实例。那个新像素启动了一条螺纹,该螺纹运行着一个led环。只要满足条件,某些环形动画就会一直运行,这与不会引起问题的简单的LED闪烁不同。
为了处理这些情况,我使用一个事件标志。当它是一个长动画时,它设置为true;当另一个led状态出现时,它未设置,因此从理论上讲,它应该像在while event.is_set()循环中那样停止动画。但是...即使我确实清除了它,也从未清除过。
某些代码:
def __init__(self):
self._logger = logging.getLogger('ProjectAlice')
self._logger.info('Initializing Project Alice')
self._leds = NeoPixels()
self._leds.onStart()
....
self._logger.info('Project Alice started')
self._leds.onConnecting()
self.greetAlice()
....
elif message.topic == self._SUB_GREETING_BACK:
self._state = State.REGISTERED
self._logger.info('- Alice greeted back, module registered')
self._leds.onConnected()
我已经删除了不相关的部分,但离开了led部分。如我们所见,它开始,创建Neopixels实例,为led调用onStart(),然后调用onConnect(),然后尝试通过mqtt到达主服务器。当主服务器答复时,我调用onConnected()。但是LED始终保持在“ onConnect()”状态,并且永远不会进入“ onConnected()”状态。那里有一个print('Done'),它永远不会显示,但是当我按ctrl-c程序时,它还会执行“ onConnected”动画
不知何故
self._animation.clear()
在
def onConnected(自身):
不注册,动画循环永远不会结束,但这
self._logger.info('-爱丽丝打招呼,模块已注册')
打印,意味着onConnected()被称为
NeoPixels类(对象):
def __init__(self):
self._running = True
self._ring = Adafruit_NeoPixel(num=config.settings['ringLedCount'], pin=config.settings['ringLedPin'], brightness=125, strip_type=ws.SK6812_STRIP_RGBW)
self._ring.begin()
self._queue = Queue.Queue()
self._animation = threading.Event()
threading.Thread(target=self._run).start()
def onStart(self):
self._running = True
self._animation.clear()
self._queue.put(self._start)
def onConnecting(self):
self._animation.clear()
self._queue.put(self._connecting)
def onConnected(self):
self._animation.clear()
self._queue.put(self._connected)
def _run(self):
while self._running:
func = self._queue.get()
func()
def _start(self):
for i in range(self._ring.numPixels()):
self._setPixelColorRGB(i, 255, 0, 0)
self._ring.show()
time.sleep(10 / 1000.0)
for i in range(self._ring.numPixels()):
self._setPixelColorRGB(i, 0, 0, 0)
self._ring.show()
time.sleep(10 / 1000.0)
time.sleep(0.25)
for i in range(self._ring.numPixels()):
self._setPixelColorRGB(i, 255, 0, 0)
self._ring.show()
time.sleep(1 / 1000.0)
def _connecting(self):
self._animation.set()
while self._animation.is_set():
for i in range(self._ring.numPixels()):
self._setPixelColorRGB(i, 255, 0, 0)
self._ring.show()
time.sleep(20 / 1000.0)
threading.Timer(interval=20 / 1000.0, function=self._setPixelColorRGB, args=[i, 0, 0, 0]).start()
print('done')
def _connected(self):
for i in range(self._ring.numPixels()):
self._setPixelColorRGB(i, 0, 128, 0)
self._ring.show()
time.sleep(1)
self._clear()
答案 0 :(得分:1)
这很像是您的队列出现计时问题。如果调用onConnected
之后对onConnecting
的调用发生得太快,则onConnected
在onConnecting
-> _connecting
设置事件之前清除事件。
这就是我剥离班级以运行和测试它的方式(我删除了所有LED环材料,并向onConnected
和_run
添加了打印语句)
import time, threading, queue
class NeoPixels:
def __init__(self):
self._running = True
self._queue = queue.Queue()
self._animation = threading.Event()
threading.Thread(target=self._run)
def onStart(self):
self._running = True
self._animation.clear()
self._queue.put(self._start)
def onConnecting(self):
self._animation.clear()
self._queue.put(self._connecting)
def onConnected(self):
print("called onConnected")
self._animation.clear()
self._queue.put(self._connected)
def _run(self):
while self._running:
func = self._queue.get()
print("now running {}".format(func.__qualname__))
func()
def _start(self):
time.sleep(.5)
def _connecting(self):
self._animation.set()
while self._animation.is_set():
for i in range(5):
time.sleep(20 / 1000.0)
print('done')
def _connected(self):
for i in range(1):
print("connected")
time.sleep(1)
这是我的运行方式:
leds = NeoPixels()
leds.onStart()
leds.onConnecting()
leds.onConnected()
以下是输出:
called onConnected
now running NeoPixels._start
now running NeoPixels._connecting
如您所见,onConnected
被调用并在_run
甚至从队列中提取_start
并对其进行处理之前清除事件。因此,在执行onConnecting
时,_connecting
会设置事件,并且由于此后没有任何清除操作,因此它将无限期地运行。
因此,更改onConnected
以等待队列清除,如下所示:
def onConnected(self):
while not self._queue.empty():
time.sleep(.1)
print("called onConnected")
self._animation.clear()
self._queue.put(self._connected)
将导致以下输出:
now running NeoPixels._start
now running NeoPixels._connecting
called onConnected
done
now running NeoPixels._connected
connected
出于好奇,您实际上如何终止/加入线程?您是匿名创建的,因此我看不到如何处理它才能将其关闭。