在树莓派中使用python进行GPIO输入的线程

问题描述 投票:0回答:1

树莓派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()
python multithreading raspberry-pi3
1个回答
0
投票

当你创建一个新的

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
的变量)。在某些时候,当您尝试引用该函数并发现实际上引用的是整数值时,这会导致令人惊讶的问题。
    

© www.soinside.com 2019 - 2024. All rights reserved.