押しボタンスイッチ(2)

デジタル入力には大きく分けて二種類ある。
一つはON/OFFの状態を見るためのステータス入力。
もう一つは状態のONになった瞬間やOFFになった瞬間を見るためのエッジ入力である。
(入力の名称はここで勝手につけている。)

スタートスイッチなどは、操作者の手で押す可能性があり、
確実にスイッチを押すために、長めに押す場合がある。
通常の入力でロジックを作成してしまうと、
ロジックが2回スタートを検知してしまう場合がある。
もちろん、連続して2回検知しても問題のないロジックであれば問題ない。
問題のあるケースの一例として、スタートボタンが押されたときに、
自動的に過去情報を修正してキャリブレーションしているようなケースだと、
2回スタートボタンが押されると過去情報がなくなってしまったりする。
(ちょっと‏事例を作るために強引な説明だが (-_-;))

今回のスイッチは、OFFの状態で1となり、ONになったときに0となる。
ロジック上は1→0になったときに1周期だけONにするファンクションが望ましい。

ロジックはそんなに難しくなく、前回が1で今回が0となる関数 F_TRIGを
作成すればよい。(falling-edge trigger)

F_TRIGの中で変数にstaticで宣言しているが、
これは呼ばれる毎に変数がクリアされないようにしている。
ただ、このロジックには欠点があり、複数個所から呼ばれると正しく動作しない。
この辺りは、いくつか解決策があるので、工夫してみてほしい。

—-スケッチの例

const int START_SW_PIN_NO = 4;

void setup() {

   //***** set serial port speed (bps)
   Serial.begin(115200);

   //***** set pin mode
   pinMode(START_SW_PIN_NO, INPUT_PULLUP); // Enable pullup for input mode.
}

void loop() {
   int start_sw, trig;
   start_sw=digitalRead(START_SW_PIN_NO);
   trig=F_TRIG(start_sw);
   Serial.print("Start Switch =");
   Serial.print(start_sw);
   Serial.print(" Trigger=");
   Serial.println(trig);
   delay(200);
}

int F_TRIG(int X){
   int Q;
   static int lastX;
   if(X==0 && lastX==1){
      Q=1;
   }else{
      Q=0;
   }
   lastX=X;
   return Q;
}