痛いOTAKUのポエム

地雷多すぎ人間の愚痴

Enter氏製のコントローラのチャタリング対策をArduinoのスケッチで行う

なにこれ

Enter氏が販売している『【pop'n music用】beatmania風コントローラー』のボタンのチャタリング対策をArduinoのスケッチ側で行いたいと思ったので、そのスケッチを公開しておきます。
コントローラの詳細は以下をご確認ください。

sha10n.hatenablog.com
erabemani.booth.pm

スケッチ

#include <Arduino.h>
#include <HID-Project.h>

//ピン番号 0は欠番
int button[12] = {
  0, 2, 3, 4, 5, 6, 7,
  8, 9, 10, 14, 15
};
//z s x d c f v g b h n
int key[12] = {
  0, 0x7A, 0x73, 0x78, 0x64, 0x63, 0x66, 0x76, 0x67, 0x62, 0x68, 0x6E
};
int i;

// Sha追加チャタリング対策
int chata[12] = {
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};

void setup() {
  for (i = 1; i < 12; i++) {
    pinMode(button[i], INPUT_PULLUP);
    chata[i]=0;
    }
  NKROKeyboard.begin();
}

void loop() {
  for (i = 1; i < 12; i++) {
    if (chata[i] > 0) {
       chata[i]--; // Shaチャタリング対策に追加
    }else if (digitalRead(button[i]) == LOW) {
       NKROKeyboard.add(key[i]);
       chata[i] = 5;
    }else{
       NKROKeyboard.release(key[i]);
    }
  }
}

(私はDJMAX RESPECTでも使いたかったためボタンではなくキーボードにアサインを変えてもらっています。もしもまるまるコピペしたい人はそこだけ注意

解説

必要はないかもしれませんが一応解説をします。
int chata[12]はチャタリング防止用のタイマーを示します。左から順に1~12です。
デフォルトで0が入っていますが、本当に一応、念のためsetup() 内でchata[i]=0;をすることで各タイマーを0にしています。

ループ内の処理では最初にif (chata[i] > 0)とタイマーが0より大きいかチェックします。
0より大きい場合(すなわちチャタリング対策時間中)ならボタンのオンオフ判定は更新せず、参照中のボタンのタイマー値を1減らします。

タイマーが0である場合、ボタンのオンオフ状態をチェックします。
オンである場合、ボタンを押し込み状態にしたうえで、参照中のボタンのタイマー値を5にセットします。
オフであればボタンを開放状態にします。

つまり、このスケッチでは
ボタンが押し込まれたら該当のボタンの押し込み状態のチェックは5回スルーする
という仕組みでチャタリングを対策しています。
なので、押し込んでから反応するまでは遅延なしになるように設定されています。
離し判定は若干遅れる可能性がありますが、めちゃくちゃ大きく見積もって1個のボタンのチェックに1ミリ秒、12ボタンで12ミリ秒かかったとしても5回なら60ミリ秒なので、4F以下だけ押したいときくらいにしか問題にはならないはずです。
まあArduino Unoは16 MHzらしいので実際にはそんな時間はかからず、なんならボタンの押し込みチェックのスルー回数は10回とかでもいいと思います。
そのあたりは使う人が調整してください。


以上です。