Blinkから始まるArduino入門 その2 pinMode()

 前回、Lチカを行うためにサンプル・スケッチBlinkを動かしました。初めてプログラムを作るときは、サンプルをまねながら学習するとよいでしょう。Blinkのスケッチの中を見ていきます。

setup()内で記述する

 Arduino UNOには、ディジタル入出力ポートは0~13番があります。どのポートを使うのも自由です。前回のBlinkでは内蔵のLEDがつながった13番ピンを使いました。0番と1番は、UARTという調歩同期式シリアル通信用に決め打ちで使われるので、ふつうは避けます。

void setup() {
pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
digitalWrite(LED_BUILTIN, HIGH);
delay(1000);
digitalWrite(LED_BUILTIN, LOW);
delay(1000);
}

 setup()内は一度だけ実行されます。

pinMode(LED_BUILTIN, OUTPUT);

は、pinMode(13,1);とも書けます。pinmode(13,1);だと「error: 'pinmode' was not declared in this scope」というエラーが出ます。'M'は大文字です。pinMode()はArduinoが用意した関数なので、どの場所でも記述できますが、関数の中で使います。ここでは一度設定すればいいので、setup()内に記述します。

 loop()内に書いてもOKですし、同じピンを入力もしくは出力に変更することも可能です(使ったことがない)。

 何を設定しているかというと、Arduino UNOでは13番ピンを出力に使う、です。13番ピンは入力にも使えるから、出力に使うという宣言をします。自分でつけた関数名や変数名は大文字や小文字は自由に使えますが、システム側で用意した関数名はそのとおりに入力します。前回、変数名の名前は自由につけられると説明しましたが、数字から始めるのはだめです。

オリジナルなBlinkに挑戦

 では最初からLEDのつながっている13番ではなく0番ピンを使いましょう。0番には何もつながっていません。0番はATMega328のデータシートによると、

  • PD0(ポートDのビット0)
  • PCINT16(ピン変化割り込み要求)
  • RXD(USART受信データ入力)

の機能が利用できます。ポートのピン内部回路は次の構成です。ATMega328にはポートが、PC0~PC7、PB0~PB7、PD0~PD7の3組23本あります。ポートのいくつかは、さらに、タイマやA-Dコンバータの機能ブロックがつながります。

 ポートは、入力と出力のどちらでも使えます。入力に使うときの記述方法には二通りあります。

pinMode(0,INPUT);
pinMode(0,INPUT_PULLUP);

 プルアップとは、たとえば10~20kΩぐらいの抵抗で電源電圧につなぐことを指します。プルダウンは10kΩぐらいの抵抗でGNDにつなぐことを指します。抵抗をつなぐと電流が少し流れますが、何も入力や出力がないとき、HIGHかLOW状態を維持できます。そうでないとき、HIGHとLOWが外部のノイズなどでパタパタと入れ替わる現象が起こる場合があります。

 回路図では次のように書きます。抵抗の回路図記号は古い規格で、今のJISは長方形で表します。でも、多くのユーザが新しい規格に従っているわけではありません。

 出力をプルアップするのは、回路がオープン・ドレインになっているときが多いです。INPUT_PULLUPは、IC内部でプルアップしています。ICの外に抵抗をつけずに済みます。

抵抗値はオームの法則で計算できる

 13番ピンにLEDがつながっていると説明しました。Arduino UNOの回路図を見ます。Yellowと書かれているLEDは、オレンジ色に近い発色です。

 天地が逆なので書き直すと次の回路になります。回路図では抵抗1kΩが並列に2個入っていたので、計算すると500Ωです。

 LEDと直列に入る抵抗を「電流制限抵抗」と呼びます。入れなくてよい場合がありますが、ほとんどの場合入れます。

抵抗の読み方

 携帯電話やスマホの小型化のために、抵抗はチップ・タイプが主流ですが、とても小さいです。ピンセットではさもうとしたら、どこかに飛んでいきます。製造現場でプリント基板の上に自動機で部品を並べやすくするために、抵抗やコンデンサはリールという形態で販売されています。電子工作ユーザは、リールで購入すると、孫子の代まで相続することになるので、人が手作業で10個単位などにはさみで切り離したものを入手します。

 1リールには3千個ほどの抵抗が入っています。たぶん、1リール数百円です。1個当たり、単位がわからないくらい安いです。部品の表面には103と書いてあれば10kΩです。プルアップ抵抗などによく見ます。204は20MΩです。読み方は、Mega Ohmというつづりなので、Ohmが母音で始まるためその前のaはなくしてMeg Ohm=メグ・オームです。筆者は欧米人の発音を聞いたことがないので、本当はどう発音しているか知りません。

 電子工作ではリード付きパーツをメインに使います。利用する抵抗にも様々な規格があります。

  • 電力 1/6W、1/4W、1/2W
  • 許容差 ±10%、±5%、±1%

 電力を扱わない回路では、上記のどれを使ってもかまいません。1/2W 100Ωであれば、形状はこれらの中では大きめで、少し電流が流れる場所に使います。次の写真は大きさの見本です。炭素皮膜抵抗はカーボン、金属皮膜抵抗はキンピと呼ぶことがあります。

 許容量±1%は、抵抗の値を測ると、標準偏差の95%?内にばらつくということです。ただし、ガウス曲線のような分布にはなっていないです。100kΩを100本測ると、90本が99.5kΩだったりします。

 5本線のカラー・コードは、色が判別できないのが普通です。どちら側が第1線かもわからない製品も一般的です。なので、DMM(テスタ)で確認しましょう。その時間を惜しむのはとても不合理です。

抵抗値の求め方

 前置きが長くなりましたが、電流制限抵抗の値を求めます。

 電源電圧が5Vのとき、計算が苦手の方は1kΩにしましょう。そうやって適当に1kΩにすると、部品箱から1kΩだけがすぐになくなってしまいます。E12系列であれば820Ωか1.2kΩがあるのでそれでかまいません。アマゾンなどで、いろいろ入って600円とかいう抵抗セットを購入すると、820Ωなんて絶対に使われないですから。系列という言葉は、抵抗の値がどのようなとびとびの値になっているかを表しています。E96系列のような細かい値の抵抗は入手困難です。設計者は、通常E12系列の抵抗(1.0、1.2、1.5、1.8、2.2、2.7、3.3、3.9、4.7、5.6、6.8、8.2)を使います。

 なぜこんなにいいかげんか。それは、計算するうえで必要な「順方向電圧Vf」が製造会社や年代によって大きく異なるからです。最初に作られた赤色LEDの順方向電圧Vfが今最新の製品と成分が異ななります。LEDの光りの発生は、電圧をかけたときのバンドギャップによって放出されるエネルギーによって異なります。より効率よく光らせようと研究開発した結果、使われる素材が10年前と大きく変わりました。したがって最初1.7V付近だったVfは2.0V付近になりました。緑色も同じです。青色はもともと3.0Vぐらいです。ご存知のとおり、青色LEDが実用になったのはつい最近のことです。

 次の回路で計算します。電源電圧は5Vです。Vf=n[V]のLEDで[n]mA流すとします。抵抗Rの両端には5[V] - Vf[V]の電圧がかかります。

  • Vf=1.7VのLEDで20mA流します。抵抗Rは85Ωです。
  • Vf=1.7VのLEDで2mA流します。抵抗Rは850Ωです。
  • Vf=3.0VのLEDで5mA流します。抵抗Rは600Ωです。
  • Vf=3.0VのLEDで20mA流します。抵抗Rは150Ωです。

 電流を多く流したほうが明るいですが、明るすぎるのは、展示会以外では不要です。電流と明るさは製品によってとても異なります。そして、10年前の高輝度LEDはいまの普及品より暗かったりします。

 では確認しましょう。 

 青色LEDに820Ωの抵抗を直列につなぎます。Vfは3.0Vぐらいなので、抵抗の両端にかかる電圧は2.0Vです。オームの法則から、電流は、

  愛はいじわーる I = E / R 
  2.0[V] / 820[Ω] = 2.4[mA]

 Vfが1.7Vである赤色であれば、抵抗の両端にかかる電圧は3.3Vです。オームの法則から、電流は、

  3.3[V] / 820[Ω] = 4[mA]

  

 妥当な抵抗値だったことがわかります。1.2kΩであれば少し電流が少なくなるので、明るさは減るかもしれません。次のグラフは、10年前の白色LEDと最近の青色LEDの電圧と電流の特性です。白色は青色LEDが中に入っています。電流がたくさん流れるからといって、どんどん明るくなるわけではなく、どこかで飽和します。

 このグラフで、Vfはいくらかは不明です。メーカによってもどの点をVfと呼んでいるかは不明です。

接続

 Arduino UNOのUSBケーブルを外します。配線中、電源はOFFするのが原則です。

 空中配線をします。抵抗とLEDのリード線をきつく指先でねじります。LEDのリード線の長いほうがアノードです。反対側はカソードです。アノードは電位の高いほうをつなぎます。回路図では、アノードに抵抗がつながります。抵抗はどちら側のリード線をつないでもかまいません。

 抵抗の空いているほうをArduinoの0番へ挿し込みます。LEDのカソード(短いほう)をGND(グラウンド)へ挿し込みます。GNDは同じ列のほうが近いです。0番はディジタル出力に設定するので、0Vか5Vの電圧が発生します。5VのときにLEDに電流が流れ、光ります。

 終わったら、回路図と見比べて、勘違いしていないか確認します。電子工作で動かないのは、ほとんど100%、自分は間違っていないという思い込みです。LEDの長いほうが抵抗につながって0番にささっていますか。LEDのカーソードをGNDに挿したつもりなのに抜けかかっていませんか。

 Arduino UNOのUSBケーブルをつなぎます。UART信号のデフォルトはHIGHなので、点灯します。

スケッチの確認

 変数LED_BUILTINを0に書き換えました。

void setup() {
pinMode(0, OUTPUT);
}

void loop() {
digitalWrite(0, HIGH);
delay(1000);
digitalWrite(0, LOW);
delay(1000);
}

 スケッチをコンパイルしてマイコンに書き込み、完了するとLEDが1秒おきに点灯を繰り返します。loop()に書かれているので、電源が入っている限り点滅は続きます。もし、点滅の部分をsetup()に持っていくとどうなるでしょうか。

void setup() {
pinMode(0, OUTPUT);
digitalWrite(0, HIGH);
delay(1000);
digitalWrite(0, LOW);
delay(1000);
}

void loop() {
}

 1秒だけLEDが点灯して、消えます。もともと点灯しているので、書き込みが完了したらLEDが消えてしまいます。この場合でも、loop()関数は必要です。

もっと楽がしたい

 電流制限用抵抗を入れないでLEDを0番につなぐとどうなるでしょうか。名前のとおり電流を制限しないので、Vf以上の電圧をかけると電流がどばっと流れます。Arduino UNOのディジタル端子は20mAの電流の流れだしもしくは吸い込みができます。

 電流が流れると誰もリミットをかけてくれません。内部回路の許すかぎりに、流れ続け、多くはそのポートのトランジスタが焼け、その周りも焼けてしまうかもしれません。0.1秒ほどの瞬間ならダメージがないかもしれません。USBケーブルをつないで電源5Vを供給しているのであれば500mAで制限がかかるかもしれませんが、期待はできません。

 先ほど電流制限抵抗の値を計算しました。わりとアバウトなのがわかります。なので、電流制限抵抗入りLEDを購入しましょう。配線もすっきりですよ。

(※)コンパイルして実行プログラムをマイコンに書き込むと説明していますが、コンパイルはオブジェクト・コードを作るだけです。そのあとリンカがライブラリなどを合体し、定数はROM領域へ変数はRAM領域へそれぞれ整理し、バイナリ・コードを作成します。ここまでの一連の動作をビルドという場合があります。それをテキストのIntel HEXで書き込みます(たぶん)。

(※)0~13番ピンがpinMode()で入力か出力に使えるように書きましたが、アナログのA0ピンはどうなのでしょうか。ATMega328のデータシートを見ます。

  • PC0(ポートCのビット0)
  • PCINT8(ピン変化割り込み要求)
  • ADC0(アナログ入力0)

 ディジタル入出力に使えますね。ADC0(A0番)からADC5(A5番)はPC0からPC5なので、いずれもArduion UNOの電源が入った後、ファームウェアがピンの初期設定時にアナログ入力に設定していると思われます。pinMode()でディジタル入出力に設定しなおすことができます。A0ピンは14番、A5ピンは19番ピンです。一度ディジタル出力に使ったピンをそのままanalogRead()しても正しく動作しません。一度プルアップなしの入力に変更してからanalogRead()します。

 6本のアナログ入力のうち0~3のいくつかをディジタル入出力に使うと、この記事のように、影響を受けて、正しいA-D変換ができないことがあるようです。4番と5番はI2C用にも使う設定なので、影響がないそうです。

 0~13番のディジタル入出力でピン数が足りないときはA0~A5をディジタル入出力に流用できるけれど、一部アナログ入力を使うときは、どのピンを利用するかは、アナログの値を読んで、ディジタル・ピンの変化の影響を受けてアナログ値が変になっていないかを確かめてから使ってください。

前へ

Blinkから始まるArduino入門 その1 ハードは何使う

次へ

Blinkから始まるArduino入門 その3 定数と変数