2013-01-12 12 views
5

Sto tentando di monitorare un pin GPIO, e per la documentazione di Linux dovrei essere in grado di fare questo, monitorando il file /sys/class/gpio/gpio##/value con select:monitoraggio GPIO con 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 

Sto tentando di fare questo in Ruby e per lo IO.Select documentation chiama select(2).

Quindi, con questa conoscenza ho buttato insieme il seguente programma di test:

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 

Tuttavia, non rileva alcuna modifica pin. Quando lancio questa app, questo cadrà immediatamente nel blocco if e visualizzerà il valore corrente del pin, quindi ogni 5 secondi stampa solo timeout.

Ho letto i documenti errati? Non dovrebbe select essere in grado di monitorare questo?

risposta

4

Prima che select si attivi correttamente su un pin GPIO, è necessario impostare il grilletto del pin. Da the GPIO docs:

"edge" ... reads as either "none", "rising", "falling", or 
    "both". Write these strings to select the signal edge(s) 
    that will make poll(2) on the "value" file return. 

    This file exists only if the pin can be configured as an 
    interrupt generating input pin. 

In Ruby semplicemente:

File.open("/sys/class/gpio/gpio17/edge", "w") { |f| f.write("both") } 

L'esempio completo dall'alto sarebbe simile:

fd = File.open("/sys/class/gpio/gpio17/value", "r") 
File.open("/sys/class/gpio/gpio17/edge", "w") { |f| f.write("both") } 

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