11月25日発売 書籍『Arduinoと3Dプリンタでロボットを作ろう』を出させて頂きました!

【Arduino入門編⑤】プルアップ・プルダウンって何?デジタル入力の解説です!

これまで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を点灯させるスケッチとなります。

今回新しく出てきた関数として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の内部プルアップ機能を使って書いたスケッチがこちらとなります。

最初のスケッチと変更されている箇所はpinMode関数の部分だけです。(シリアルモニタはもう必要ないのでカットしました)

pinMode関数はこれまでINPUTやOUTPUTで使ってきましたが、これ以外にもINPUT_PULLUPという内部プルアップ機能を有効にする設定ができます。

Arduino内部で端子のプルアップ抵抗を有効にしてくれるモードなので、スイッチが押されていない状態でもちゃんとHIGHが入力された状態となり冒頭のように宙に浮いた状態にはならず動作を安定させる事ができます。

そして回路はこのように接続し直しました。
何も押されていない状態ではプルアップされHIGHの状態となり、スイッチが押されるとLOWとなるようこのようにGNDに接続しています。
回路もかなり簡略化されましたね!

それでは実際にスケッチを動かしてみて下さい。
スイッチが押されるとLEDが消灯し、押されていない状態ではLEDが点灯するのが確認できます。
プルアップ回路なのでスイッチのオンオフとLEDの点灯が逆転しているのがポイントです。

スイッチが押されるとLEDがオフ・・・
何か逆で分かりにくい?
なんて方はスケッチに少し手を加えればいいだけのことですよ!

デジタルピンでの入力にはdigitalRead関数を使う事や、端子を浮いた状態にしないためにプルアップ抵抗やプルダウン抵抗を繋げる、そしてArduinoには内部プルアップ機能があるという事について理解出来れば今回の目標は達成です。

今回使った関数(コマンド)まとめ

関数使用方法
pinMode(pin,mode);Arduino UNOが持っているデジタル入出力ピン(D0~D13)の設定をする。

(書式)pinMode(pin, mode);
pin:設定したいピンの番号
mode:入力[INPUT]、出力[OUTPUT]、プルアップを有効にする場合[INPUT_PULLUP]

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を使い何かを(サーボモーターの制御など)動かすのに便利となります。

その他 Arduino入門編 記事一覧
【Arduino入門編㉛】INA219モジュールで電圧・電流を計測する基本的な方法! 【Arduino入門編㉚】マイコンのデジタル端子(I/O)不足を解消!『I/Oエキスパンダー(MCP23017)』の基本的な使い方! 【Arduino入門編㉙】SPI通信の基礎知識!SPIで使われる信号線や接続方法などについて! 【Arduino入門編㉘】ソフトウェアシリアルを使ってみる! 【Arduino入門編㉗】赤外線(IR)モジュールを使いリモコンの信号を読み取り送受信する方法! 【Arduino入門編㉖】UARTシリアル通信の基礎知識!Arduino間でのデータのやり取りなどをやってみる! 【Arduino入門編㉕】ステッピングモーターを動かしその基礎を理解する!(28BYJ-48 & ULN2003) 【Arduino入門編㉔】Arduinoで7セグメントLEDを制御してみよう!(スタティック制御 / ダイナミック制御) 【Arduino入門編㉓】PCA9685 16チャンネルPWMサーボモータードライバを使って複数のサーボモーターを同時に制御してみる!(最大16台) 【Arduino入門編㉒】ArduinoでDCモーターを制御する。【L298Nデュアルモータードライバ】 【Arduino入門編㉑】温湿度センサー(DHT11)を使い温度と湿度を計測する! 【Arduino入門編⑳】Arduino Uno R3ボードのピン配列&基本機能まとめ! 【Arduino入門編⑲】RTC(リアルタイムクロック)モジュールDS3231を使いシンプルな時計を作る![I2C通信] 【Arduino入門編⑱】I2C通信の基礎!LCDディスプレイに文字を表示させてみる![後編] 【Arduino入門編⑰】LCDディスプレイに文字を表示させてみる![前編][1602 LCDモジュール] 【Arduino入門編⑯】サーボモーターをジョイスティックやシリアルモニタから動かしてみる! 【Arduino入門編⑮】Arduino Unoへの電力供給(外部電源)および電源出力端子の使い方!【追記】 【Arduino入門編⑭】センサーシールド(Sensor Shield)を使ってみる! 【Arduino入門編⑬】テスト環境に便利!Arduino拡張ボード(シールド)プロトタイプシールドを使ってみる! 【Arduino入門編⑫】光センサー(Cdsセル)をアナログ入力ポートで読み取り制御に使ってみる!

1 COMMENT

コメントを残す