チャタリング防止

PICやarduinoで,タクトスイッチ等の安物を使うと,話題に上るのがチャタリングです。チャタリングのこと
を考えないと思った動作をしなくなります。
通常は,シュミットトリガー回路に代表されるハードを使って取り除く方法や,ソフトで取り除くこと等が必
要のようです。ソフトでは,間をあけて何回か測定して判別する方法等があるようですが,あるHPで,ビット
シフトを使った方法がでていました。

#define MAXPIN 13

int checkbutton(int i){
   static byte val[MAXPIN];
   static byte state[MAXPIN];

   if(digitalRead(PIN[i]) == 1){
      val[i] = val[i]<<1;
      val[i] += digitalRead(PIN[i]);
   }else{
      val[i] = 0;
   }

   if(val[i] == B01111111){
      state[i] = 1 - state[i];
   }

   return state[i];
}

やはり,先達はすごい。い くつか変数を用意しておいて,古いデータと比べるということは考えつきますが,
ビットシフトを使うとは,すごいなと思いました。ただ,このプログラム,IDEでコンパイルすると

 B01111111→→0b01111111

と怒られます。ちょっとした勘違いなんでしょうね。「弘法も筆の誤り」ですね。

追記
 あと,シフトビットのいいところは,オーバーフローを気にしなくていいことでしょうか。シフトで
はみでた部分は,破棄されるようですので。ここを,int等の変数で足し算すると,オーバーフローの処置をいれないとPGが暴走しますので。

併せて,変数のスコープ等について,調べていたら,大きな勘違いをしていることに気がつきました。IDE
では,Loopの中にmainのプログラムを書きますが,一回だけ実施したい処理を次のように書きました。


loop(){
   int flag;
   if(flag==0){
      syori;//動作させたい処理
      flag=1;
   }
}

みたいな記述をしていましたが,思った動作はしませんでした。それもそのはず,loopの中で,
最後の「 }」の前で,変数が初期化されてしまうとのこと。これでは,思った動作をしませんね。
保持するには,

  int flag;→→static int flag;

のように,静的変数の宣言をしないとだめということが分かりました。これ,IDEの癖みたいなものでしょう
か。知らないとこまりますね。今まで,loopのなかの冒頭で,変数の宣言をしていましたが,これ,何回も
宣言することになって,なんだろうと,疑問にも思っていたところなので,この疑問も解決ですね。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA