Arduino

Arduinoを使ったスイッチ制御の方法

前回はArduinoを使ってLEDを点滅させる方法をご紹介しました。

実生活上では光をつけっぱなしにしておくことはあまりなく、意図的に光を点けたり消したりしています。そこで、今回はLEDの点滅をスイッチを使って制御する方法をご紹介したいと思います。

紹介するスイッチを使った制御方法は、スイッチを押している間だけ点灯する方法とスイッチを押したら点灯・点滅を切り替える方法の2つです。

Arduinoを使った回路

スイッチを使ってLEDを点灯する回路構成について説明していきます。今回もArduinoとフレットボードを使って回路を作っています。

必要な機器・端子

使用した機器・端子は以下の通りです。

Arduino マイコン搭載の小型コンピュータ
フレットボード 抵抗・ジャンパー線などを使って回路を作る基盤
LED 順方向に電圧を加えると発光する半導体
ジャンパー線 電気を中継する線
抵抗10kΩ 電圧を下げる端子
スイッチ ボタンのON/OFF
LEDをつける

Arduinoの13番ポートとフレットボードの(f,18)をジャンパー線でつなぎ、同じくGNDと(j,17)をつなぎます。その間にLEDのカソードを(h,17)、アノードを(h,18)に差し込みます。

スイッチをつける

まず、スイッチを下図のように(f,7)、(f,9)、(e,9)、(e,7)にまたがるように配置します。その後、Arduinoの5Vポートと(g,9)をジャンパー線でつなぎ、(g,7)と(g,2)をまたぐように抵抗10kΩを差し込みます。そして、(j,7)からジャンパー線でスイッチの出力ポートとしてArduinoの7ポートに、同じく(j,2)とGNDをつなぎます。

スイッチを押している間だけ点灯する方法

スイッチを押している間だけLEDのランプが光り続け、スイッチから手を離したらランプが消えるようにプログラミングします。

プログラムコード

以下がスイッチを押している間だけ点灯するプログラムコードになります。

const int LED = 13;//LEDのポート
const int BTN = 7; //ボタンのポート

int val = 0;//ボタンの初期値はオフ

void setup() {
// put your setup code here, to run once:
pinMode(LED,OUTPUT);//LEDは出力モード
pinMode(BTN,INPUT);//ボタンは入力モード

}

void loop() {
// put your main code here, to run repeatedly:
val = digitalRead(BTN);//ボタンが押されているかを確認する

if(val == HIGH){
digitalWrite(LED,HIGH);//LEDをオン
}else{
digitalWrite(LED,LOW);//LEDをオフ
}
}

LEDは光を放つので出力すなわち、pinModeはOUTPUTを指定していましたが、スイッチはボタンをONまたはONにするため、pinModeはINPUTで指定する必要があります。

pinMode(BTN,INPUT);//ボタンは入力モード

また、指定したポートにLEDはLOWかHIGHを書き込むためにdigitalWriteを使っていましたが、スイッチはONなのかOFFなのか(HIGHなのかLOWなのか)を判断するためにdigitalReadを使っています。

val = digitalRead(BTN);//ボタンが押されているかを確認する

実行結果

実行結果は以下のようになります。

スイッチを押したら点灯・点滅を切り替える方法

スイッチを押したらLEDが光り続け、もう一度スイッチを押すと消灯するプログラムは以下の通りです。

プログラムコード

プログラムコードを以下に記載します。

const int LED = 13;//LEDのポート
const int BTN = 7; //ボタンのポート

int val = 0;//ボタンの初期値はオフ
int old_val = 0;//ひとつ前のボタンの状態
int sts = -1;//ボタンを押したかどうかの状態を記憶

void setup() {
// put your setup code here, to run once:
pinMode(LED,OUTPUT);//LEDは出力モード
pinMode(BTN,INPUT);//ボタンは入力モード

}

void loop() {
// put your main code here, to run repeatedly:
val = digitalRead(BTN);//ボタンが押されているかを確認する

if(val == HIGH && old_val == LOW){
sts = sts * (-1);//正数の場合にLEDを点灯、負数の場合は消灯
delay(50);//ハウシング対策
}

old_val = val;//ボタンの状態をひとつ前の状態として記憶とする

if(sts > 0){
digitalWrite(LED,HIGH);//LEDを点灯
}else{
digitalWrite(LED,LOW);//LEDを消灯
}
}

スイッチのON/OFFによってLEDの状態を切り替えるのは2つのポイントがあります。

スイッチの前の状態を記憶する

プログラム内のLOOPは非常に速い周期で実行されるため、人の手がスイッチを押している間に何百回何千回以上もLOOPが実行されます。それによって、スイッチを押したけれども、LEDが点灯しなかったり、消灯しなかったりと挙動がおかしくなります。そのため、スイッチの前の状態を記憶します。

int old_val = 0;//ひとつ前のボタンの状態

この現在とひとつ前ののスイッチのON/OFFの状態を条件にLEDを点灯するかしないかを判断します。

if(val == HIGH && old_val == LOW){
sts = sts * (-1);//正数の場合にLEDを点灯、負数の場合は消灯
delay(50);//ハウシング対策
}
ここでLEDの点灯状態を記憶するためにstsを使っていますが、点灯状態を”1″、消灯状態を”-1″とし、-1を乗算することによって点灯⇔消灯の状態遷移を行っています。
バウシング対策

スイッチは指で押すプラスティック部分側にばねがスイッチ本体側にある金属に触れることで通電します。しかし、接触した後もバネが振動してON/OFFを繰り返し引き起こし、意図しない挙動になります。

そこで、バウシング対策として50ms程度の待ち時間を用意すれば回避できます。

delay(50);//ハウシング対策

実行結果

実行結果は以下になります。

プルアップ抵抗とプルダウン抵抗

マイコンの入力端子は電圧源かGNDに接続しているのがルールです。どこにも接続していない状態でいるとマイコンが不安定な挙動をしたり、最悪の場合マイコンが壊れることもあります。そこで、スイッチやセンサーを使って外部信号を扱う場合にプルアップ抵抗やプルダウン抵抗を回路に組み込む必要があります。なお、前章までの回路にはプルダウン抵抗を組み込んでいます。

プルアップ抵抗

プルアップ抵抗はマイコンを基準に電圧源側に抵抗を配置した回路になります。この場合はスイッチを押すとOFF、スイッチを離すとONになります。

プルダウン抵抗

プルダウン抵抗はマイコンを基準にGND側に抵抗を配置した回路になります。この場合はスイッチを押すとON、スイッチを離すとOFFになります。

まとめ

スイッチを使って回路を制御する場合、コンピュータや端子の特徴を意識してプログラムする必要があります。プログラムは1秒間に非常に多くの処理をこなすため、意図しない挙動が多々起こります。そういった原因がわかっていれば、予めプログラムに追加しておくべきです。

また今回の場合はスイッチはバウシングが起こることが分かっていますので予めディレイを仕込むなどして対策が必要です。

参考書