使用Python在Beaglebone中检测和比较GPIO事件

0 投票
1 回答
2033 浏览
提问于 2025-04-18 13:43

我正在尝试在Beaglebone Black上检测两个不同GPIO口的事件,然后判断哪个事件发生得更早。我使用的是Adafruit_BBIO.GPIO这个库,代码是用Python写的。现在这个代码运行得不太对,我也不知道为什么。以下是我的代码:

import sys
import thread
import time
from datetime import datetime
import bitarray
import Adafruit_BBIO.GPIO as GPIO

gpio_state = [0, 0]
gpio_time = [0, 0]
ir_recv = ['GPIO0_26', 'GPIO1_12']

def checkEvent(index):
    while True:
        if GPIO.event_detected(ir_recv[index]): 
            if (gpio_state[index] == 0):
                gpio_state[index] = 1
                gpio_time[index] = datetime.now()
                print ir_recv[index]
                time.sleep(5) # time to avoid rebounces

for gpio in ir_recv:
    GPIO.setup(gpio, GPIO.IN)
    GPIO.add_event_detect(gpio, GPIO.RISING)

try:
    thread.start_new_thread(checkEvent, (0, ) )
    thread.start_new_thread(checkEvent, (1, ) )
except:
    print "Error: unable to start thread"

while True:
    if (gpio_state[0] == 1) and (gpio_state[1] == 1):
        if gpio_time[0] > gpio_time[1]:
            print "1"
        if gpio_time[0] < gpio_time[1]:
            print "2"
        if gpio_time[0] == gpio_time[1]:
            print "???"
        gpio_state[0] = 0
        gpio_state[1] = 0
        gpio_time[0] = 0
        gpio_time[1] = 0

我没有收到任何错误信息。主要的问题是事件没有被正确比较,比如说虽然GPIO0_26的事件发生得比GPIO1_12的事件早(也就是说,gpio_time[0]比gpio_time[1]小),但是在最后的循环中输出却没有打印出“2”。有时候代码还会重复打印线程中的GPIO引脚。

提前感谢任何能帮助我找到解决方案的建议。

1 个回答

0

我推荐你使用 PyBBIO 这个工具(其实我是这个工具的作者)。它有一个中断的接口,基于 epoll(这是用来处理内核级别的中断信号的),这样会让事情变得简单很多。像下面这样应该就能解决问题(我还没测试过):

from datetime import datetime
from bbio import *

gpio_state = [0, 0]
gpio_time = [0, 0]
ir_recv = ['GPIO0_26', 'GPIO1_12']

def getInterrupt(index):
    gpio_time[index] = datetime.now()
    gpio_state[index] = 1
    print "received interrupt from {} at {}".fomrat(ir_recv[index],
                                                    gpio_time[index]
                                                    )

def setup():
    for i in range(len(ir_recv)):
      pinMode(ir_recv[i], INPUT, pull=-1)
      # The optional pull=-1 enables the internal pull-down resistor

    attachInterrupt(ir_recv[0], lambda: getInterrupt(0), RISING)
    attachInterrupt(ir_recv[1], lambda: getInterrupt(1), RISING)


def loop():
    # You can do other stuff here while you're waiting...
    delay(1000)

run(setup, loop)

另外,你要确保你的 PyBBIO 是最新版本,可以用下面的命令更新:

# pip install -U PyBBIO

撰写回答