[トップページへ戻る]

AVR ATmega88 A/Dコンバータ応用例 温度計

2011年2月
これまでマイコン工作はATtiny2313を中心に利用してきました。
このマイコンはA/Dコンバータを内蔵していないので、必要なときはアナログコンパレータを応用したA/Dコンバータ(もどき)を使っていました。しかし精度は高くありません。
ここらでちゃんとしたA/Dコンバータを使えるようになりたいと思い、手持ちのATmega88を使って学習することにしました。

この記事は「マイコン初心者ではないがA/Dコンバータには慣れていない」自分が、実験した内容や考えをまとめたものです。(↑想定する読者層)
今回、練習として単純な温度計を作りました。プログラムと回路図を公開します。


A/Dコンバータ
A/Dコンバータ …「Analog-to-Digital Converter」「A/D変換器」
A/Dコンバータの仕組みについては参考書を読んでください。ここでは電源と基準電圧の取り方について書きます。

A/Dコンバータは入力電圧(アナログ量)を測定し、n段階の数値(デジタル量)に変換する機能です。
何段階に変換するかはA/Dコンバータの分解能によります。10bitのA/Dコンバータなら1024段階(0〜1023)です。
A/Dコンバータは単体のICの他、これを内蔵したマイコンという形でも手にすることができます。
※単体ICのA/Dコンバータは、より精度の高い変換や、より高速な変換を求めるときに使われます。

A/Dコンバータは、入力された電圧を「ある基準となる電圧」と比較して数値に変換します。この基準となる電圧を「基準電圧」「リファレンス電圧」と呼びます。入力電圧の大きさが基準電圧と同じとき、変換値は最大値となります(例:1023)。基準電圧より大きな入力電圧は最大値に変換されます。

AVRマイコンATmega88はA/Dコンバータを内蔵しており、マイコン内部に1.1Vの基準電圧を持っています。
これにより、入力電圧が1.1V以下のシステムなら大変シンプルにA/Dコンバータが利用できます。
もっと大きな入力電圧をA/D変換したいときは、マイコンの動作電圧(AVCC)を基準電圧とすることができます。
また、基準電圧を外部から与えることもできます(大きさはAVCCまで)。
※マイコンには本体(デジタル回路)の電源端子VCCの他、A/Dコンバータ(アナログ回路)の電源端子AVCCがある。
※A/Dコンバータを使う/使わないに関わらず、AVCCにも電源を接続する。VCCと共通の電源でよい。



動画リンク
A/Dコンバータの動作の様子
ATmega88の内蔵A/Dコンバータを使った電圧計の様子です。
左のLCD表示がA/Dコンバータによる電圧計。右のテスターは電圧の比較・確認用です。
基準電圧はAVCCに設定(USB給電。実測値4.8V)。電源電圧を半固定抵抗で分圧してA/Dコンバータに入力し、その値を測定しています。
入力電圧を最大にしてもA/D変換値は1023になりませんでしたが(使い古しの半固定抵抗の誤差のため)、計算値は1mVの位で四捨五入しているので表示上はテスターの値と一致しています。※あくまで動作例なので適当に処理している。


【図1】 A/Dコンバータを利用する回路の基本形

シンプルにA/Dコンバータを利用する回路の基本形です。例として電源にUSB(5V)を想定しています。
基準電圧は電源電圧AVCCか内部基準1.1Vを設定します。
※基準電圧の設定は配線作業ではなくソフトウェア的なこと。ハードウェア的には(基板上では)、AREFピンには何も配線しない。
※AREFピンはオープンでよいのか、コンデンサでGNDに接続した方がよいのか、という話が気になる人は検索してください。


AVCCと内部1.1Vのどちらを使うかは入力電圧の大きさによります。例えば、数百mVの電圧を出力するセンサーが対象なら内部1.1Vを選択します。数Vの電圧を可変抵抗で分圧して入力するようなシステムならAVCCを選択します。
※「AVR ATtiny2313 ビデオ出力 ブロック崩し〜アナログ入力〜」のボリューム操作が後者の例。

基準電圧と入力電圧の(桁数的な)差が大きいとA/Dコンバータの分解能が活かせません。仮にセンサーの出力が数mVだとすると、基準電圧に対して3桁の違いがあります。これは、A/D変換の最大値1023に対して0〜数十の範囲でしか値が動かないということです。
このようなときはセンサーの出力をOPアンプで増幅してA/Dコンバータへ入力します。センサーの出力を数百mVに増幅すれば基準電圧に対して1桁差となり、結果的にA/D変換の精度が上がります。
※以降の図では、入力電圧は十分な大きさであるとしてOPアンプを省略。

図では表示デバイスとして液晶モジュール(LCD)を挙げています。他に7セグでもバーLEDでも何でもよいです。
場合によってはモーターやスピーカーかもしれません。


【図2】 安定した基準電圧を与えた回路


実はマイコン内部にある基準電圧1.1Vは正確ではなく、動作環境の影響を受けてわずかにずれます。
※データシートでは min:1.0V / typ:1.1V / max:1.2V
そのため、より正確なA/D変換を利用したい(しかし単体ICを使うほどでもない)場合は、基準電圧として安定した電圧を外部から与えます。この目的でシャントレギュレータを使います。
シャントレギュレータは三端子レギュレータのように定電圧を出力するデバイスで、データシートの用途欄にはまさに「基準電圧用」と書かれています。代表的なシャントレギュレータTL431は2.5Vの定電圧源になります。

マイコン側は「AREFピンに入力された電圧を基準電圧とする」という設定にします。

シャントレギュレータの効果は覿面(てきめん)で、AVCCや内部1.1Vのときよりずっと安定したA/D変換ができました。
※変換値のふらつきがほとんど無い。
ではシャントレギュレータにマイコンもセンサーも接続すれば、全体的に安定した回路になるのでは? と考えるかもしれませんが、それは難しいと思います。シャントレギュレータの先に大きな電流変化がある回路は接続できません。
この回路では、シャントレギュレータはA/Dコンバータの基準電圧として使うことに専念した方がよいでしょう。


【図3】 多様な電源電圧に対応した回路

製作物によっては複数の電源に対応させたいことがあります。
例えば、12V(PC電源),9V(ACアダプタ),5V(USB)の3電源対応など。
9Vや12Vで回路を直接動かすことはできないので、三端子レギュレータで電圧を落として供給することになります。
三端子レギュレータの出力電圧は正確で安定しています。よってA/Dコンバータの基準電圧は、シャントレギュレータを使わずともAVCCでよいと思います。

図において5Vの三端子レギュレータを使った場合、12V, 9Vを入れると5Vが出てきますが、5Vを入れて5Vは出てきません。ここで使う三端子レギュレータは最も低い電源電圧よりもさらに低い定格のものである必要があります。よって、3.3Vの三端子レギュレータとしています(低ドロップアウト型)。※低いものといっても、肝心のマイコンが動作する電圧であることが必須。

図中のLCDは5V用です。3.3V電源では画面が映りません。別途5V電源を用意する必要があります。
一応、SC1602/SD1602などお馴染みの液晶モジュールは、Vo端子に負電圧を加えることで3.3V電源でも動かせます。詳しくはこちらの記事を見てください。→「LCDモジュールを3.3V/3V回路で使う


ノイズ対策
安定したA/D変換のためには安定した基準電圧を用意する他、ノイズ対策にも気を付けます。
ATmega88には、デジタル回路(マイコン本体)用の電源端子VCCとは別にアナログ回路(A/Dコンバータ)用の電源端子AVCCがあります。基本的にVCCとAVCCは共通の電源に接続します。
ここでノイズ低減のため、AVCCにフィルタを付ける方法がデータシートで紹介されています。
(→右図。LCフィルタを付ける説明図)
※自分の実験回路(ブレッドボード上の温度計。基準電圧はシャントレギュレータ)ではLCフィルタを試していませんが、
無くても安定しているように見えます。電子レンジの横で使うと変わってくるかもしれません(?)


LCフィルタはハードウェア面でのノイズ対策。一方、ソフトウェア面での対策もあります。
プログラム的に見てA/D変換は1サイクルで完了するわけではなく、完了フラグが立つまで待たなければなりません。この間にマイコン内部で、デジタル回路の動作がアナログ回路にノイズ的な影響を与えます。
具体的には、完了フラグが立つまでwhileループで監視するソース記述の場合です。ループしている間はデジタル回路が動作しているわけですから、A/Dコンバータの動作に多少でも影響を与えることになります。

そこで、完了フラグが立つまでデジタル回路をスリープ(待機状態)するソース記述にします。A/Dコンバータの動作中はプログラムの実行が中断され(デジタル回路が休止)、アナログ回路への影響を最小限に抑えることができます。
この効果は実際にそれぞれの記述でプログラムを実行してみれば分かります。
※と言っておきながら、実は自分の実験回路(同)ではほとんど違いがありませんでした。プログラムの内容にもよると思います。一応、微妙な差ですが確かにSLEEPした方が安定しました。


シャントレギュレータ
シャントレギュレータTL431で2.5Vの定電圧源を作り、A/Dコンバータの基準電圧とします。
基本的な回路はデータシートを参照してください。特にNJM431のアプリケーションノートには、シャントレギュレータの仕組みや2.5Vの定電圧源として利用する際の説明が詳しく書いてあります。※NJM431はTL431と中身が同じ物。
TL431のデータシート:
TI http://tij.co.jp →トップページ→「TL431」で型番検索。
NJM431のデータシート:
新日本無線(NJR) http://semicon.njr.co.jp/jpn/ →製品情報ページ→「NJM431」で検索。
データシートの他、アプリケーションノート「シャントレギュレータアプリケーションマニュアル」はシャントレギュレータの仕組みと具体的な設計例を詳しく説明しているので必読。



今回製作した温度計でNJM431を使いました。抵抗Rsの値は次のように決めました。
VoutはA/Dコンバータの基準電圧入力ピン(AREF)に接続します。ATmega88のデータシートより、AREFピンの入力インピーダンスは32kΩなので、流れ込む電流…すなわちIoutは、
  Iout = 2.5V / 32kΩ = 78uA ※実測値は70uAだった。

またTL431の仕様によるとカソード電流Ikaは1mA以上でなければなりません。よって、トータルで必要な電流Iinは、
  Iin = Iout + Ika >= 1.078mA

Iin=2mA、Vin=5Vとすると、Rsは、
  Rs = (5V - 2.5V) / 2mA = 1.25kΩ

よって、Rs=1.2kΩにしました。
仕様上、Ikaは100mAまで流せますが、NJM431の「シャント(略)アプリ(略)マニュアル」の設計例ではIka=5mAとしており、またTL431のデータシートの電気特性ではIka=10mAとした値が示されています。Ikaはこの程度を目安に設計するのがよいようです。今回の製作例なら1.2kΩ(Ika=2mA)〜470Ω(Ika=5.3mA)程度がよいと思います。

【参考】Vin=3.3Vの場合、Rs = (3.3V - 2.5V) / 2mA = 400Ω → 330Ω(Ika=2.4mA)、100Ω(Ika=8.0mA)など。

ところで、このときの実験で気付いたのですが、自分の回路ではIkaが1mAに近いほどA/D変換の結果が良好でした。Ikaが大きくなるにつれ(5mA,10mA)、誤差が大きくなりました。電源ラインの引き方が悪いのだと思います。VCCとAVCCの間に、Rsの値によって変わるmV単位の電位差が現れました。面倒なので気にしないことにしました。


温度計を製作する
A/Dコンバータの使い方を知るため、温度計を作りました。基板には仕上げずブレッドボード上で完成としています。
マイコンは、(1)A/Dコンバータ内蔵で、(2)外部基準電圧(AREF)ピンがあって、
(3)LCDを接続できるだけのピン数があれば、何でもよいです。
今回は手持ちにあったAVR ATmega88(無印)を使いました。

シャントレギュレータNJM431/TL431を2.5Vの基準電圧として使います。
抵抗Rsは1.2kΩ。カソード電流は約2mA流れます。

温度センサはLM61、Bグレード(計測範囲:-25〜85度、誤差:+-3度)。
【参考】Cグレードは 計測範囲:-30〜100度、誤差:+-4度。
データシートを参考に 0.1uFのコンデンサを付けています。

電源はUSB給電で5V。マイコン、温度センサ、シャントレギュレータ、LCDを接続。
LCDの表示は開発中の様子で、左上の値はバッファ内のA/D変換値の合計です。ここから入力電圧を逆算します。
※LCDは「LCDモジュール SC162シリーズ」で紹介した”開発で使い回す用”のもの。まさに今回活躍した。

本番動作の様子。
上段:現在の気温。
下段:最低気温、最高気温。
マイナスの気温を表示した例。
(値はダミー)
【参考】7セグを使用した例。
※[c]の上に[-]表示でマイナスの気温に対応。

回路図


libm.aを指定する

プログラム
ダウンロード adctest88_v100.zip (hexファイルとCのソース)

学習目的で組んだプログラムのため、コメントが多すぎて「ソースの説明書」状態になっています。※プログラムを追う目的ではかえって見づらい。
lcdlib.c/.hは自作のLCDライブラリ。この記事公開時点での最新版です。

温度計プログラムではより正確なA/D変換を求め、浮動小数計算をしています。そのままコンパイルするとavr-gccの標準ライブラリがリンクされ、プログラムサイズが数KB増大します。このようなときは最適化されたライブラリ「libm.a」を使いましょう。※libm.aはAVR Libcで用意された数学ライブラリ。
リンクオプション「-lm」を指定します。AVR Studioで開発している場合は、設定(ツールバーの歯車のアイコン)→Librariesから指定できます。

【参考】ATmega88でfloat型を使ったプログラムのサイズ比較
libm.aなし Program: 3644 bytes (44.5% Full)
Data: 277 bytes (27.1% Full)
libm.aあり Program: 2018 bytes (24.6% Full)
Data: 13 bytes (1.3% Full)

発展
プログラムサイズには余裕があるので機能を拡張して楽しむことができます。10分ごとに気温を測り、マイコンのEEPROM領域に保存。1日後にデータを吸い出して、Excelで折れ線グラフを描いてみるのはどうでしょう。

2012/01 追記
上記参考図「7セグを使用した例」のプログラムと回路図を公開します。
カソードコモンの7セグ用の設計です。
ダウンロード AdcTest88_lm61_7seg.zip (hexファイル、Cのソース、回路図)


部品について
マイコンはA/Dコンバータ内蔵のものが必要です。今回はATmega88を使いました。
クロックは内蔵1MHzで十分です。

シャントレギュレータは代表的なTL431またはNJM431が安価で入手しやすいです。2.5Vの定電圧が作り出せます。
他のシャントレギュレータでは2.5Vとは限らないのでデータシートで確認してください。また、その電圧に合わせてソフトウェアの修正も必要となります。

温度センサはLM61を使いましたが他の型番でも構いません。その場合、ピン配列と使い方(基本回路)をデータシートで確認してください。

表示デバイスはお馴染みSC1602/SD1602と同等のSC162Cを使いました。※回路図はSD1602で書いています。
LCDに限らず7セグでも何でもよいですが、マイコンのピン数が足りるか確認してください。

電源は5Vです。USBかACアダプタで。
記事で書いたように、LCDがどうにかなるなら3.3Vでも動作します。

今回はブレッドボード上に組んで完成としましたが、温度計として使い続けるならもちろん基板にハンダ付けします。
基板の大きさは、例えば秋月電子のCタイプ基板(25x15穴)で足りるでしょう。


温度計 部品一覧 (回路図はここをクリック
部品名 部品番号 個数 参考価格/備考
AVR(マイコン) U1 ATmega88(P) 1 180円(秋月電子
シャントレギュレータ U2 TL431 または
NJM431
1 10個100円(秋月電子)
1個30円(秋月電子/千石電商
温度センサ U3 LM61(BIZ/CIZ) 1 4個200円(秋月電子)
抵抗 R1 1.2kΩ [茶赤赤金] 1 1個5円/100個100円
積層セラミックコンデンサ C1-C3 0.1uF [104] 3 10個100円
キャラクタ液晶モジュール LCD SD1602/SC162Cなど 1 (秋月電子/aitendo
(抵抗) R2 47Ω [黄紫黒金] 1 LCDの部品として
(半固定抵抗) VR 10kΩ [103] 1 LCDの部品として


◆ ◆ ◆
AVRの内蔵A/Dコンバータの使い方が分かりました。
製作予定の物の中にA/Dコンバータなしでは作れない物があって先送りしていたのですが、
これでいつでも作れます。


2011/04 追記
案外便利だったので基板に仕上げて使ってみることにしました。
AVRとLCDの接続に関して、配線の都合上、プログラムを一部変更しています。




(C) 『昼夜逆転』工作室 [トップページへ戻る]
inserted by FC2 system