MAKER UNO + で始めるSTEM (6) アナログ入力
●アナログ入力を試す
ピンヘッダのA0~A5がアナログ入力です。電線を用意し、3か所接続します。
- A0をGNDへ
- A1を5Vへ
- A2を3.3Vへ
電線は0.3~0.5mmΦの単線が便利です。細い線がよってある撚線は、このような用途には不向きです。ブレッドボードで配線に用いるジャンパ線を使うのが便利です。ジャンパ線はオス-オスです。
入力端子を電源につないだら、壊れるのではないかという疑問が出ます。マイコンのI/O端子は入力モードにしているときはとても高いインピーダンスになっているので、電源につないでも電流がほとんど流れません。ただし、ATMega328に限らず、マイコンの入力端子に加えられる最大入力電圧はVdd+0.3Vぐらいです。つまり5.3Vまでです。それ以上が加わると、内部で電流の流れが予測しない方向になり、どこかが破壊されるかもしれません。
A0などのアナログ入力ポートに、12Vなどの電池をつないではいけません。どうしても測りたいときは、12Vをたとえば1/3にする分圧回路を抵抗で組みます。測った後、プログラムで3倍にします。
次のスケッチを動かします。
シリアルモニタに表示された、アナログ・ポートの値です。電圧に直すには、まず10231024で割って、基準電圧の5.0Vを掛けます。このときreadAxは整数なので、(float)で実数にキャストします。そうしないと、「整数/整数」の演算で得られるのは整数になるため、期待しない数値になります。
ここで、10231024という数字を使っています。これは、A-Dコンバータが10ビットなので、GNDと基準電圧の間を2^10=1024で分解できますが、0Vから数えると最大値は2^10-1=1023になります。どちらの数字を使うか、筆者には正しい答えがわかっていません。しかし、ATMega328のA-Dコンバータの絶対精度は±2LSBなので、誤差範囲かもしれません。
(2020/05/07)1023は間違いなので、1024に変更した。
●温度を測る
前回解説した温度センサの中で、定番のLM35を利用します。これはアナログ出力ですが、利用時にとても便利な特性になっています。コンピュータがなくても温度が測れるのです。
●テスタで電圧を測ると
LM35の+VsとGNDに約5Vをつなぎ、Vout端子とGND間をテスタの電圧レンジで測ります。ICの足(リード線)の順番を見るとき、必ず特徴をわかったうえでデータシートを見ます。このICのパッケージはTO-92で、円筒形の一部がカットされた形状をしています。その削った平らな面に情報が印刷されています。今はレーザーによる刻印なので、人の目にはあまり読める鮮明な状態ではありません。
0.197Vと表示されました。これを百倍して単位を摂氏とします。19.7℃です。ここまでの実験から、温度計を作るのはどうすればよいのかが見えてきます。
●ATMega328のA-Dコンバータの構成
筆者が初めて8ビットのA-Dコンバータを使ったころ(1977年)、デイテルとかバーブラウンという専門メーカがありました。現在は、10~16ビットぐらいのA-Dコンバータは、マイコンの周辺モジュールのひとつになりました。
A-Dコンバータのスペックを見るとき、分解能(ビット数)と変換時間がキーポイントです。
少し前まで、A-Dコンバータの代表的な変換方式は三種類ほどありました。
- フラッシュ
- 逐次比較
- 二重積分
フラッシュの変換時間は高速ですが分解能は低く、二重積分は変換時間が長いですが分解能を高くできました。1996年に発売されたAVR(ATMegaシリーズは第2世代)に逐次比較のA-Dコンバータが内蔵されました。
現在は、ΔΣ(デルタ・シグマ)がよく使われます。この方式は、分解能が高く、低速から中速領域をカバーしているのと、ディジタル・デバイスの製造プロセスで作りやすいことから、マイコンに内蔵されるA-Dコンバータの主流になっています。
この方式は、安田靖彦氏の発明です。入り口に減算器があり、その後ろに1ビットA-Dコンバータが、その出力は減算器に戻ります。そのフィードバック・ループの途中に積分回路を入れたのが、このΔΣ方式A-Dコンバータの処理の中心となるΔΣ変調器です。24ビットぐらいになると、1ビットA-DコンバータではSN比が取れないので、3ビットぐらいのA-Dコンバータが使われます。
逐次比較型(SAR)A-Dコンバータは、コンパレータとD-Aコンバータで構成されます。コンパレータの二つある入力に一方にアナログ入力をつなぎ、もう一方には、D-Aコンバータが出力する基準電圧をつなぎます。1回比較するたびに、D-Aコンバータの電圧を変えていきます。分解能は16~18ビットが最大で、変換速度は数Mspsと、一番利用の多い領域をカバーしています。
●A-Dコンバータの前にマルチプレクサ
1個のA-Dコンバータを1入力として使うことはまずありません。4~16個の入力を切り替えるアナログ・マルチプレクサをA-Dコンバータの前に入れます。マルチプレクサの後ろにはサンプル・アンド・ホールド(S&H)回路がつながり、その出力はA-Dコンバータの入力につながっています。
S&H回路は、常に変化する入力電圧を、一瞬だけコンデンサに電荷として蓄え、A-D変換中に電圧が変わらないようにします。
このサンプル・アンド・ホールド回路に通常はバッファを入れるのですが、ATMega328では簡易的なため省略されています。その結果、チャネルを切り替える前のチャネルで高い電圧を読んだときに、コンデンサに充電された電荷を放電しきれないため、おかしな値を読み出すことがあります。
●2バイトの出力
AVRは8ビット・マイコンなので、A-D変換の結果は2バイトですから、一度に読めません。下位バイトを読んだときに上位バイトはロックされ、つぎに上位バイトを読んだときに違うタイミングの変換データが入っていないように配慮されています。
Arduino IDEでは単にanalogRead()で2バイトを一度に扱えるので、データの型はintにしておきます。
●LM35をアナログ入力A0につなぐ
デバイスをピンヘッダに直接つなぐと、マイコン・ボード付近の温度しか測れません。
ケーブルを延長します。ケーブルは銅線で抵抗値は大変低いですが、長さによっては、電圧を低下させるぐらいの抵抗値になります。写真のような長さでは無視できます。ケーブルが長くなると、無視できないのはケーブル間の容量です。通常、デバイスが大きな容量負荷を駆動する能力はそれほど高くありません。したがって、データシートにあるように補償回路を入れます。
電源が赤色と黒色、信号Voutは黄色のケーブルにしました。
●A-D変換の基準電圧
A-Dコンバータは、基準電圧を分解能のビット数で量子化します。10ビットA-Dコンバータは2^10=1024ですが、入力信号を分割すると最初は0なので、10231024段階のデータが得られます。
ATMega328のデフォルトは電源電圧を基準電圧にします。したがって、5.0Vです。今テスタで測ると4.94Vでした。MAKER UNO +ではUSBから5Vをもらっていますから、つなぐPCによって電圧はいつも変わります。Arduino UNOはDCジャック入力のときはレギュレータICが一定した5Vを出力するので、いつも同じ電圧が出ます。しかし、レギュレータICの出力は製品によってばらつくので、5.0Vだったり、5.05Vのこともあります。
基準がばらつくので、正確に測れないじゃないかという疑問がわきます。検証してみましょう。
1LSB、つまり、最小の量子化ビットはいくらの電圧なのか、Googleの電卓で計算します。
5V / 10231024 = 4.88758553 4.8828125[mV]
基準電圧が±5%変化したとき、1LSBは4.64320625~5.1319648 4.63867187~5.12695312の範囲の値を取ります。LM35を使って室温を測って25℃のとき、計測する電圧は250mVです。analogRead()で読んだ値が51だったとしましょう。
- 電源電圧が5.25Vのとき 261.73020527mV 26.2℃
- 電源電圧が5.00Vのとき 249.26686217mV 24.9℃
- 電源電圧が5.25Vのとき 236.80351906mV 23.7℃
電源電圧が±5%変化したとき、24.9℃であるはずの温度が-1.2~+1.3℃の変化が生じます。LM35はデータシートによれば25℃時の確度は±0.5℃ですから、センサのもつ確度より、電源電圧の変動のほうが大きな誤差になります。つまり、電源電圧を使うと、最悪、センサの能力を生かせないということです。
そこで、比較的安定な内部の基準電圧1.1Vを利用します。この電圧はデータシートによれば1.0~1.2Vの範囲を取ります。バンド・ギャップ電圧を利用した温度変化に対して安定な電圧を出力するという基準電圧です。しかし、とりえる電圧の範囲が広いので、困りものです。
1.1Vを利用すると、条件によってはメリットがあります。入力が0~1.0Vの範囲だとします。そうすると、1LSBは0.9775171mVと細かいのです。
3番目の方法は、Aref端子に安定な基準電圧をつなぎ、外部基準電圧を使う方法です。1個千円以上しますが、ADR4533BRZ(使用例)は、出力電圧は±0.02%、温度係数は2ppm/℃(-40~+125℃)なので、3.3Vの外部電源として利用するスペックでは過剰ですが、ベストな選択です。
話を戻して、USBの5Vが使うたびにいつも違うなら、使うたびに電源電圧を測ればよいのです。普通のDMM(テスタ)の値で十分です。
●スケッチ
DMMで5Vの電圧を測った値をVrefに設定できる記述にしました。5.00と書いている部分を、より正確にA-D変換がしたいときは、実際にDMMで測った数値に変更します。
12行目で、Temp,1としたのは、Serial.print()が実数の値を表示するとき、小数点第2位まで表示するのがデフォルトです。LM35の確度から意味のない桁なので、捨てました。
実行結果です。シリアルモニタは、Arduino IDE 1.8.7から時間を表示できる機能が追加されました。「タイムスタンプを表示」にチェックを入れます。
(※参考文献)山根 彰;AVRマイコン・リファレンス・ブック。
中村 黄三;実験研究に!図る電子回路の作り方。
祖父江達也、峰野太喜;電源電圧や温度の変動に強い基準電圧回路。
コラム 色
人は、いつも勘違いや思い込みをします。電子工作で配線をするとき、ちょっとした工夫で、トラブルを避けられます。
電源の配線は、ケーブルの色を決めます。プラスは赤色。グラウンド(GND)は黒色。マイナスは青色です。たったこれだけのルールで、マイコン・ボードを壊さずに済みます。
マイコン・ボードで使われている電源回りには保護回路が入っています。PCとつないでいるUSB2.0(1.1)は、最大500mAまで電流が流せます。実際は、ハブを使っていると1Aぐらいは流せますが、それを超えると電流制限回路が働き、無限に電流は流れません。
Arduinoの基板上に入っているレギュレータICには、過電流防止回路が入っています。ICの規定以上の電流が流れたら、電流を抑制し、負荷のショート状態がなくなったら復活します。
Arduino UNOのDC入力には、ダイオードが入っていて、プラスとマイナスが逆につながれると、電流が流れないように内部の回路を保護します。実験をしているとき、おかしい、と思ったらすぐに電源を切ります。Arduinoの場合はUSBケーブルを抜きます。保護回路によっては、長時間は、発生する熱に耐えられないこともあります。おかしい、と思う感覚は、いろいろな部品をこわすと身に付きます。
部品を壊したら、その原因を調べるという姿勢が、工学では必要です。
PS. 筆者は電源にエネループをよく使います。エネループPROには電流制限回路が入っていますが、通常の製品は、ショートするとたくさんの電流が流れて危険です。途中つないでいる部分が発熱して発煙することもあります。学生との実験では、内部抵抗が少し高めのアルカリ電池を使うと、そういうトラブルは避けられます。