PIC解説

【PIC】ADCの使い方 サーミスタで温度測定

投稿日:

今回は ADC (Analog to Digital Converter) の使い方を解説します。

PIC の IOピンは通常デジタルの入出力しか出来ませんが、ADC を使用することでアナログ入力(電圧測定)をすることが可能になります。

ADC の活用例としてサーミスタの抵抗値を測定することで温度を測定してみようと思います。

 

使用する部品

今回使用する主な部品は以下の通りです。

PIC については ADC モジュールが搭載されているものであれば大丈夫です。

LCDの使い方についてはこちらの記事を参照してください。

【PIC】LCD 1602の使い方

ADCモジュール

まずは ADCモジュールについて簡単に解説します。

先程 ADC でアナログ入力が可能になると説明しましたが、実際には完全なアナログ値というのは扱うことが出来ないので、デジタル値で電圧を測定します。

デジタル入力が High / Low の2段階しかないのに対し、アナログ入力では 0 ~ 1023 (10bit ADC の場合)の 1024 段階あります。

この 1024 段階はある基準(基本は VDD と GND)に対する相対値であり、実際の電圧を表している訳ではないことに注意してください。

ADC測定値-実際電圧

 

続いてPIC16F1579 のデータシートを見てみると、冒頭の部分に次の記述が見られます。

Analog-Periferals

10bit というのは ADC の解像度であり、10bit = 1024 段階で電圧を測定することができます。

12ch というのは ADC に利用できる IOピンの数のことです。気を付けなければならないのは、すべての IOピンが利用可能という訳ではない点と、同時にどれか1つの IOピンしか測定できないという点です。

 

ADC 関連レジスタ

ADC に関連するレジスタとその初期化例を解説します。各ビットについての詳細はクリックすると見られます。

ADCON0

ADCON0

詳細

CHS (Analog Channel Select bits)

ADC の測定を行うチャンネルを指定します。
00000 = AN0, 00001 = AN1, … 01011 = AN11
01100 ~ 11100 = 予約済み
11101 = 内部温度計, 11110 = DAC, 11111 = FVR

GO/DONE (ADC Conversion Status bit)

このビットを1にすると ADC測定が開始され、測定中は1のままで測定が終了すると0になります。

ADON (ADC Enable bit)

このビットを1にすると ADCモジュールが有効化されます。ADCモジュールは消費電力が比較的大きいので、ADC を使用しない場合は0にしておいた方が良いようです。

チャンネルは AN0を使用し、ADCモジュールを有効化させます。

ADCON0 = 0b00000001;

ADCON1

ADCON1

詳細

ADFM (ADC Result Format Select bit)

1:右詰め 0:左詰め(後述)

ADCS (ADC Conversion Clock Select bits)

000 = Fosc/2, 001 = Fosc/8, 010 = Fosc/32, 011 = FRC
100 = Fosc/4, 101 = Fosc/16, 110 = Fosc/64, 111 = FRC

ADC の測定のクロックを指定します。次の表(網掛けの部分は不適切)をもとに Fosc に対して適切な分周比を選択します。
ADC Clock Period

ADPREF (ADC Positive Voltage Reference Configuration bit)

00 = VDD, 01 = 予約済み, 10 = 外部参照ピン, 11 = FVR

ADC の上限の基準を設定します。電圧を測定したい場合、電源電圧が正確に分かっていれば VDD での測定結果から求められますが、そうでない場合は FVR(Fixed Voltage Reference)モジュールを基準とすることで電圧が計算できます。

また、このデバイスにはありませんが、下限の基準を設定出来るものもあります。

測定結果は右詰めで、Fosc は4MHz で使用し、上限の基準はVDDとします。

ADCON1 = 0b10010000;

ADCON2

ADCON2

詳細

TRIGSEL (Auto-Conversion Trigger Selection bits)

タイマーなどの特定のイベントで自動で ADC測定を行うように設定できます。
Auto-Conversion Trigger

自動測定は行いません。

ADCON2 = 0b00000000;

 

ADRESH, ADRESL

ADC の測定結果は 10bit なので、ADRESH と ADRESL の2つのレジスタにまたがって保存されます。
10bit すべて使用する場合は右詰め、上位8bit で十分な場合は左詰めにするとよいです。

測定結果フォーマット

 

サンプルプログラム

ADC の初期化後、実際に ADC の測定をするプログラムがこちらです。

今回は1ch しか使わないためチャンネルの選択は省略していますが、複数のチャンネルを切り替える場合は、測定開始の前に ADCON0 レジスタの CHS にチャンネルを指定しておく必要があります。

 

サーミスタ

サーミスタ

サーミスタは温度によって抵抗値の変化する抵抗です。抵抗値を測定することによって温度を計算することが出来ます。

(写真の先端部の太い部分がサーミスタで大部分はリード線です)

サーミスタの抵抗値と温度の関係は次のようになっています。

サーミスタ関係式

(T0, R0 はある温度とその温度における抵抗値、Bはサーミスタ固有の定数)

これを T について解くと次のようになります。

T0, R0, B は定数ですので、T は R の関数として表されました。

 

分圧そこで R を測定する必要がありますが、ADC で直接 R を測定することは出来ません。ではどうするかというと、基準となる抵抗を用意して、分圧から抵抗値の比を求めてサーミスタの抵抗値を計算します。

基準の抵抗の値を r 、ADC の測定結果を A とすると、次の式が成立します。この時、電源電圧には依存しないことに注意してください。

分圧関係式

これを R について解くと次のようになり、R が A の関数として表されます。

分圧R(A)

これで晴れて ADC の測定結果から温度が計算できるようになりましたが、この計算をマイコンにやらせるのは大変なので、あらかじめ Excel で計算してデータを用意してしまいましょう。

データシートから、T0 = 25 (℃)、R0 = 10000(Ω)、B = 3435(K) が得られます。r についてはまだ適切な値が分からないので変更できるようにしておき、とりあえず 10000(Ω)とします。

Excelに先程の計算式を入力します。

ExcelExample

A = 0, 1023 の時にゼロ除算のエラーが発生しますが、測定値がそのような値をとることは考えられないので気にする必要はありません。

計算結果をグラフにしてみるとこんな感じです。

グラフ1

実際に使用する環境を考えると、測定範囲は 0℃~100℃ で十分なのでその範囲で見てみます。

グラフ2

手持ちの抵抗の中から r の値を適当に選んでみた結果、r = 3200 (Ω)のグラフが一番よさそうでした。(3.3kΩの抵抗をテスターで測ったら3.2kΩでした)

グラフ3

ということで r の値と温度のテーブルが得られました。

 

動作テスト

ADC を使用してサーミスタで温度を測定し LCD に表示させてみました。

動作テスト

比較用として温度センサー BME280 の測定結果と並べてみました。どちらも 27.0℃ となっており、きちんと温度を測定できていることが分かります。

気温を測定するだけであれば温度センサーと変わりませんが、サーミスタであれば水温なども測定することが出来ます。

以下回路図とプログラムです。

Schematic

温度のテーブルに関しては、10倍して小数第一位までを整数とした上で、見づらいので別ファイルに入れておきました。また、0番目と 1023 番目にはとりあえず0を入れておきました。

LCDライブラリ

今回の記事は以上となります。最後までご覧いただきありがとうございました。

-PIC解説

執筆者:


  1. サーミスタによる温度測定、サーミスタの抵抗値を読む方法についてあれこれ書いてみました。
    ご一読いただければ。

    A/Dコンバータでサーミスタの抵抗値を読む サーミスタをつなぐ場所は?
    http://igarage.cocolog-nifty.com/blog/2023/03/post-ad45c1.html

    Arduino サーミスタを使った温度測定で 【ゼロ除算問題】
    http://igarage.cocolog-nifty.com/blog/2023/03/post-4bb96a.html

    ミスが広まる 1/1023 vs 1/1024
    http://igarage.cocolog-nifty.com/blog/2020/01/post-a02d3f.html

居酒屋ガレージ店主(JH3DBO) へ返信する コメントをキャンセル

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

関連記事

【PIC】I2C通信のやり方

マイコンで Lチカが出来たら次は LCD に文字を表示したり、色々なセンサーを扱いたいですよね。今回はマイコンと周辺機器の通信によく使われる I2C通信のやり方をちょっとだけ詳しく解説していきます。 …

PIC超入門!ゼロからLチカまでの道【その4:プログラム書き込み~Lチカ】

前回プログラムが完成したので、あとはプログラムを書き込んで、回路を組み立ててついにLチカです! あともう少しでゴールなので頑張りましょう。 前回の記事はこちら PIC超入門!ゼロからLチカまでの道【そ …

【PIC】I2CでLCDに文字を表示する

前回の記事で I2C通信を制御するライブラリを作成したので、今回はそれを使って LCD に文字を表示させてみたいと思います。 前回の記事はこちら↓ 【PIC】I2C通信のやり方 目次1 LCD2 接続 …

PIC超入門!ゼロからLチカまでの道【その3:コンフィギュレーション~プログラミング】

前回プロジェクトを作成して設定まで終わったのでいよいよプログラミングに入ります。PIC の第一の関門であるコンフィギュレーションも順を追ってやっていけば簡単にできます。 前回の記事はこちら PIC超入 …

【PIC】LCD 1602の使い方

今回はパラレル接続のキャラクタLCD の使い方を紹介します。 タイトルに 1602 とついていますが、キャラクタLCD の制御IC は大抵同じものなので、文字数の違うものだったり、メーカーの違うもので …