前回はデジタルピンの出力動作としてLOW-HIGH(0-5V)出力とPWM出力について説明した。今回はデジタルピンへの入力とアナログピンへの入力について説明したい。合わせてピンへ入力された電圧をモニタ上に表示する方法についても説明する。
1. デジタルピンへの入力
デジタルピンへの入力は入力された電圧がLOWレベル(0V)かHIGHレベル(5V)のみを判定する。今回は2ピンに0Vあるいは5Vを入力するものとする。回路モデル(下図参照)としては5Vを供給するためにコンポーネント---すべて---から電源を追加した。0Vと5Vを切り替えるためにスライドスイッチを利用し、スライドスイッチが左の場合はGND、右の場合は5Vにつながることで、2ピンが浮く(何もつがなっていない)状態を防いでいる。Tinkercadの電源は、特に説明には書かれていないが、定電圧・定電流電源と考えてよさそう。(詳細は電流源:定電圧電源と定電流電源:1.定電圧電源(CVモード)|エヌエフ回路設計ブロック)電源をクリックして電圧を5V、電流を例えば0.05A(50mA)に設定しておく。本来の使い方としては、定電圧モードCVでは5Vになるように電源は出力電流を制御するものだが、便利な使い方としては、電流は50mA以上流れないのでショートや過剰電流による機器の破損を防ぐことができる。(シミュレーション上ではあまり関係ないが)あとGND側は念のために200Ω抵抗を入れている。
2. デジタルピンへの入力電圧の読み出し
次にデジタルピン2へ入力されている電圧、LOWレベルまたはHIGHレベルの読み出すためのスケッチについて説明する。まず、2ピンを読み込みにするためpinMode(2, INPUT_PULLUP);
とする。今回の回路はスイッチをどちらに切り替えても2ピンが浮くことはないので、モードはINPUT_PULLUPあるいはINPUTでもよい。(浮いてしまうようであればpinMode()
でINPUT_PULLUP
を指定すればよい) 2ピンから入力電圧を読み出した結果を格納する変数をvalとしてint型であらかじめ定義しておく。2ピンの入力の読み出しはval=digitalRead(2);
とする。入力がLOWレベルの場合0、HIGHレベルの場合1を返す。val
の表示としてシリアルモニタ上に表示することとする。(PCに接続せずスタンドアローンで動作させる場合は、LED点灯やLCDに表示すること等が考えらえる) シリアルモニタに表示するにはシリアル通信の設定をする必要がある。今回はモニタ表示のみの説明に絞り、シリアル通信の詳細は今後とする。void setup()
内でSerial.begin(9600);
とすることでシリアル通信を開始することができる。Serial.begin(9600)
はボーレートを9600bpsに設定している。valの値をシリアルモニタ上に表示するにはloop関数内にSerial.println(val);
とすればvalの値がシリアルモニタ上に表示される。なおSerial.print(val);
とすると改行が入らない。最後に待機delay(1000);
とすることで1秒ごとに2ピンの入力をシリアルモニタ上に表示する。スケッチ全体は
int val; void setup(){ pinMode(2, INPUT_PULLUP); Serial.begin(9600); } void loop(){ val=digitalRead(2); Serial.println(val); delay(1000); }
Tinkercad上でシリアルモニタを表示させるには、"コード"を表示させた状態で一番下のシリアルモニタをクリックすると、モニター表示、入力窓、入力の送信ボタン、モニタ表示のクリアボタンがあらわれる。(下図参照)
シリアルモニタが表示された状態でシミュレーションを実行した結果を示す。シミュレーション実行中にスライドスイッチをクリックするとスイッチが切り替わり、それに応じてシリアルモニタ上に"0"(LOW:0V入力)または"1"(HIGH:5V入力)が表示される。なおLOW/HIGHの電圧範囲は、電源の電圧を5V以外に変えてみると、Tinkercadのシミュレーション上では2.4V以上をHIGHと判定する。
3. アナログピンへの入力
デジタルピンへの入力ではLOWレベルとHIGHレベルのどちらかを読み出したが、アナログピンへ入力することで0~5Vを10bit分解能(0~1023)で読み出すことができる。Arduino UnoではアナログピンはA0~A5に割り当てられている。今回はデジタルピンへの入力で用いた電源の出力を直接A0ピンに入力することにする。(過剰電流が生じる恐れがあれば抵抗を入れればよい)A0に入力された電圧を読み出すにはanalogRead(A0);
とすると5Vまでの電圧に応じて0~1023の範囲の数値を返す。5V以上は一律で1023になるが、実際には入力範囲を超える電圧は破損する可能性があるのでレギュレータ等で5V以上にならないようにする。スケッチは以下のようにした。
float val; void setup(){ Serial.begin(9600); } void loop(){ val=analogRead(A0); Serial.print(int(val)); Serial.print(" :"); Serial.print(val*5/1023); Serial.println(" V"); delay(1000); }
A0の入力に応じた0~1023までの数値と、電圧Vに換算した数値をシリアルモニタ上に表示するようにしている。実行例は下のようになる。実行中に電源の電圧ノブを回して電圧を変えると、それに応じてシリアルモニタの電圧表示が変化する。
4. INPUTとINPUT_PULLUPの違い
デジタル入力のところで、pinMode()
で指定するINPUT
とINPUT_PULLUP
の違いについて補足する。PULLUP抵抗はHIGH側(5V)に入っている抵抗で入力端子が何もつながっていないときに5Vとなる。(例えば
プルアップ抵抗、プルダウン抵抗 | 物を作る者を参照。)下の一番左の回路は、ピン2の入力をINPUT_PULLUP
にするとボタンを押下時"0"、ボタンを離すと"1"を返す。(スケッチは上記デジタルピン入力のもの)真ん中の回路はピン2をINPUT
とすると左の回路と等価になり、ボタン押下時に"0"、ボタンを離すと"1"を返す。一番右の回路はボタン押下時の"1"、ボタンを離すと不定(Tinkercadでシミュレーションを実行すると"1"を返す)となるので動作しない。INPUT_PULLUP
により外部の抵抗が不要になり回路がシンプルになるというメリットがある。
5. まとめ
今回はデジタルピンおよびアナログピンへの入力動作について説明した。デジタルピンやアナログピンにセンサ等を接続して、今回のスケッチを利用すればArduinoを用いてセンサ情報を取得することが可能である。次回はシリアル通信についてもう少し触れてみようと思う。