Open dpbutler opened 10 years ago
I have seen this issue but I'm a bit busy at the moment. I'll get around to testing this later in the week.
Thanks for submitting a detailed report though, that really helps!
Hi Tom,
Is there any thing else I can do to help with this issue
Kind Regards,
Dave
In your first code example are you receiving events from PIFace Digital 0? Have you tried creating two event listeners, one for each PiFace Digital?
Hi Tom,
Tried the following code tonight with 4 PiFaces and got some really strange results. If i push a button I see no interrupt until I press another button on a different PiFace. When I push the second button the event is from the first button press. If I press two buttons on the same PiFace nothing happens but when I press a button on a different PiFace the event is from the first button press on the other PiFace.
I know this is very confusing and I wish I could explain better. Hopefully the following example is easier to understand:
***Push button 2 on PiFace 0
***Push button 0 on PiFace 2
You pressed button 2
***Push button 1 on PiFace 1
You pressed button 0
***Push button 1 on PiFace 0
You pressed button 1
***Push button 2 on PiFace 0
***Push button 3 on PiFace 1
You pressed button 1
***Push button 2 on PiFace 0
Deactivating listeners...
Listeners Deactivated
Seems the Pi is not seeing the interrupt pin until another PiFace raises it. Do you agree?
Code is...
import pifacedigitalio as p
import pifacedigitalio.version as pfdioV
import pifacecommon.version as pfcV
import time
quit = False
def print_flag(event):
print("You pressed button ", event.pin_num)
def stop_listening(event):
global quit
quit = True
p.init(0)
p.init(1)
p.init(2)
p.init(3)
print("pifacedigitalio version = ", pfdioV.__version__)
print("pifacecommon version = ", pfcV.__version__)
print("Creating l0")
pfd0 = p.PiFaceDigital(0)
l0 = p.InputEventListener(pfd0)
l0.register(0, p.IODIR_OFF, print_flag)
l0.register(1, p.IODIR_OFF, print_flag)
l0.register(2, p.IODIR_OFF, print_flag)
l0.register(3, p.IODIR_OFF, stop_listening)
print("Creating l1")
pfd1 = p.PiFaceDigital(1)
l1 = p.InputEventListener(pfd1)
l1.register(0, p.IODIR_OFF, print_flag)
l1.register(1, p.IODIR_OFF, print_flag)
l1.register(2, p.IODIR_OFF, print_flag)
l1.register(3, p.IODIR_OFF, stop_listening)
print("Creating l2")
pfd2 = p.PiFaceDigital(2)
l2 = p.InputEventListener(pfd2)
l2.register(0, p.IODIR_OFF, print_flag)
l2.register(1, p.IODIR_OFF, print_flag)
l2.register(2, p.IODIR_OFF, print_flag)
l2.register(3, p.IODIR_OFF, stop_listening)
print("Creating l3")
pfd3 = p.PiFaceDigital(3)
l3 = p.InputEventListener(pfd3)
l3.register(0, p.IODIR_OFF, print_flag)
l3.register(1, p.IODIR_OFF, print_flag)
l3.register(2, p.IODIR_OFF, print_flag)
l3.register(3, p.IODIR_OFF, stop_listening)
print("Activating l0...")
l0.activate()
print("Activating l1...")
l1.activate()
print("Activating l2...")
l2.activate()
print("Activating l3...")
l3.activate()
print("Waiting for buttons...")
while not quit:
time.sleep(1)
print("Deactivating listeners...")
l0.deactivate()
l1.deactivate()
l2.deactivate()
l3.deactivate()
print("Listeners Deactivated")
Really appreciate you taking the time to help on this.
Your explanation makes sense. This seems to be a problem with the interrupt queue in pifacecommon. I recall having a similar issue when I was testing but it disappeared somewhere. I think it has something to do with this function and it is on my todo list this week. In the mean time, if you have the time, you could litter that function with print statements and try to figure out what's going on.
Hi Tom,
I added the following print statements to the function you suggested:
while True:
# wait here until input
print("Waiting for port events on ", chip)
try:
print("Polling for event")
events = epoll.poll()
print("Got events")
except KeyboardInterrupt as e:
print("In KeyboardInterrupt")
if return_after_kbdint:
return
else:
raise e
except IOError as e:
print("In IOError")
# ignore "Interrupted system call" error.
# I don't really like this solution. Ignoring problems is bad!
if e.errno != errno.EINTR:
raise
# find out where the interrupt came from and put it on the event queue
if port == pifacecommon.mcp23s17.GPIOA:
print("Interrupt from GPIOA")
interrupt_flag = chip.intfa.value
else:
print("Interrupt not from GPIOA assume GPIOB")
interrupt_flag = chip.intfb.value
if interrupt_flag == 0:
print("interrupt_flag was 0")
continue # The interrupt has not been flagged on this board
else:
if port == pifacecommon.mcp23s17.GPIOA:
print("Interrupt value captured for GPIOA")
interrupt_capture = chip.intcapa.value
else:
print("Interrupt value captured for GPIOB")
interrupt_capture = chip.intcapb.value
print("Adding interrupt to queue")
event_queue.add_event(InterruptEvent(
interrupt_flag, interrupt_capture, chip, time.time()))
print("Interrupt_flag: ", interrupt_flag)
print("interrupt_capture: ", interrupt_capture)
print("Interrupt added to queue")
Prior to pressing any buttons I see this output
pifacedigitalio version = 3.0.2
pifacecommon version = 4.0.0
Creating l0
Creating l1
Creating l2
Creating l3
Activating l0...
Activating l1...
Activating l2...
Waiting for port events on <pifacedigitalio.core.PiFaceDigital object at 0xe29650>
Polling for event
Got events
Interrupt not from GPIOA assume GPIOB
Activating l3...
interrupt_flag was 0
Waiting for port events on <pifacedigitalio.core.PiFaceDigital object at 0xe29650>
Polling for event
Waiting for buttons...
Waiting for port events on <pifacedigitalio.core.PiFaceDigital object at 0xebbb50>
Polling for event
Got events
Interrupt not from GPIOA assume GPIOB
interrupt_flag was 0
Waiting for port events on <pifacedigitalio.core.PiFaceDigital object at 0xebbb50>
Polling for event
Waiting for port events on <pifacedigitalio.core.PiFaceDigital object at 0xed2910>
Polling for event
Got events
Interrupt not from GPIOA assume GPIOB
Waiting for port events on <pifacedigitalio.core.PiFaceDigital object at 0xefb670>
interrupt_flag was 0
Waiting for port events on <pifacedigitalio.core.PiFaceDigital object at 0xed2910>
Polling for event
Polling for event
Got events
Interrupt not from GPIOA assume GPIOB
interrupt_flag was 0
Waiting for port events on <pifacedigitalio.core.PiFaceDigital object at 0xefb670>
Polling for event
When I press the first button on a PiFace no output is printed
After one button press on one PiFace followed by another button on a different PiFace the following output is printed
Got events
Interrupt not from GPIOA assume GPIOB
Got events
Interrupt not from GPIOA assume GPIOB
Got events
Interrupt not from GPIOA assume GPIOB
Got events
Interrupt not from GPIOA assume GPIOB
Interrupt value captured for GPIOB
Interrupt value captured for GPIOB
interrupt_flag was 0
Waiting for port events on <pifacedigitalio.core.PiFaceDigital object at 0xebbb50>
Polling for event
interrupt_flag was 0
Waiting for port events on <pifacedigitalio.core.PiFaceDigital object at 0xe29650>
Polling for event
Adding interrupt to queue
Adding interrupt to queue
Interrupt_flag: 1
interrupt_capture: 254
Interrupt added to queue
Waiting for port events on <pifacedigitalio.core.PiFaceDigital object at 0xed2910>
Polling for event
Interrupt_flag: 1
interrupt_capture: 254
Interrupt added to queue
Waiting for port events on <pifacedigitalio.core.PiFaceDigital object at 0xefb670>
Polling for event
After pressing two buttons on a PiFace followed by one on a different PiFace the output is
Got events
Interrupt not from GPIOA assume GPIOB
Got events
Interrupt not from GPIOA assume GPIOB
Got events
Interrupt not from GPIOA assume GPIOB
Got events
Interrupt not from GPIOA assume GPIOB
interrupt_flag was 0
Waiting for port events on <pifacedigitalio.core.PiFaceDigital object at 0xefb670>
Polling for event
Interrupt value captured for GPIOB
Interrupt value captured for GPIOB
Adding interrupt to queue
Interrupt_flag: 1
interrupt_capture: 254
Adding interrupt to queue
interrupt_flag was 0
Waiting for port events on <pifacedigitalio.core.PiFaceDigital object at 0xed2910>
Polling for event
Interrupt added to queue
Waiting for port events on <pifacedigitalio.core.PiFaceDigital object at 0xebbb50>
Polling for event
Interrupt_flag: 2
interrupt_capture: 255
Interrupt added to queue
Waiting for port events on <pifacedigitalio.core.PiFaceDigital object at 0xe29650>
Polling for event
You pressed button 1
It seems this function is operating correctly I think. Is this many iterations common if multiple PiFaces are used? I will try tomorrow with one PiFace only and with Multiple PiFaces but only one listener, if you think this will help?
Is the problem likely to be in the epoll.poll()? This does not seem to be returning for the first button press.
Hi Tom,
Done some further testing.
With four PiFaces connected and one listener for Interrupts on first PiFace only I see the following and regardless of what buttons I press I get no further output.
pi@pitest ~ $ python3 inttest.py
pifacedigitalio version = 3.0.2
pifacecommon version = 4.0.0
Creating l0
Activating l0...
Waiting for buttons...
Waiting for port events on <pifacedigitalio.core.PiFaceDigital object at 0x17b7cb0>
Polling for event
Got events
Interrupt not from GPIOA assume GPIOB
Interrupt value captured for GPIOB
Adding interrupt to queue
Interrupt_flag: 255
interrupt_capture: 255
Interrupt added to queue
Waiting for port events on <pifacedigitalio.core.PiFaceDigital object at 0x17b7cb0>
Polling for event
If I have only 1 PiFace connected I see the following before pressing any buttons:
pi@pitest ~ $ python3 inttest.py
pifacedigitalio version = 3.0.2
pifacecommon version = 4.0.0
Creating l0
Activating l0...
Waiting for buttons...
Waiting for port events on <pifacedigitalio.core.PiFaceDigital object at 0x2120cb0>
Polling for event
Got events
Interrupt not from GPIOA assume GPIOB
Interrupt value captured for GPIOB
Adding interrupt to queue
Interrupt_flag: 255
interrupt_capture: 255
Interrupt added to queue
Waiting for port events on <pifacedigitalio.core.PiFaceDigital object at 0x2120cb0>
Polling for event
After I press button 1 I get this:
Got events
Interrupt not from GPIOA assume GPIOB
Interrupt value captured for GPIOB
Adding interrupt to queue
Interrupt_flag: 1
interrupt_capture: 254
Interrupt added to queue
Waiting for port events on <pifacedigitalio.core.PiFaceDigital object at 0xb00cb0>
Polling for event
Got events
Interrupt not from GPIOA assume GPIOB
Interrupt value captured for GPIOB
Adding interrupt to queue
Interrupt_flag: 1
interrupt_capture: 255
Interrupt added to queue
Waiting for port events on <pifacedigitalio.core.PiFaceDigital object at 0xb00cb0>
Polling for event
You pressed button 0
After button 2:
Got events
Interrupt not from GPIOA assume GPIOB
Interrupt value captured for GPIOB
Adding interrupt to queue
Interrupt_flag: 2
interrupt_capture: 253
Interrupt added to queue
Waiting for port events on <pifacedigitalio.core.PiFaceDigital object at 0xb00cb0>
Polling for event
Got events
Interrupt not from GPIOA assume GPIOB
Interrupt value captured for GPIOB
Adding interrupt to queue
Interrupt_flag: 2
interrupt_capture: 255
Interrupt added to queue
Waiting for port events on <pifacedigitalio.core.PiFaceDigital object at 0xb00cb0>
Polling for event
You pressed button 1
After button 3
Got events
Interrupt not from GPIOA assume GPIOB
Interrupt value captured for GPIOB
Adding interrupt to queue
Interrupt_flag: 4
interrupt_capture: 251
Interrupt added to queue
Waiting for port events on <pifacedigitalio.core.PiFaceDigital object at 0xb00cb0>
Polling for event
Got events
Interrupt not from GPIOA assume GPIOB
Interrupt value captured for GPIOB
Adding interrupt to queue
Interrupt_flag: 4
interrupt_capture: 255
Interrupt added to queue
Waiting for port events on <pifacedigitalio.core.PiFaceDigital object at 0xb00cb0>
Polling for event
You pressed button 2
After button 4:
Got events
Interrupt not from GPIOA assume GPIOB
Interrupt value captured for GPIOB
Adding interrupt to queue
Interrupt_flag: 8
interrupt_capture: 247
Interrupt added to queue
Waiting for port events on <pifacedigitalio.core.PiFaceDigital object at 0xb00cb0>
Polling for event
Got events
Interrupt not from GPIOA assume GPIOB
Interrupt value captured for GPIOB
Adding interrupt to queue
Interrupt_flag: 8
interrupt_capture: 255
Interrupt added to queue
Waiting for port events on <pifacedigitalio.core.PiFaceDigital object at 0xb00cb0>
Polling for event
Deactivating listeners...
Listeners Deactivated
pi@pitest ~ $
Is there any reason why I get two events for each button press? Does it matter? I'm guessing my earlier prognosis that the issue is in epoll.poll() is still correct?
I have a similar issue with two boards. Only getting interrupts on the first board, and randomly on 2nd. Any progress with this issue? How should be the boards connected, is PiRack the only feasible option?
Hi all,
I am having a problem with interrupts when using multiple PiFace boards. I have a Model A Pi connected to multiple PiFace boards via a PiFace Rack.
If I have only 1 PiFace connected I can receive interrupts fine. Once I connect a second PiFace with different hardware address my interrupts are no longer received.
I have tried receiving interrupts using pifacecommon and pifacedigitalio methods.
pifacedigitalio test code is as follows
pifacecommon test code is
Not sure if I am missing something or if there is an issue. I have tried on multiple PIs using multiple PiFaces.