Same Shit Different Day

Arduino実験機1号~Arduino+プッシュボタン編

メール 印刷
ThumbnailArduino(公式サイト)を使うと、マイコンを操作して様々な外部機器を制御できます。

と、言っては見たものの実際にArduinoを使ってどんな物を作るのかと聞かれると、具体的なアイデアは直ぐには出てきません

そんなこんなで、動作確認くらいしかできていなかったArduinoですが、とある行事に参加することになりまして、そこで簡単なアンケートみたいなものをすることになりました。

アンケートと言っても用紙に何かを記入してもらうようなものではなく、単純な二捨択一式(好きとか嫌いとか)で気軽に済ませられるもので、ボタンを二つ用意してその数を集計するだけのもので十分に物足ります。

アナログ的に考えれば、電子カウンタとボタンを繋ぐだけで済ませてしまいたい感じですが、せっかくArduinoがあるので、PCと通信させて視覚的にも凝ったカウンタにできれば理想的です。

  1. ボタンの入力をArduinoで検知してシリアルポートに情報を送信
  2. PC上のサーバーでTCPポートを監視し、シリアルポートの情報をTCPポートへ転送
  3. Flashアプリを作成、TCPポートを監視して、入力があれば情報を受信しカウンタを更新
ざっと処理の流れとしてはこんな感じでしょうか。

2番目の処理は、シリアルポートへ直接アクセスできないFlashアプリとArduinoを通信させるためのもので、一番厄介そうな部分ですが、とりあえずは必要ありません。

用意したものは、
Thumbnail
  1. Arduino Duemilanove
  2. プッシュボタン2個(何でもOK)
  3. 1kΩ抵抗2個(プルダウン用)
  4. Arduino IDE
Arduinoの基盤上にはユーザーがコントロール可能なLED(Digital13番)が用意されていてUSBケーブルでPCとArduinoを接続、Arduino IDEをPCにインストールしたら、サンプルプログラムをArduinoにアップロードして問題なく使用できるかどうかを試してみることができます。

さて、問題なくArduino IDEが動いたら、早速プッシュボタンを図のようにプルダウン抵抗を入れて接続します。

下記のようにスケッチを書いてコンパイル、Arduinoへアップロードします。
int btPin = 2;
int ledPin=13;
int pinState = LOW;

void setup() {
  pinMode(btPin, INPUT);
  pinMode(ledPin, OUTPUT);
}

void loop() {
  pinState = digitalRead(btPin);
  if (pinState == HIGH) {
    digitalWrite(ledPin, HIGH);
  } else {
    digitalWrite(ledPin, LOW);
  }
} 
ボタンを押した時に基板上のLEDが点灯すれば、ひとまずはOKです。

次に、シリアル経由でボタンが押されたら、ボタンが押されたと言う信号を送信するように変更してみましょう。

int btPin = 2;
int pinState = LOW;

void setup() {
  pinMode(btPin, INPUT);
  Serial.begin(9600);
}

void loop() {
  pinState = digitalRead(btPin);
  if (pinState == HIGH) {
    Serial.println("Pushed!");
  }
} 
Thumbnailこれで、ボタンが押されたらシリアル経由で”Pushed!”が送信されるはずです。

シリアル経由で信号が送信されているかどうかは、Arduino IDEのシリアルモニター機能を使います。

シリアルモニターをONにしてボタンを押すと・・・確かに”Pushed!"と表示されてはいますが、ボタンを一回押しただけなのに何回も”Pushed!"が送信されています。

これではボタンが押されたかどうかの判定ができず使い物になりません

電子カウンタなら電圧の入力時間そのものが比較的長く緩慢なため、ボタンを押すくらいの時間なら一回押されたと判定する(感度の調整によります)のですが、Arduinoには通用しません。

デジタルなArduinoは、マイコンがプログラムを実行するサイクル時間でボタンが押されているかどうかを判定してしまうため、例えボタンを幾ら早押ししてもマイコンからすれば軽く数十サイクルが過ぎてしまうためです。

これはバウンスと呼ばれ、機械的に回避することができないのでソフト側で対応する必要があります。

たかだかボタン(スイッチ)なのに厄介なものです。

バウンスを回避するには、一定の時間内は同じ判定結果を出さなければ良い、すなわちボタンが押された瞬間に”ON”であれば、一定時間の間にまた”ON”と言う判定が出た場合は無視すると言うプログラムを書けばよいことになります。

この一定時間と言うのは、ボタンの構造等によって左右されますが、何回か試せば最適な時間が導き出せると思います(ここでは20ms)。

何となくアルゴリズムは理解できましたが、実はArduinoの公式サイトには豊富なライブラリがすでに用意されていて、その中にボタン入力の際のバウンスを回避する”デバウンス”と言うライブラリが存在します。

デバウンスのライブラリは古いために、”バウンス”と言う新しいライブラリが推奨されていますが、バウンスライブラリではうまく行きませんでしたので、とりあえず動作確認が取れているデバウンスライブラリを使うことにします。

ライブラリを指定通り”/hardware/libraries”にコピーし、
#include 
#define BtPin 2

// 20msをデバウンス用に定義
Debounce debouncer = Debounce(20, BtPin);

void setup() {
  pinMode(BtPin, INPUT);
  Serial.begin(9600);
}

void loop() {
  if (debouncer.update() && debouncer.read() == HIGH) {
    Serial.println("Pushed!");
  }
} 
こんな感じにスケッチを変更します。

コンパイルに問題がなければArduinoにアップロードしてシリアルモニターを実行してみます。

ボタンを一回押すと、”Pushed!”が一回だけ、モニター画面に表示されるはずです。

 
ホーム | がらくた紹介 | Arduino実験機1号~Arduino+プッシュボタン編

最新記事

人気記事