温度センサ

このエントリーをはてなブックマークに追加

 

 今回は温度センサです。温度センサから取得した温度を、シリアル通信を使用して7セグメントディスプレイに表示させます。7セグメントディスプレイはこちらの記事を参照してください。
 今回作成する回路での取得可能な温度は0 ~ 99度です。プログラムを改良すれば範囲を広げることは可能です。
 温度を取得するために、AD変換を行っています。AD変換(ウィキペディア)についての説明はウィキペディアを参照してください。

 回路図およびプログラムに関する各種詳細は、以下の記事を参考にしてください。

 

1.今回使用するPICについて

 今回使用するPICは「PIC12F1822」です。

 

2.回路

2.1 電子回路図

 

 

2.2 電子回路の写真

 

 

 

 

2.3 回路説明

2.3.1 使用するパーツ一覧
パーツ名 使用数
PIC12F1822 1
温度センサ(サーミスタ 103AT-2) 1
抵抗10[kΩ] 1
5[V]出力電源 1

 AD変換を使用する場合、電源の電圧は非常に重要になります。今回はPICの電源電圧を基準とするため、安定した5[V]電源が必要になります。また、センサへの電源も重要になるので注意してください。今回はそれほど精度を求めないので、比較的安価で大体5[V]の出力を得られる、USB出力を持った充電池を使用しています。

 

2.3.2 精度を上げるポイント

 温度の精度を上げるポイントがあります。以下のどちらかまたは両方を実施すると精度が上がります。

  • 10[kΩ]の抵抗を高精度抵抗にする
  • 10[kΩ]の抵抗をテスタで計測し、その値をプログラムに反映する
2.3.3 PICの配線
PICのピン 接続
VDD 5[V]電源
RA0 シリアル通信(TxD:送信)
RA1 シリアル通信(RxD:受信)
RA2 -未使用-
RA3 -未使用-
RA4 温度センサ(サーミスタ 103AT-2)
RA5 -未使用-
VSS グランド

3.プログラム

 プログラムの基本的な部分は以下の記事を参考にしてください。

3.1 温度センサに関するプログラム

 温度センサを使用するために必要な部分のみを説明しています。

 

3.1.1 ADコンバータの設定
OSCCON = 0b01110000 ;    // 内部クロック8MHz

ANSELA = 0b00010000 ;    // AN3をアナログにし、他はデジタルI/Oに割当てる
TRISA  = 0b00011010 ;    // RA1,3,4を入力にし、他は出力に割当てる
PORTA  = 0b00000000 ;    // 出力ピンの初期化(全てLOWにする)

ADCON1 = 0b10100000 ;   // 右寄せ、Fosc/32,VDDをリファレンスにする

ADCON0 = 0b00001101 ;   // AN3を使用する
__delay_us(5);          // ch設定後、反映待ち

 ADコンバータを使用するための設定を行います。AN3はピンRA4に割り付けられています。RA4をアナログ入力にするため、ANSELAの4bit目を1に設定します。
ANSELA = 0b00010000;

 RA4を入力に設定します。(シリアル通信でRA1を入力、RA0を出力に設定しています。RA3は入力専用)
TRISA = 0b00011010;

 ADコンバータの設定を行います。

ビット 名前 設定値 意味
bit0-1 ADPREF 00 正参照電圧をVDDに接続する
bit4-6 ADCS 010 Fosc/32
bit7 ADFM 1 取得したデータを右詰めにする

ADCON1 = 0b10100000;

 ADコンバータを有効にし、AN3を使用する設定を行います。

ビット 名前 設定値 意味
bit0 ADON 1 ADコンバータを有効にする
bit2-6 CHS 00011 AN3を使用する

ADCON0 = 0b00001101;

 ADコンバータのチャンネル設定後、一定時間待たないと設定が反映されないため待ちます。
__delay_us(5);

 

3.1.2 ADコンバータからデータ取得
// AD 変換
GO_nDONE = 1;   // 変換開始

// アナログをデジタルに変換
while( GO_nDONE )
{
    // wait
}

ad_data = ADRESH;
ad_data = (ad_data << 8) | ADRESL;

 AD変換の開始を指示します。
GO_nDONE = 1;

 GO_nDONEが0になると変換完了なので、0になるのを待ちます。
while( GO_nDONE )
{
    // wait
}

 取得したデータは10ビットあるので、2バイトの変数に代入します。初めに上位ビットを代入、代入した値を8ビット左シフト後に論理和を取ります。
ad_data = ADRESH;
ad_data = (ad_data << 8) | ADRESL;

 取得したデータを電圧に変換します。電源電圧を使用しているので5[V]、PICのアナログ変換の分解能が10ビットなので1024です。
電圧 = 5[V] × 取得したデータ / 1024

 

3.1.3 取得したデータから温度を計算

 温度センサの抵抗値がわかれば温度を取得することができます。そこで、今回の回路は分圧回路(ウィキペディア)になっていので、取得した電圧を利用し、温度センサの抵抗値を計算します。

Vin : Vout = (R1 + R2) : R2
R2 = R1 × Vout / (Vin – Vout)

 温度センサの抵抗値を計算で求めることができたので、その値から温度を計算します。計算式は以下の通りです。
R = R0 × exp(B × (1/T – 1/T0))

記号 意味
R 温度センサの抵抗 AD変換から求めた値
R0 温度センサが25度の時の抵抗値 10[kΩ]
B 温度センサの定数 3380
T 測定温度(ケルビン) 求めたい値
T0 25度(ケルビン:25 + 273.15) 298

注:今回計算を楽にするために、273.15ではなく273で計算しています。

 今回使用しているPICは計算能力が低いです。なので、複雑な計算をさせると非常に時間がかかってしまいます。また、複雑な計算を行うには多くのメモリが必要です。しかし、使用するPICのメモリが少ないため計算を行えません。上記式をT=に変換し計算を行おうとしたのですが、メモリ不足で行えませんでした。そこで、今回は計算結果のテーブルを作成し、そのテーブルを利用し温度を求める方法にしました。
 0度の場合
R = 10000 × exp(3380 × (1 / (0 + 273) – 1 / 298))
R = 28254.581
R = 28255

 1度の場合
R = 10000 × exp(3380 × (1 / (1 + 273) – 1 / 298))
R = 27006.286
R = 27006

 以上のように100度まで計算を行いテーブルを作成しました。

const unsigned short temperature_ohm_tbl[101] =
{
    28255, 27006, 25822, 24697, 23629,
    22614, 21650, 20733, 19861, 19032,
    18243, 17491, 16776, 16095, 15445,
    14826, 14236, 13674, 13137, 12625,
    12136, 11669, 11223, 10797, 10389,
    10000,  9628,  9272,  8931,  8605,
     8293,  7994,  7708,  7434,  7171,
     6919,  6678,  6446,  6224,  6011,
     5807,  5610,  5422,  5241,  5067,
     4900,  4739,  4585,  4437,  4294,
     4157,  4025,  3897,  3775,  3657,
     3544,  3434,  3329,  3228,  3130,
     3036,  2945,  2857,  2773,  2691,
     2612,  2537,  2463,  2392,  2324,
     2258,  2194,  2133,  2073,  2016,
     1960,  1906,  1854,  1804,  1755,
     1708,  1663,  1618,  1576,  1534,
     1494,  1455,  1418,  1382,  1346,
     1312,  1279,  1247,  1216,  1185,
     1156,  1128,  1100,  1073,  1047,
     1022
};

 

 計算を簡単にするため、小数点以下は四捨五入しています。例えば、温度センサの抵抗値が「18243」の場合、10度になります。ただ、実際に同じ数字になることはほとんどないと思います。実は端数は温度の少数値になります。では、計算方法を説明します。

例:18000[Ω]の場合
10度:18243
11度:17491

 ここから、10度であることが判明します。続いて、少数値です。10度から超えた量を計算します。
18243 – 18000 = 243

 10度と11度の差は752あるので、比率を求めます。
243 / 752 = 0.3231

 以上の計算から、10.3度となります。最後に本プログラムでは、温度をシリアル通信を利用して7セグメントディスプレイに送信しています。

 

3.2 ソースコード

 プログラムの全文を掲載します。

  プログラム新しいウィンドウで開く

<注意>
ファイル名は必要に応じて変更し利用してください。
本サイトの注意事項を確認してください。
ソースコードや回路図などを使用する場合、上記注意とともに、自己責任でお願いします。

    

 

4.動作確認

 シリアル通信バージョンの7セグメントディスプレイと接続し電源を入れると、温度センサから取得した温度を7セグメントディスプレイに表示します。

 

 

 

 

 

<更新履歴>

 

 日付  内容
2015年7月7日 新規作成
2016年10月6日 フォーマット変更(内容の変更はなし)

 

I2C          メニューへ          温湿度センサ

コメントを残す

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

CAPTCHA


日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)