どうしてもポーリングではなく割り込み処理にて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回割り込みが発生してしまうということになります。
そのため、個別できちんと指定する必要が有るようです。
最近のコメント