Arduinoでタクトスイッチ(プルアップ,チャタリング対策,長押し判定)

電子工作でおなじみのタクトスイッチですが、しっかり使おうとすると案外めんどくさかったりします。Arduinoでのタクトスイッチの使い方、注意点等をまとめました。

大量のタクトスイッチ

プルアップ抵抗

タクトスイッチを使うときはプルアップ抵抗をつけます。抵抗は読み取りピンと5Vの間につけます。抵抗値は1kから100kΩ程度のものをつけましょう。写真は10 kΩものを使用しています。

プルアップ抵抗のつけかた

内部プルアップ

プルアップ抵抗をつけるのがめんどくさい人は内部プルアップを使いましょう。内部プルアップを使うとプルアップ抵抗をつける必要がなくなります。ArduinoだとpinMode(ピン番号,INPUT_PULLUP);と書くだけで内部プルアップが使えます。

内部プルアップの場合
void setup ( ) {
  Serial.begin(9600);               // 9600bpsでシリアルポートを開く
  pinMode(2,INPUT_PULLUP);
  }
  
void loop ( ) { 
  if(digitalRead(2) == LOW){        //スイッチが押されているとき
    Serial.println("OSARETAYO!");
  }
}

チャタリング対策

タクトスイッチを使うときに考慮しなければいけないのがチャタリング。スイッチを一度しか押していないのに、複数回押されたと判断されてしまう。こんなときはチャタリングが原因なのでチャタリング対策をしましょう。

#define PUSH_SHORT 100
int count_low = 0;

void setup ( ) {
  Serial.begin(9600);               // 9600bpsでシリアルポートを開く
  pinMode(2,INPUT_PULLUP);
  }
  
void loop ( ) { 
  if(digitalRead(2) == LOW){        //スイッチが押されているとき
    if(count_low <= PUSH_SHORT)count_low ++;
  }else{                            //スイッチが押されていないとき
    count_low = 0;
  }
  
  if(count_low == PUSH_SHORT){
    Serial.println("OSARETAYO!");
  }
}

上のプログラムでは100回連続でLOWを読み取ればスイッチが押されたと判定するプログラムです。 PUSH_SHORTの値を増やせば、より強力になります。

スイッチを離したときの判定

スイッチを離したときにもチャタリングが発生します。スイッチを離したときにも何か処理をさせたいときに使ってください。

#define PUSH_SHORT 100
int count_low = 0;

void setup ( ) {
  Serial.begin(9600);               // 9600bpsでシリアルポートを開く
  pinMode(2,INPUT_PULLUP);
  }
  
void loop ( ) { 
  if(digitalRead(2) == LOW){        //スイッチが押されているとき
    if(count_low < 0)count_low = 0;
    else if(count_low <= PUSH_SHORT)count_low ++;
  }else{                            //スイッチが押されていないとき
    if(count_low > 0)count_low = 0;
    else if(count_low >= -PUSH_SHORT)count_low --;
  }
  
  if(count_low == PUSH_SHORT){
    Serial.println("OSARETAYO!");
  }
  if(count_low == -PUSH_SHORT){
    Serial.println("hanaretayo...");
  }
}

長押しを判定する

スイッチが足りないときは長押し機能を使うと便利です。PUSH_LONGを変えると長押しの時間が変えられます。

#define PUSH_SHORT 100
#define PUSH_LONG 32000
uint16_t count_low = 0;

void setup ( ) {
  Serial.begin(9600);               // 9600bpsでシリアルポートを開く
  pinMode(2,INPUT_PULLUP);
  }
  
void loop ( ) { 
  if(digitalRead(2) == LOW){        //スイッチが押されているとき
    if(count_low <= PUSH_LONG)count_low ++;
  }else{                            //スイッチが押されていないとき

    if(count_low >= PUSH_LONG)Serial.println("NAGAOSHIDAYO!!!!!");
    else if(count_low >= PUSH_SHORT)Serial.println("OSARETAYO!");
    
    count_low = 0;
  }
}

スイッチを押したときの判定だと長押しかどうか判別できないので、スイッチを離したときに判別を行います。この方法だと、押した長さによって複数の処理に分岐することも出来ます。

delay()を使わないので他の処理とかぶることなく使用できます。周期を一定にしたければタイマ割り込みを使いましょう。

コメント