PIC AVR 工作室別館 arduinoの館->TopPage->標準機能->デジタル入出力
arduinoのデジタル入出力について
arduinoのデジタル入力は、AT-MEGA168が装備しているデジタル入出力ピンを使って実現されています。 このデジタル入出力機能の概要と使い方、使用上の注意点をまとめていきたいと思います。
arduinoのデジタル入出力機能
デジタル入出力ピンについて
arduinoの0番~13番ピンの14本のピンは、デジタル入出力端子として割り当てられています。 そして、アナログ入力ピンとして割り当てられているアナログ0番~5番もそれぞれデジタル14番~19番として 使用することが可能です。
これらのうち、デジタル0番~13番は(MEGA168のリセット時と同様)デフォルトでデジタル入力ピンに設定されています。 14番~19番はデフォルトでアナログ入力ピンに設定されています。
これらのデジタル入力ピンを出力ピンに切り替えて使ったり、アナログ入力端子をデジタルモードで使うときには ピンモードを切り替えることで使います。
なお、本来AT-MEGA168は各ポート単位(Bポート、Cポート、Dポート)で束ねて一度に入出力することも、 1ピン毎に入出力することも可能なのですが、arduinoでは1ピン毎の入出力しか対応していません。ただ、arduinoの 入出力は通常LEDを1ピン毎にオン/オフするとか、1ピン毎にモーターの制御端子を繋いだりとか、そういった 1ピン単位のアクセスを行う用途が一般的で、ポート単位で束ねて入出力する用途は希でしょう。無くても多分困りません。
デジタル入出力の使い方
arduinoのデジタル入出力の命令について
デジタル入出力を行う関数はarduinoの標準機能に取り込まれています。以下のような3つの簡単な命令、関数で 利用することができます。
ピンの入出力モード設定
pinMode(pin, mode);
ピンモードを入力、もしくは出力に変更する命令です。
pinにはピン番号を、modeには「INPUT」か「OUTPUT」の定数キーワードを指定します。「INPUT」は入力モード、 「OUTPUT」は出力モードともに大文字で指定します。
デジタル0番~13番はデフォルトで入力に設定されています。出力に換える時には各ピン番号とOUTPUTを指定します。 ピン番号に14~19を指定すると、アナログ入力ピンに割り当たっていた各ピンをデジタルピンとして使用することが出来るように なります。
入力モードに設定したピンからの入力
変数 = digitalRead(pin); (戻り値はint型)
各入力ピンから信号を入力します。ピンに高い電圧が入力されている時は変数にHIGHが、低い電圧が入力されている時には 変数にLOWが代入されます。
出力に設定したピンへの出力
digitalWrite(pin, value);
pinで指定した各出力ピンに電圧を出力します。valueにはHIGHかLOWを指定します。HIGHならVcc電圧が、 LOWなら0Vが出力されます。ちなみにVccはDiecimilaなら5Vです。
なお、pinで指定したピンが入力モードになっている時にこのdigitalWriteでHIGHを出力すると、入力プルアップが オンになります。プルアップについては以下をご参照ください。
デジタル入出力端子の電気特性
arduinoのデジタル入出力ピンは、AT-MEGA168の電気特性を引き継いでいます。1ピンあたりに流入/吐き出し (シンク/ソース)が可能な電流は20mAまでです。LEDを光らせる程度なら問題ありません。例えば10mA程度 の電流を流そうと思ったら、出力端子にLEDと500Ω前後の抵抗を直接に繋ぐことで実現できます。まぁ、1kΩ 程度で充分明るく光ると思いますが。
1ピンあたり20mA流せるといっても、すべてのピンに一斉に20mAを流せると言うわけではなく、arduinoの 入出力ピンを数本束ねた単位毎にそれぞれ何mAまで流せるかが決まっています。詳しいことはMEGA168データシートの Electrical Characteristicsページをご参照ください。
あと、入力端子に掛けられる電圧の範囲ですが、(GND-0.5V)~(Vcc+0.5)の範囲内に入っている 必要があります。この範囲を外れるとラッチアップを起こす恐れがあります。
ここで注意が必要なのは、arduinoのVccに電圧がかかっていない時はVcc=0Vなので、入力端子に掛けられる 電圧は-0.5V~+0.5Vまでということになります。つまり、Vccにきちんと電源電圧がかかっていない時に 入力信号が入ってくると故障する恐れがあるということです。今のところこのような事象にめぐり合ったことは幸いにも ありませんが、ただ頭に留めておく必要はあるかとおもいます。
入力モード時のプルアップについて
マイコンの入力ピンは、そのピンに何も接続していない状態だとHIGHかLOWかが決まらない不安定な状態になってしまいます。
その入力ピンからの情報をスケッチ中で入力しないなら大きな混乱は生じないのですが、現実的には後述する貫通電流対策への配慮を する必要もあり、入力端子はHIGHかLOWに固定させるか出力ピンに設定するかどちらかの対応が必要になります。
出力ピンに設定する場合、出力電圧がGND電位かVcc電位どちらかが常時出力されるわけですが、この状態で何らかの機器を 接続した際、仮にその機器も出力モードになっていると出力同士がが衝突…つまりショートして 両方の機器が故障してしまう恐れがあります。もちろん意識していればそんなヘマはしないと思いますが、 ちょっと気を抜いて配線をやり直したときなどに、不意に間違えることが有ります。そんな時に、arduinoから煙が昇って 「お亡くなり」ということになりかねません。
なので、マイコンの入力端子の処置としては通常プルアップ(HIGHに固定)かプルダウン(LOWに固定)が使われます。
arduinoの内蔵プルアップ機能
プルアップやプルダウンは、各入力端子を抵抗を通してVccやGNDに接続することで行います。 ただしarduinoのコアに使われているMEGA168には、入力ピンをプルアップするための機能が内蔵されているので、 これを利用するのが一番簡単でしょう。これを利用することで外付けの抵抗を使わずにプルアップを設定することが出来ます。
このように、内蔵プルアップはMEGA168に内蔵された抵抗と、その有効/無効を切り替えるためのスイッチ(正確にはトランジスタ) で構成されます。
内蔵プルアップ機能の有効/無効を切り替えるのは簡単で、digitalWrite(pin, HIGH); とするだけです。 つまり、入力ピンにHIGHを出力すればオンです。ちなみに、digitalWrite(pin, LOW); としてもプルダウンにはならず、 プルアップ機能がオフになるだけです。ご注意を。
まぁ、そういう私も入力端子を未接続かつプルアップもしないままの状態というスケッチをしょっちゅう作ってしまう のですが、面倒くさがらずにちゃんとやっておいた方が、動作を安定させたり故障を未然に防いだりできます。詳しくは後述の貫通電流 をご参照ください。
スイッチ入力などへの内蔵プルアップの利用
なお、プルアップは未使用入力ピンの処理だけに使われるのではなく、例えばタクトスイッチなどの入力部品を 繋ぐ時にも使われます。
このようなタクトスイッチからの信号をHIGH、LOWに固定するために、プルアップ抵抗がよく使われます。 この場合のプルアップ抵抗は外付けのプルアップ抵抗でもいいのですが、内蔵プルアップ抵抗を利用することも可能です。 ただ、内蔵のプルアップ抵抗はおよそ50kΩと抵抗値が大きいので、スイッチが遠くに離れている場合はノイズの影響を 受けやすくなるため、もう少し小さい抵抗を外付けにしてプルアップした方が安定します。
1つのボード上でタクトスイッチと繋ぐようなときならあまり考慮しなくても大丈夫だと思いますが、ボード上のコネクタから 配線を生やして外付けのボタンスイッチなどに繋ぐような場合は、内蔵プルアップ抵抗では信号が安定しないかもしれません。
なお、プルアップで接続する場合はこのように論理が「負論理」(スイッチオンでLOW、スイッチオフでHIGHが入力される)と なってしまうのですが、なぜプルダウンではなくプルアップが使われるのかは、いろいろ調べてみると幾つかの 理由があるようです。TTL回路を使っていた頃の名残だとか、フェールセーフの観点から故障時にどちらの電位に固定させるべきか…など。 ただ、どれもあまりはっきりとした理由にはなっていない感じです。特にC-MOS ICの場合は。作成する回路によって どうすべきかを都度判断するのが良さそうです。
実際の内部等価回路
上記の各図は、正確な回路図を記したものでは有りません。理解が容易なように簡易的に記したものですので、正確な情報は MEGA168のデータシートをご覧ください。
サンプルスケッチ
サンプルスケッチ LED点灯
デジタル9番ピンに繋いだタクトスイッチからオン/オフを入力し、それをそのままデジタル3番に繋いだLEDに表示 するというスケッチです。このピン配置はreduino-nanoにあわせて設定しているので、お手元のarduinoボードにあわせて 適宜変更して使ってください。
int ledout = 3; int upBtn = 9; int input_data; void setup(){ pinMode(ledout,OUTPUT); pinMode(upBtn,INPUT); digitalWrite(upBtn,HIGH); //setting pull up resistor } void loop(){ input_data = digitalRead(upBtn); digitalWrite(ledout,input_data); }
スケッチの解説
一番のポイントはデジタル9番に繋いだデジタル入力の動作です。
pinMode(upBtn,INPUT); にて入力モードに設定し、次の行のdigitalWrite(upBtn,HIGH); にて内蔵プルアップ抵抗を オンに設定しています。これにより、スイッチがオフの状態ではプルアップ抵抗でHIGHが入力されます。 スイッチがオンの状態ではGNDに接続されてLOWが入力されます。
そして、入力した内容をそのままLEDに出力しています。
内蔵プルアップを使ったスイッチからの入力は負論理になりますが、reduino-nanoのLED(デジタル3番)も 負論理なので、ボタンを押す(LOW入力)と点灯、ボタンを離す(HIGH入力)と消灯になります。
普通のarduinoの場合、デジタル13番に繋がっているLEDは正論理なので、その場合は表示が逆になります。
デジタル入出力の注意点
入力モードの貫通電流
アナログ入力に戻す時の注意点
… 準備中です …