デジタル入力には大きく分けて二種類ある。
一つは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; }