使用 Raspberry Pi 和 PiFace Digital 中断
Interrupts with Raspberry Pi and PiFace Digital
我刚刚用 PiFace Digital element14 I/O 开发板设置了一个 Raspberry Pi。到目前为止,我已经按照几个步骤让它工作,这样我就可以连接 I/O 端口(控制 LED 并操作开关来做事)我写的 python 代码工作正常并且我可以让它做点什么。
目前我只是在闲逛,感受在 Pi 上编程的感觉,并试图了解这些功能。我想为一个简单的 6 位二进制计数器设置一个状态机,当我告诉它时,它会向上和向下计数,我可以很容易地做到这一点。但是当我试图将它提升到一个新的水平并使用中断来设置状态时,我 运行 遇到了问题。
我按照Manual as well as This Guide获取了激活中断的代码。
我写的代码执行没有错误,但是,要么没有检测到中断,要么它们什么都不做,我不确定是哪一个。我的代码如下。我知道 while 循环适用于 'waiting' 和 'counting' 状态,因为我可以定义初始条件。它计数正确,所以我很确定 while 循环没问题,只是没有状态变化。
import pifacedigitalio as pfio
import os
import time
def startCounter(event):
global state
state = 'counting'
print('counter started')
def stopCounter(event):
global state
state = 'waiting'
def stopProg(event):
global state
state = 'stop'
def resetCounter(event):
global state
state = 'reset'
def setLEDs(stateArray):
i = 0
for state in stateArray:
pfio.digital_write(i,state)
i = i + 1
def calcBools(count):
binString = bin(count).rsplit('0b')[1]
stringLength = len(binString)
zeroString = '0' * (8 - stringLength)
newString = zeroString + binString
i = 0
boolsOut = [0,0,0,0,0,0,0,0]
for bit in newString:
if bit == '1':
boolsOut[i] = 1
i = i + 1
return boolsOut
####################
### MAIN PROGRAM ###
####################
pfio.init()
pifacedigital = pfio.PiFaceDigital()
listener = pfio.InputEventListener(chip=pifacedigital)
signalDirection = pfio.IODIR_RISING_EDGE
listener.register(0, signalDirection, stopProg)
listener.register(1, signalDirection, startCounter)
listener.register(2, signalDirection, stopCounter)
listener.register(3, signalDirection, resetCounter)
listener.activate()
counter = 0
running = True
state = 'waiting'
setLEDs([0,0,0,0,0,0,0,0])
direction = 'up'
while(running):
if state == 'stop':
running = False
listener.deactivate()
counter = 0
elif state == 'waiting':
time.sleep(1)
print('waiting...')
elif state == 'counting':
if direction == 'up':
counter = counter + 1
else:
counter = counter - 1
if counter > 63:
direction = 'down'
elif counter == 0:
direction = 'up'
elif state == 'reset':
counter = 0
else:
time.sleep(0.1)
setLEDs(calcBools(counter))
print(counter)
time.sleep(0.25)
所以这段代码不起作用,我尝试了一些使用 pifacecommon 库也不起作用的东西,将一些代码行替换为:
import pifacecommon as pfc
readport = pfc.mcp23s17.GPIOA # I also tried GPIOB to no avail
listener = pfc.interrupts.PortEventListener(readport, 0)
在此之后,两种方法的侦听器命令是相同的。与此同时,我尝试使用 pfc.mcp23s17.write 命令,但显然它不存在或类似的愚蠢借口。
在此先感谢您阅读本文,如果您有回复就更要感谢,如果您有答案就更要感谢!
-本
编辑(已解决):我的回答在我一直提供的第 2 个 link 的评论中 :( 结果我写的一切都正确,我只需要 运行 文件来自终端而不是 IDLE3。
所以我的问题的答案在我一直提供的 2nd link 的评论中。我需要做的只是 运行 来自终端的程序,而不是 IDLE3。
我认为原因在于 Linux 中中断的处理方式。 Linux ISR 不是真正的 ISR,处理器将 ISR 置于睡眠模式,直到它被调用。谁能详细说说为什么IDLE3不支持中断?
我刚刚用 PiFace Digital element14 I/O 开发板设置了一个 Raspberry Pi。到目前为止,我已经按照几个步骤让它工作,这样我就可以连接 I/O 端口(控制 LED 并操作开关来做事)我写的 python 代码工作正常并且我可以让它做点什么。
目前我只是在闲逛,感受在 Pi 上编程的感觉,并试图了解这些功能。我想为一个简单的 6 位二进制计数器设置一个状态机,当我告诉它时,它会向上和向下计数,我可以很容易地做到这一点。但是当我试图将它提升到一个新的水平并使用中断来设置状态时,我 运行 遇到了问题。
我按照Manual as well as This Guide获取了激活中断的代码。
我写的代码执行没有错误,但是,要么没有检测到中断,要么它们什么都不做,我不确定是哪一个。我的代码如下。我知道 while 循环适用于 'waiting' 和 'counting' 状态,因为我可以定义初始条件。它计数正确,所以我很确定 while 循环没问题,只是没有状态变化。
import pifacedigitalio as pfio
import os
import time
def startCounter(event):
global state
state = 'counting'
print('counter started')
def stopCounter(event):
global state
state = 'waiting'
def stopProg(event):
global state
state = 'stop'
def resetCounter(event):
global state
state = 'reset'
def setLEDs(stateArray):
i = 0
for state in stateArray:
pfio.digital_write(i,state)
i = i + 1
def calcBools(count):
binString = bin(count).rsplit('0b')[1]
stringLength = len(binString)
zeroString = '0' * (8 - stringLength)
newString = zeroString + binString
i = 0
boolsOut = [0,0,0,0,0,0,0,0]
for bit in newString:
if bit == '1':
boolsOut[i] = 1
i = i + 1
return boolsOut
####################
### MAIN PROGRAM ###
####################
pfio.init()
pifacedigital = pfio.PiFaceDigital()
listener = pfio.InputEventListener(chip=pifacedigital)
signalDirection = pfio.IODIR_RISING_EDGE
listener.register(0, signalDirection, stopProg)
listener.register(1, signalDirection, startCounter)
listener.register(2, signalDirection, stopCounter)
listener.register(3, signalDirection, resetCounter)
listener.activate()
counter = 0
running = True
state = 'waiting'
setLEDs([0,0,0,0,0,0,0,0])
direction = 'up'
while(running):
if state == 'stop':
running = False
listener.deactivate()
counter = 0
elif state == 'waiting':
time.sleep(1)
print('waiting...')
elif state == 'counting':
if direction == 'up':
counter = counter + 1
else:
counter = counter - 1
if counter > 63:
direction = 'down'
elif counter == 0:
direction = 'up'
elif state == 'reset':
counter = 0
else:
time.sleep(0.1)
setLEDs(calcBools(counter))
print(counter)
time.sleep(0.25)
所以这段代码不起作用,我尝试了一些使用 pifacecommon 库也不起作用的东西,将一些代码行替换为:
import pifacecommon as pfc
readport = pfc.mcp23s17.GPIOA # I also tried GPIOB to no avail
listener = pfc.interrupts.PortEventListener(readport, 0)
在此之后,两种方法的侦听器命令是相同的。与此同时,我尝试使用 pfc.mcp23s17.write 命令,但显然它不存在或类似的愚蠢借口。
在此先感谢您阅读本文,如果您有回复就更要感谢,如果您有答案就更要感谢!
-本
编辑(已解决):我的回答在我一直提供的第 2 个 link 的评论中 :( 结果我写的一切都正确,我只需要 运行 文件来自终端而不是 IDLE3。
所以我的问题的答案在我一直提供的 2nd link 的评论中。我需要做的只是 运行 来自终端的程序,而不是 IDLE3。
我认为原因在于 Linux 中中断的处理方式。 Linux ISR 不是真正的 ISR,处理器将 ISR 置于睡眠模式,直到它被调用。谁能详细说说为什么IDLE3不支持中断?