树莓派GPIO引脚中线程的疑问
我自己在研究差速驱动机器人的编码器,我需要同时使用两个编码器读取车轮的速度和位置。我在 python 中使用了线程库,尽管我只启动了这两个函数,但只启动了第一次运行时启动的函数,而第二次运行时则没有启动。我不确定问题是什么,在树莓派 3b 的 gpio 引脚中使用线程时有什么需要注意的吗,如果是的话请帮忙并提出解决方案。
from threading import Thread
import RPi.GPIO as GPIO
import time
import datetime
def encoder_right(t1):
...
def encoder_left(t1):
...
t1 = datetime.datetime.now()
Thread1 = Thread(target = encoder_right(t1),daemon = True)
Thread2 = Thread(target = encoder_left(t1),daemon = True)
Thread1.start()
Thread2.start()
Thread1.join()
Thread1.join()
当你创建一个新的
threading.Thread
对象时,你需要将一个函数传递给target
参数。在您的代码中,您不是传递函数对象,而是“调用”函数。也就是说,当你写:
Thread1 = Thread(target=encoder_right(t1), daemon=True)
您正在打电话
encoder_right(t1)
;您的代码永远不会超出这一点,因为您已经进入了无限循环。您永远不会创建线程,也永远不会到达此代码之后的行。
Thread1 = Thread(target=encoder_right, args=(t1,), daemon=True)
Thread2 = Thread(target=encoder_left, args=(t1,), daemon=True)
这样,您就可以在
target
参数中传递函数对象,而
Thread
对象将负责在新线程中启动该函数。
与你的问题无关,但你只需要在程序中调用一次GPIO.setmode(GPIO.BCM)
和
GPIO.setwarnings(False)
;您不需要在每个线程中调用它。也就是说,你可以这样写:def encoder_right(t1):
...
def encoder_left(t1):
...
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
t1 = datetime.datetime.now()
Thread1 = Thread(target=encoder_right, args=(t1,), daemon=True)
Thread2 = Thread(target=encoder_left, args=(t1,), daemon=True)
Thread1.start()
Thread2.start()
Thread1.join()
Thread2.join()
还有!我会避免给变量赋予与函数相同的名称(例如,在函数
encoder_left
中,你还有一个名为
encoder_left
的变量)。在某些时候,当您尝试引用该函数并发现实际上引用的是整数值时,这会导致令人惊讶的问题。