●Arduinoでスイッチを使う

Arduinoに押しボタンスイッチを取り付けてみます。
基本的に入力可能なデジタルピンならばどこにでも接続できます。

一番若い番号であるデジタルピン2番に接続する事にしました。

デジタル回路に接続するには、プルダウンやプルアップをする必要があります。
ピンがフリーの時にプラスの電圧を掛けるのがプルアップ、マイナスの電圧を掛けるのがプルダウンと言います。
もし、プルアップもプルダウンもしないと、値が不定になり誤動作する可能性があります。


▼プルダウン

プルダウンでは、GNDと対象とするピンを1KΩ〜10KΩの抵抗で接続してピンに常にマイナスの電圧がかかるようにします。
それに対してスイッチはプラス極に接続します。
スイッチが押されるとピンはプラスの電圧がかかり、スイッチが離されるとマイナスの電圧がかかるためデジタル回路が認識できるのです。
スイッチが押された状態ではプラス極とマイナス極を抵抗がつないでしまい電力が消費されますが、抵抗値が大きいため些細な電流しか流れません。


プルダウンしている所、GNDと2番デジタルピンが抵抗で接続されています。
void setup () {
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(2, INPUT);
}

void loop () {
  digitalWrite(LED_BUILTIN, digitalRead(2));
}

基板上のLEDのピン番号はLED_BUILTINの定数になっています(ボードにより違うため)、このプログラムではスイッチが押されるとLEDが点灯します。


▼プルアップ

Arduinoには内蔵プルアップ回路があり、プルアップの場合にはプラス極との間に抵抗を接続しなくても、プルアップできるようになっています。
ただし、内蔵プルダウン回路は存在しません。
プルアップを使用した場合には、対象デジタルピンがプラスの電圧を帯びているため、スイッチはGNDとの間に接続します。
スイッチを押すことによりピンにマイナスの電圧がかかり、デジタル信号として認識されます。


内蔵プルアップを使うため、スイッチ以外の部品が必要ありません。
void setup () {
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(2, INPUT_PULLUP);
}

void loop () {
  digitalWrite(LED_BUILTIN, !digitalRead(2));
}

基板上のLEDのピン番号はLED_BUILTINの定数になっています(ボードにより違うため)、このプログラムではスイッチが押されると基板上のLEDが点灯します。
内蔵プルアップを有効にしているため"pinMode"の設定で、"INPUT_PULLUP"が指定されています。

プルダウンに対してプルアップはピンにかかる電圧が逆になるため、プログラムでデータを取得する際にONとOFFが逆転させる必要があります。
そのため、"digitalRead"の戻り値に対して"!"を付ける事によりONとOFFを逆転させています。


■チャタリング対策

押しボタンなどの各種接点が接触するスイッチでは、ONになった瞬間やOFFになった瞬間に接点がバウンドしたり切れが良く接続されないために、
瞬間的にON・OFFが繰り返されます。
人間の目ではほんの一瞬ですが、マイコンの高速なスピードでは非常に長い間ON・OFFが繰り返されている事になるためプログラムが誤動作します。
void setup () {
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(2, INPUT_PULLUP);
}

int i,j;

void loop () {
  j=digitalRead(2); 
  if(!j){
    //スイッチが変化するまで待つ
    while(digitalRead(2)==j);
    i=!i;
    digitalWrite(LED_BUILTIN,i);
  }
}

このプログラムではボタンを押すとLEDが点灯、もう一度押すと消灯になるようになっていますが、通常のスイッチではチャタリングでうまく動作しないはずです。
チャタリング防止には対象ピンを複数回にわたり時間を空けて読んで値が確定しているのか確認する必要があります。
void setup () {
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(2, INPUT_PULLUP);
}

int i,j;

void loop () {
  if(chatteringCut_pullupPin(2)){
    i=!i;
    digitalWrite(LED_BUILTIN,i);
  }
}

unsigned int chatteringCut_pullupPin(int pinNo){
  unsigned int i=0;
  while(!digitalRead(pinNo)){
    i++;
    delay(1);
  }
  //1111111111000000 でアンドを取り下位ビットをマスクする
  //つまりループが63を超えるまで0しか返さない
  return i&(~(unsigned int)0x3F);
}

chatteringCut_pullupPin関数では、時間を空けてデジタルピンを64回読んでONを確定させて、その後はOFFになるまでカウントアップし長押しを検出します。
このプログラムでは正しく動作します。
ただ、ボタンを押している間はプログラムがループに突入して全体が止まるためもっと別のアプローチが必要になるかもしれません。
チャタリング対策のプログラミング方法は色々あると思いますのでご参考までに。


▲トップページ > マイコンなど