I am attempting to monitor a GPIO pin, and per the Linux docs I should be able to do this by monitoring the /sys/class/gpio/gpio##/value
file with select
:
"value" ... reads as either 0 (low) or 1 (high). If the GPIO
is configured as an output, this value may be written;
any nonzero value is treated as high.
If the pin can be configured as interrupt-generating interrupt
and if it has been configured to generate interrupts (see the
description of "edge"), you can poll(2) on that file and
poll(2) will return whenever the interrupt was triggered. If
you use poll(2), set the events POLLPRI and POLLERR. If you
use select(2), set the file descriptor in exceptfds. After
poll(2) returns, either lseek(2) to the beginning of the sysfs
file and read the new value or close the file and re-open it
I am attempting to do this in Ruby, and per the IO.Select documentation it calls select(2)
.
So, with this knowledge I threw together the following test program:
fd = File.open("/sys/class/gpio/gpio17/value", "r")
loop do
rs,ws,es = IO.select(nil, nil, [fd], 5)
if es
r = es[0]
puts r.read(1)
else
puts "timeout"
end
end
However, it does not detect any pin changes. When I launch this app it will immediately fall into the if
block and display the pin's current value, and then every 5 seconds just prints timeout
.
Have I read the docs wrong? Shouldn't select
be able to monitor this?