これまでArduino UNOを使いデジタル出力・アナログ出力(PWM)の話をやってきました。
出力先としてはまだLEDを点灯させることしかやっていないため少し地味なのですが、もう少し基本をやっていきたいと思います。
そうです出力とくれば、あと入力についての話が残っています。
アナログ入力とデジタル入力の話をしたいと思いますが、今回はデジタル入力の話に限定したいと思います。
これまでデジタル入出力ピン(Arduino UNOの場合D0~D13までの14本)をpinMode関数を使い出力に設定しdigitalWrite関数を使い実際に出力させていました。
今回はそのデジタル入出力ピンを入力(INPUT)に設定し入力ピンとして機能するようにしてみたいと思います。
デジタル入力といえばセンサーからのパルスを入力したりいろいろ利用されますが、今回はタクトスイッチと呼ばれる押せば接点が接触、離せば開放されONとOFFを切り替える最も基本的なスイッチを使って解説していこうと思います。
スイッチによる単純なONとOFFの読み取りとなりますが、ここで非常に重要なプルアップやプルダウンの話が出てきますので踏まえてご紹介したいと思います。
目次
【Arduino】デジタル入力におけるプルアップ・プルダウンについて!
今回の目標
タクトスイッチを使いそのON/OFFによりLEDを点灯や消灯させてみたいと思います。
スイッチからのON/OFFつまりHIGH(5V)かLOW(0V)の読み取りなので、デジタル入出力端子(D0~D13)を入力(INPUT)に設定すれば簡単に出来そうですが・・・
しかしそう簡単に動いてくれないのがデジタルの世界!
タクトスイッチのような単純なスイッチでは、スイッチが押されている状態ではArduinoの入力側に繋がり何かしらの電圧がかかった状態となります。
しかしスイッチが押されていない状態、つまりスイッチの接点が離れた状態ではArduinoの入力側には何も繋がれていない状態となります。
この何も繋がれていない状態は実は0Vではなく、宙に浮いた状態(フローティングと呼ばれます)となりデジタル回路において不安定な状態となります。
デジタル入力において入力端子がこのように宙に浮いた状態(不安定な状態)を避けるため、プルアップ抵抗やプルダウン抵抗といったものを繋いで安定させてあげる必要があります。
またArduinoの場合、内部プルアップ機能を有効にすることにより実際に繋ぐ抵抗を省略することも出来ます。
このあたり、今回理解できればと思います。
【失敗例】Arduino入力ピンにタクトスイッチを直接繋げてみる!(プルアップ・プルダウン抵抗なし)
まずはまだご説明していないプルアップ抵抗やプルダウン抵抗というものを入れないで回路を組んでみたいと思います。
これは完全に失敗例となります。
それでは回路を組んでみます。
Arduinoから取った5V電源がタクトスイッチを介しデジタルピン8に入力しています。
スイッチが押されている場合にはArduinoの入力ピンに電圧がかかり、スイッチが押されていない場合には遮断され0Vになるように接続しています。
簡単な回路で、まず思い浮かぶのがこの回路だと思います。(何度も言いますが失敗例です)
今回スイッチが押された状態を確認しやすくするためLEDも1本取り付けました。
そして使用スケッチはこちら。
タクトスイッチが押されたらそのHIGH or LOWを判別し13番ピンに繋いだLEDを点灯させるスケッチとなります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | // Arduino入門編⑤ デジタル入力 プルアップ・プルダウンについて // https://burariweb.info int LED_PIN = 13; // 13番ピンをLEDに割り当て int INPUT_PIN = 8; // タクトスイッチからの入力を8番ピンに割り当て int val; void setup(){ pinMode(LED_PIN, OUTPUT); // LEDに繋いだピンを出力に設定 pinMode(INPUT_PIN, INPUT); // タクトスイッチに繋いだピンを入力に設定 Serial.begin(9600); // シリアル通信を有効に } void loop(){ val = digitalRead(INPUT_PIN); // 入力ピン(タクトスイッチ)の状態を読み取る digitalWrite(LED_PIN, val); // 入力ピンの状態によりLEDの点灯・消灯 Serial.println(val); // シリアルモニタに入力ピンの状態を出力 } |
今回新しく出てきた関数としてdigitalRead関数があります。
これが今回やろうとしているスイッチのON/OFFの判定、つまりHIGHかLOWの状態を読み取る関数となります。
これまでLEDを点灯させる場合、pinMode関数を使いピンを出力(OUTPUT)に設定しdigitalWrite関数を使って実際に出力させてLEDを点灯させました。
今回はそれの入力版となります。
デジタルピンは入出力で使えるので、pinMode関数で入力(INPUT)指定すると入力端子として使えるようになります。
そしてその値を読み取るのがdigitalRead関数となります。
pinMode 関数
Arduino UNOが持っているデジタル入出力ピン(D0~D13)の設定をする。
(書式)pinMode(pin, mode);
pin:設定したいピンの番号
mode:入力[INPUT]、出力[OUTPUT]、プルアップ[INPUT_PULLUP]
digitalRead 関数
指定したピンの値(HIGH or LOW)を読み取ります。
事前にpinMode関数で入力(INPUT)に設定しておく必要があります。
(書式)digitalRead(pin);
pin:読み取りたいピン番号
今回スイッチの入力状態を少し分かりやすくするためシリアルモニタを使いました。
デジタルピンに入力された値(スイッチのオンオフ)をPC上でHIGH(1)またはLOW(0)として確認出来るようにしています。
今回はPC上でスイッチの状態(ON/OFF)を確認できるんだ!程度でいいと思います。
Serial.begin(speed);
シリアル通信を有効にします。
シリアル通信のデータ転送レート(bps)を指定します。
(300, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, 115200bps)
Serial.println(data) ;
データをシリアルポートへ出力します。
つまりPCのシリアルモニタに出力し表示させます。(改行付き)
スケッチを動かしてみる
それでは実際に上記スケッチを動かしてみて下さい。
普通に?考えるとスイッチが押されていない状態ではLEDは消灯、スイッチが押されたらLEDが点灯する・・・はずですが・・・?
あれ?どうもおかしいですね?
スイッチが押されていない場合でもLEDがチカチカと点灯しています。
シリアルモニタで入力ピンの状態を確認してみましょう。
下の部分を押すとシリアルモニタが立ち上がります。
今回データ転送レートはスケッチ内で9600bpsとしていいるのでこれに合わせて下さい!
digitalRead関数で読み取った値(スイッチのON/OFFの状態)を表示させています。
スイッチが押された状態ではシリアルモニターには常に”1”が出力されLEDも点灯しています。
しかし押されていない状態では”0”と”1”が不規則に入力されているのが分かります。
LEDもチカチカと点滅しています。
冒頭で述べましたが、スイッチが押されていない状態ではArduinoの入力ピンに何もつながっていない状態(宙に浮いた状態)となり不安定な動作となっています。
アナログ回路のようにスイッチを押したら点灯、離せば消えるのようにはならずデジタル回路では少し工夫が必要なようです!
プルアップ・プルダウンとは?
先程確認できましたが、入力端子に何も繋がれていない状態(浮いた状態)ではその動作が不安定となります。
そこで何も繋がれていない状態をなくすために、プルアップやプルダウンという方法が使われます。
つまりスイッチの場合、何も押されていない状態(スイッチの接点が離れている状態)でも確実にHIGHかLOWを識別できる電圧をArduino側に入力してあげるという事です。
簡単に言うと抵抗を1本使い入力側に何かしらの電圧がかかった状態にするというものです。
その抵抗のことをプルアップで使えばプルアップ抵抗、またプルダウンで使えばプルダウン抵抗と呼びます。
それではプルアップ回路・プルダウン回路を見てみましょう。
プルアップの基本的な回路とその動作
プルアップ回路の基本的な接続方法はこのようになります。
ご覧の通り、Arduinoの入力端子には抵抗を通して5V(HIGH)の電圧が常にかかった状態となり、GND(マイナス)との間にスイッチが設けられています。
このような接続では、通常何も押されていない状態ではArduinoの入力ピンには5Vが供給されHIGH状態となっています。
そしてスイッチが押されるとGNDに接続されることによりArduinoの入力ピンは0V(LOW)となります。(抵抗を介しているので短絡にはなりません)
これがプルアップ回路となり、使われている抵抗をプルアップ抵抗といいます。
先程使った回路に10kΩ程の抵抗を1本追加し以下のように接続し直してみて下さい。(スケッチはそのままでOK)
この回路ではスイッチが押されていない状態ではArduinoは”HIGH”として認識しLEDが点灯します。
スイッチが押されると”LOW”として認識されLEDが消灯します。
今回はちゃんとHIGHとLOWの識別が出来ていますね!
これがプルアップ回路となります。
プルアップ回路ではスイッチが押されている場合Arduino入力端子が0(LOW)となり、押されていない場合に1(HIGH)となります。
この反転しているのところがポイントとなります。
プルダウンの基本的な回路とその動作
先程のプルアップ回路の抵抗とスイッチを接続する位置を入れ替えるとプルダウン回路となります。
プルダウン回路の基本的な接続方法はこのようになります。
スイッチがOFFのときArduinoの入力端子は抵抗を介しGNDとつながっているのでLOWとなります。
そしてスイッチが押されるとVccと繋がるのでHIGHの5Vを認識します。
先程の回路をこのように接続し直しました。(スケッチはそのままです)
そして実際にスケッチを動かしてみて下さい。
こちらのプルダウン回路では、スイッチが押されるとLEDが点灯し離すと消灯する動作となることが確認できます。
こちも問題なく動作しましたね!
プルアップ回路・プルダウン回路は抵抗とスイッチの位置が入れ替わっているだけですが、スイッチが押された時の動作が反転する点がポイントとなり注意が必要です。
スイッチ | Arduino入力端子 | |
プルアップ回路 | ON(OFF) | OFF(ON) |
プルダウン回路 | ON(OFF) | ON(OFF) |
Arduinoの内部プルアップ機能を使ってみる
以上、プルアップ回路やプルダウン回路を使う事により入力端子が開放された状態がなくなり安定して動作させることが出来るようになりました。
しかしArduinoには内部のマイコンチップが内部抵抗をプルアップさせる便利な機能があります。
マイコン内部でプルアップ抵抗を有効にしてくれるので、先程説明したようにプルアップ抵抗を外部に接続する手間が省けます。
Arduino のマイコンチップ内でプルアップ抵抗が繋がったこのようなイメージとなります。
便利な機能です!
これでわざわざプルアップ用の抵抗を用意する必要がなく部品点数が減ります。
そして回路も簡略化することが出来ます。
今回こちらの項目から説明してもよかったのですが、今後プルアップやプルダウンという考え方は何度も出てくる重要な考えとなります。
本記事内でちゃんと理解して頂ければと思います。
そしてArduinoの内部プルアップ機能を使って書いたスケッチがこちらとなります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | // Arduino入門編⑤ デジタル入力 内部プルアップを有効 // https://burariweb.info int LED_PIN = 13; // 13ピンをLEDに割り当て int INPUT_PIN = 8; // タクトスイッチからの入力を8ピンに割り当て int val; void setup(){ pinMode(LED_PIN, OUTPUT); // LEDに繋いだピンを出力に設定 pinMode(INPUT_PIN, INPUT_PULLUP); // タクトスイッチに繋いだピンを入力に設定 } void loop(){ val = digitalRead(INPUT_PIN); // 入力ピン(タクトスイッチ)の状態を読み取る digitalWrite(LED_PIN, val); // 入力ピンの状態によりLEDの点灯・消灯 } |
最初のスケッチと変更されている箇所はpinMode関数の部分だけです。(シリアルモニタはもう必要ないのでカットしました)
12 | pinMode(INPUT_PIN, INPUT_PULLUP); // タクトスイッチに繋いだピンを入力に設定 |
pinMode関数はこれまでINPUTやOUTPUTで使ってきましたが、これ以外にもINPUT_PULLUPという内部プルアップ機能を有効にする設定ができます。
Arduino内部で端子のプルアップ抵抗を有効にしてくれるモードなので、スイッチが押されていない状態でもちゃんとHIGHが入力された状態となり冒頭のように宙に浮いた状態にはならず動作を安定させる事ができます。
そして回路はこのように接続し直しました。
何も押されていない状態ではプルアップされHIGHの状態となり、スイッチが押されるとLOWとなるようこのようにGNDに接続しています。
回路もかなり簡略化されましたね!
それでは実際にスケッチを動かしてみて下さい。
スイッチが押されるとLEDが消灯し、押されていない状態ではLEDが点灯するのが確認できます。
プルアップ回路なのでスイッチのオンオフとLEDの点灯が逆転しているのがポイントです。
スイッチが押されるとLEDがオフ・・・
何か逆で分かりにくい?
なんて方はスケッチに少し手を加えればいいだけのことですよ!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | // Arduino入門編⑤ デジタル入力 内部プルアップを有効 // https://burariweb.info int LED_PIN = 13; // 13ピンをLEDに割り当て int INPUT_PIN = 8; // タクトスイッチからの入力を8ピンに割り当て int val; void setup(){ pinMode(LED_PIN, OUTPUT); // LEDに繋いだピンを出力に設定 pinMode(INPUT_PIN, INPUT_PULLUP); // タクトスイッチに繋いだピンを入力に設定 } void loop(){ val = digitalRead(INPUT_PIN); // 入力ピン(タクトスイッチ)の状態を読み取る if(val == 0 ){ digitalWrite(LED_PIN, HIGH); // スイッチが押されるとLEDが点灯するように変更 } else { digitalWrite(LED_PIN, LOW); } } |
デジタルピンでの入力にはdigitalRead関数を使う事や、端子を浮いた状態にしないためにプルアップ抵抗やプルダウン抵抗を繋げる、そしてArduinoには内部プルアップ機能があるという事について理解出来れば今回の目標は達成です。
今回使った関数(コマンド)まとめ
関数 | 使用方法 |
pinMode(pin,mode); | Arduino UNOが持っているデジタル入出力ピン(D0~D13)の設定をする。 (書式)pinMode(pin, mode); |
digitalRead(pin); | 指定したピンの値(HIGH or LOW)を読み取ります。 事前にpinMode関数で入力(INPUT)を設定しておく必要があります。 |
Serial.begin(speed); | シリアル通信を有効にします。 シリアル通信のデータ転送レート(bps)を指定します。 (300, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, 115200bps) |
Serial.println(data) ; | データをシリアルポートへ出力します。 PCのシリアルモニタに表示させ確認できます。(改行付き) |
今回使ったパーツ
Arduino UNO
Arduinoはオープンソースのハードウェアなので正規品以外にも互換品が多数メーカーから販売されています。
互換品でも正規品と比べて特に問題なく使用でき数百円程度で購入が可能なのでArduino学習用としていいですね!
Arduino スターターキット
これからArduino学習を進めていくにあたりArduino UNO(互換品)やブレッドボード、ジャンパーピンなどがセットになったスターターキットが販売されています。
私はGeekcreit製のスターターキットを使っていますが、ELEGOO製のものは国内Amazonなどでも購入可能で人気があるようです。(セット内容はほぼ同じです!)
そしてELEGOOのサイトからスターターキット用サンプルスケッチのダウンロードも可能です。(Geekcreitのキットでも使えます)
参考 チュートリアルダウンロードELEGOO基本的にこれからこのセットで出来るものから紹介していこうと考えていますが、かなり多くのことが出来ます。
電子工作を始めるにはまずブレッドボードやジャンパーピン、メインとなるArduino UNOやサーボ、LEDなどの基本的なパーツがないと実際に動かすことが出来ませんが、個々にパーツを購入して回路を組んでとなるとかなりの手間がかかります。
スターターキットがあればArduinoの初歩的なことはかなりの数こなすことが出来るのでオススメです!
そこからスキルアップに伴い個別でセンサーなど必要なものを増やしていくのがいいと思います。
今回使ったタクトスイッチももちろんスターターキットの付属品に含まれています。
抵抗セット
抵抗は使用頻度が高いパーツの1つです。
こちらも1000本ほど入ったセットが数百円程度で売られているので1セット持っておくとこれから便利になるかと思います。
上記Arduinoスターターキットにもある程度の数(正確な本数数えてなくてすいません)入っており、LEDの制限抵抗としてやプルアップ・プルダウン用抵抗として使えます。
ブレッドボードを使い複数の回路を組んで同時にいろいろと試して・・・なんてやってると、やはり本数的にたくさん手元にあった方がいいと思います。
タクトスイッチ
タクトスイッチは単純なON/OFFをするためのスイッチとなりますが電子工作では使用頻度が高いパーツとなります。
上記Arduinoスターターキットにも同封されています。
形状やサイズなど種類も様々なものが販売されています。
地味な基盤をスイッチカバーの色を変えてカラフルに・・・色々と遊べます!
今回のポイント
- デジタル端子からの入力読み取りはdigitalRead関数を使う!(HIGH or LOWの判別)
- 入力端子が浮いた状態になるのを防ぐためプルアップやプルダウン回路を使う!
- Arduinoには内部プルアップ抵抗を有効にする機能が付いている!(pinMode関数でINPUT_PULLUPを指定)
最後に!
今回、digitalRead関数を使いデジタルピンからスイッチの状態を読み取りON/OFFの判定を行ってみました。
デジタル入力は今後センサーなどの情報を受け取る場合に使う事も出来ます。
電子工作でよく使われるタクトスイッチを例として使いましたが、プルアップやプルダウンについて理解する事が非常に重要となる事が分かりました。
またプルアップに関してはArduino学習を進めていくにあたり今後いろいろと出てきます。(I2C通信のSCL・SDAのプルアップなど)
はじめは少し取っ付きにくいですが、今回の内容を実際に回路を組み何度も試して理解を深めて下さい!
今回デジタルでの入力を行いました。
次回は可変抵抗(ボリュームなど)を使ったアナログ入力についてやってみたいと思います。
これを使えばジョイスティックなどアナログ値の入力が可能となりArduinoを使い何かを(サーボモーターの制御など)動かすのに便利となります。
[…] This website is also informative for a basic understanding of the tactile switch program. […]
[…] 【Arduino入門編⑤】プルアップ・プルダウンって何? […]