どうしてもポーリングではなく割り込み処理にてGPIOを監視したかったので調べていたら最近wiringPi.hにwiringPiISRと呼ばれる頼もしい関数が追加されたようなので試してみました。
下記のサンプルコードではRaspberry Piにポケットガイガー Type5をGPIO 2にシグナル、GPIO 3にノイズを接続して100マイクロ秒で送られてくるパルスを検知します。
#include <wiringPi.h>
#include <stdlib.h>
#include <stdio.h>
void signal(void){
printf("Signal\n");
}
void noise(void){
printf("Noise\n");
}
int main(void){
int setup = 0;
setup = wiringPiSetupSys();
while(setup != -1){
wiringPiISR( 30, INT_EDGE_FALLING, signal );
wiringPiISR( 31, INT_EDGE_RISING, noise );
sleep(10000);
}
return 0;
}
コンパイル
$ sudo gcc Interrupt.c -lwiringPi
実行結果(最初ポケットガイガー Type5をつついてノイズを発生させてみました)
$ ./a.out
Noise
Signal
Noise
Signal
Noise
Noise
Noise
Signal
Signal
Noise
Noise
Signal
Signal
Noise
Signal
Signal
Signal
Signal
Signal
Signal
他にもwaitForInterruptという関数もあるようですがwiringPiISRの方が便利かもしれません。
当たり前ですがこれをポーリングで書くとsleepがほとんど使えない状態になるのでCPU使用率が偉いことになりますw
組み込みLinuxの世界も楽しいものですね。
追記
プログラムに下記のように記述しておりましたのを修正しました。
wiringPiISR( 2, INT_EDGE_BOTH, signal );
wiringPiISR( 3, INT_EDGE_BOTH, noise );
ポケットガイガーのシグナルは通常はHighで検知されるとlowとなります。ノイズは通常lowで信号が検知されるとhighとなります。ここで”INT_EDGE_BOTH”を指定すると、信号が来て割り込みが発生し、通常の状態に戻ったときも割り込みが発生します。つまり一回の検知で2回割り込みが発生してしまうということになります。
そのため、個別できちんと指定する必要が有るようです。
0 Comments.