Open Freaksed opened 9 years ago
You mean the following code?
>>> import pifacecad
>>> cad = pifacecad.PiFaceCAD()
>>> listener = pifacecad.SwitchEventListener(chip=cad)
>>> listener.register(0, pifacecad.IODIR_RISING_EDGE, print)
>>> listener.activate()
I've just ran this on a fresh install of wheezy (after installing the python3-pifacecad
package) and when I press switch 0 I get a print out of data.
Are you still having this issue? Are you running the latest version of Raspbian?
Actually scratch that, I can't seem to get SwitchEventListener
/interrupts to work either. There appears to be a problem with epoll
. I'm going to dump what I have so far.
There is an MCP23S17 port expander on each PiFace product. For each port (A and B) there is an interrupt flag
register and an interrupt capture
register. The interrupt flag
register is set to 0b1
whenever an interrupt occurs and the port's value is put in the capture register. Let's test this with PiFace CAD:
>>> import pifacecad
>>> cad = pifacecad.PiFaceCAD()
>>> bin(cad.intfa.value)
0b0
>>> bin(cad.intcapa.value)
0b11111111
And the results after pressing switch 0:
>>> bin(cad.intfa.value)
0b1
>>> bin(cad.intcapa.value)
0b11111110
And again:
>>> bin(cad.intfa.value)
0b0
>>> bin(cad.intcapa.value)
0b11111110
Notice how the flag has cleared after reading the INTCAPA register. So, interrupts are clearly working on the chip.
The MCP23S17 is configured such that the interrupt wire connected to GPIO25 (RPi pin 22) is active-low (0) when an interrupt has occurred (interrupt flag is high). In other words: GPIO25 is 0 when an interrupt has occurred, 1 otherwise. Let's see this in action:
Bring GPIO25 into userspace and check it's value:
$ echo 25 > /sys/class/gpio/export
$ more /sys/class/gpio/gpio25/value
1
Now check its value after pressing switch 0:
$ more /sys/class/gpio/gpio25/value
0
We use epoll
to detect changes on this file, which signals that an interrupt has occurred:
>>> import select
>>> gpio25 = open('/sys/class/gpio/gpio25/value', 'r')
>>> epoll = select.epoll()
>>> epoll.register(gpio25, select.EPOLLIN | select.EPOLLET)
>>> epoll.poll()
The final command should hang until the interrupt occurs (and changes the /sys/class/gpio/gpio25/value
file) after which it will return some file descriptor/event information.
The problem is that epoll is no longer returning and just hangs forever. I'm not sure why this is but am investigating. If anyone has anything to input then that would be great.
Also, the interrupt_example.c
program doesn't work either. Further evidence to the problem being with epoll (or, at least, the way I'm using it). https://github.com/piface/libmcp23s17
Some more information:
Thomas, noticed that init_epoll(void) in libmcp23s17.c, line 226 you open the file readonly and nonblocking
gpio_pin_fd = open(gpio_pin_filename, O_RDONLY | O_NONBLOCK);
In the above you do not specify not blocking on the open or change the file control
gpio25 = open('/sys/class/gpio/gpio25/value', 'r')
I have this issue as well on Pi 2 with PiFace CAD2. It seems to be just the listeners / interupts. Is there a way I can work around or fix this based on the above?
My initial opinion was that the device tree config.txt changes addressed the interrupt issue so give them a go
Either disable the device tree in raspi-config (option 8/A5) or add dtoverlay=spi-bcm2708 to /boot/config.txt manually
It seems it may be the IDLE issue I picked up on the Element 14 site. I tried the various changes above in multiple combinations with no effect. But then I tried running it in a different environment than Raspbian IDLE and interupts worked perfectly (that was under Mavproxy / dronekit-python - part of the UAV technology the RPi will be art of). Then I tried running it from $ prompt and they worked sporadically. Need to do more experimenting around this later.
[Edit] Runs fine in Terminal if called as root. A bit brutal but allows me to code and test at least!
If you find it works as root then check the file permissions in the /sys/class/gpio/gpio25 file system - I found that these changed between 3.x and 4.x and I added 'chmod 666 /sys/class/gpio/gpio17/value' to get my own code to work (in the case of the PiFaceCAD the interrupts use gpio25)
@SailingGreg Thanks ! 'chmod 666 /sys/class/gpio/gpio25/value' made the SwitchEventListener to work again with the PiFaceCAD
Also thanks! On Rpi 2 and CAD2 and my build it seems to be in /sys/class/gpio/gpiochip0/device/gpio/gpio25/value - does that make sense? I have changed its permissions and it now runs without root access on Terminal, but not through inbuilt IDLE.
Not familiar with IDLE but another thing you can check is the user rights - 'id' will list the group memberships and see if 'gpio' is included as an alternative to chmod
BTW chmod 666 is a bit of a hack and chmod o+r woud be tidier
Will try the 'id' route and see what I learn. But not overly fussed - all good in Terminal and running in the environment it is meant for. Here are the comments on IDLE at Element 14: http://www.element14.com/community/thread/28282/l/piface-cad--eventinterrupt-for-keys?displayFullThread=true (which were from Tom in the first place!)
Is anyone working on fix? It looks like there is no point in buying PiFace 😞
I am trying to use the SwitchEventListener as shown in the documentation but it doesnt seem to do anything, the program just hangs.