ArduinoやESP8266等でボタン入力する方法は色々あるが、簡単な方法は
pinMode(PIN番号,INPUT_PULLUP);
としてピンモードをINPUT_PULLUPとする事でArduinoマイコン内でピンのプルアップが有効となり、ボタンは該当ピンとGNDの間に接続するだけで済む。
詳細はスイッチサイエンスさんの記事で紹介されている。
時計合わせ等ボタンを押して数値を設定する場合、一桁程度の設定であればボタンを連打しても良いが、2桁以上の数字の調整の場合ボタン連打は苦行になる。
そんな時はキーリピート処理を付ける。ボタンを押して、一定時間押し続けていると数値が連続して上下する処理である。
さらに押し続けていると、数値の上がり方も速くなる動作を見た事があると思う。処理によっては1ずつ上がっていたのが5ずつの加算になり、その後10ずつの加算にと加算値が増えるタイプもある。
下記スケッチはボタンを押して1.2秒経過するとキーリピート開始し、さらに押し続けているとキーリピートがどんどん加速していくサンプルである。D5ピンとGNDピンの間にボタンを付けるかワイヤーでショートし、シリアルモニタの数字出力を見ているとキーリピートにより数値が上がり方が加速していくのが分かる。
チャタリング防止のため、ボタンが50ms以上押された状態でないと反応しない様にもしている。
#define BUTTON_PIN 5 //ボタン接続ピン このピンとGND間にボタンを繋ぐ
#define BUTTON_CHECK_TIME 50 //このミリ秒以上ボタン押下状態が続いていれば押されていると判断
unsigned long current_millis;
unsigned long start_buttonpress;
unsigned long last_buttonpress = 0;
bool last_state;
int count = 0;
bool check_button()
{
bool button_press;
button_press = digitalRead(BUTTON_PIN) == LOW ? true : false;
//ボタン押されていない
if (!button_press) {
last_state = false;
last_buttonpress = 0;
return false;
}
//ボタン誤動作防止のため、押されてから一定時間以上ボタンの状態が続いてからボタン押下と判断する
if (!last_state) { //押された直後
//変化があった時間を記録
start_buttonpress = current_millis;
last_state = true;
return false;
}
if ((unsigned long)(current_millis - start_buttonpress) > BUTTON_CHECK_TIME)
return true;
return false;
}
void setup() {
Serial.begin(115200);
last_state = false;
pinMode(BUTTON_PIN, INPUT_PULLUP);
}
void loop() {
current_millis = millis();
if (check_button()) { //ボタンが押されている
if (last_buttonpress == 0) { //最初の押下処理
count++;
Serial.println(count);
last_buttonpress = current_millis;
}
else { //キーリピート処理
unsigned long timediff;
timediff = (unsigned long)(current_millis - last_buttonpress);
if (timediff >= 1200) { //前回処理時間から1.2秒以上経過している場合に押下処理
//last_buttonpressを少し前に戻す事でキーリピートする。
//ボタンを押してからの時間が長くなるとリピートの間隔が短くなる
timediff = (unsigned long)(current_millis - start_buttonpress);
last_buttonpress = current_millis - 1000 - (min(190, timediff / 100));
count++;
Serial.println(count);
}
}
}
}