今回は温度センサです。温度センサから取得した温度を、シリアル通信を使用して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日 | フォーマット変更(内容の変更はなし) |