Arduinoに自作のデバウンスを組み込んでみた 2

[Arduinoに自作のデバウンスを組み込んでみた](http://qiita.com/ttatsf/items/9e14d42855f363116a47)の続き。
だいぶ前に作ったMIDI CCを出す(だけ)のスイッチ。
![P_20160706_113957.jpg](https://qiita-image-store.s3.amazonaws.com/0/61597/82a36ccc-b111-9f67-cbef-1420f050e779.jpeg)

調子が悪いと返ってきたのを機にプログラムを入れかえました。

中味がDuemilanoveなんでSerialからMIDI端子に出しています。USBでは出ません。
なので[DebounceFunc for Arduino](http://qiita.com/ttatsf/items/510761700a1eaa01982c)にあるスケッチ例とは、Serialの速度、MIDI送信の仕方が違います。

```cpp
#include <DebounceFunc.h>
const int ND = 4;
const int LED_PIN = 13;
const int IN_PIN[ ND ] = {4, 6, 8, 10};
const int GND_PIN[ ND ] = {5, 7, 9, 11};
const int MSG = 176;    //CC (channel:0)
const int VAL1[ ND ] = {70, 71, 72, 73};  // CC number
IsFALLING isFalling[ ND ] /*  = {50, 50, 50, 50}  */;
IsRISING isRising[ ND ]  /*  = {50, 50, 50, 50}  */;

void setup() {
  pinMode(LED_PIN, OUTPUT);
  for (int i = 0; i < ND; i++) {
    pinMode(IN_PIN[i], INPUT_PULLUP);
    pinMode(GND_PIN[i], OUTPUT);
    digitalWrite(GND_PIN[i], LOW);
  }
  Serial.begin(31250);
}

void loop() {
  for (int i = 0; i < ND; i++) {
    const int DATA = digitalRead( IN_PIN[i] );
    if ( isFalling[i](DATA) ) {
      MIDI_TX(MSG, VAL1[i], 127);
      digitalWrite(LED_PIN,HIGH);
    }
    if ( isRising[i](DATA) ) {
      MIDI_TX(MSG, VAL1[i], 0);
      digitalWrite(LED_PIN,LOW);
    }
  }
//  delay(1);
}

void MIDI_TX(const int MESSAGE, const int VAL1, const int VAL2) 
{
  Serial.write(MESSAGE);
  Serial.write(VAL1);
  Serial.write(VAL2);
}
```

当初デバウンスタイムを50msで始めましたが、デフォルト値で全然大丈夫なスイッチだったので、そこはコメントアウトしました。

#修正前のスケッチ。 思いっきり手続き型。

前に入れてたのを捜すと...ありました。

```cpp
#define pushVal 0  //for push-on switches.
//#define pushVal 1  //Otherwise,use this for push -off switches.
#define nd 4  //number of digital switches.
#define msg 176  //controll change. note-on:144 note-off:128

const int inPin[nd] = {4,6,8,10};  //input pins for switches.
const int gndPin[nd] = {5,7,9,11};  //input pins' ground.
const int val1[nd] = {70,71,72,73};  //controll No or note No
int val2[nd];  //controll value or velocity

long time[nd];  //the last time each switches was toggled.
//long now;  
const long debounce = 300;  //debounce time. Increase if the output flickers.

//int reading;

void setup(){
  for(int i=0 ; i < nd ; i++ ){
    pinMode(inPin[i] , INPUT);
    digitalWrite(inPin[i] , HIGH);
    pinMode(gndPin[i] , OUTPUT);
    digitalWrite(gndPin[i] , LOW);
    
    time[i] = millis();
    
    val2[i] = readPin(i);
  }  
    Serial.begin(31250);
}
void loop(){
  static int reading;
  static long now; 
  
  for(int i = 0 ; i < nd ; i++ ){
    reading = readPin(i);
    
    if(reading != val2[i]){
      now = millis();
      
      if(now-time[i] > debounce){
        val2[i] = reading;
        MIDI_TX(msg , val1[i] , val2[i] );
        time[i] = now;
      }
    }
  }
}

int readPin(int i){
  
  return digitalRead(inPin[i])  == pushVal ? 127 : 0 ;
}

void MIDI_TX(int MESSAGE, int VAL1, int VAL2) 
{
  Serial.write(MESSAGE);
  Serial.write(VAL1);
  Serial.write(VAL2);
}
```

今でも動くように```Serial.write()```に変更してあります。

どうしてたんだっけ? 自分でやったことをすっかり忘れている...

+ ボタンが変更された時刻と以前に変更された時刻の差がデバウンスタイムを超えたら
	+ ボタンの変更を有効にする 
	+ そうでなければボタンの変更を無視する

というように読めます。
ん? アルゴリズムがロックアウト(とりあえず変更して、一定時間操作不能にする)になってる?
なんでだろ...
そのときはそれがいいと思った?覚えてない...
ただデバウンスタイムが300msになってるので、やっぱり安定しなくて苦労したのかな?
だめだ、覚えてないわ...