Arduinoとサーミスタで温度測定
こんなこと、やります。
- サーミスタの使い方、計算方法を学ぶ
- Arduinoとサーミスタを使って温度の測定
- サーミスタの温度校正
つかうもの
本記事でつかうものをご紹介します。
サーミスタ
103JT-050というサーミスタを使用しました。薄型である程度曲げることができます。
厚さは500μmと超薄型で、電気絶縁性も優れています。
温度測定範囲は、-50℃〜+125℃となってます。
Arduino
Arduino Uno Rev3を使用しました。
もちろん他のArduinoでも構いません。
もしまだArduinoをお持ちでないようでしたら、オススメArduinoどれを選べばいい?Arduinoで電子工作をはじめる方へをご参考になさってみてください。
その他の電子部品
プルアップのため10kΩの固定抵抗を使います。プルアップ抵抗の誤差は温度計算に影響しますので、誤差範囲の小さい抵抗を選んでください。金属皮膜抵抗ですと±1%以内でオススメです。また、ブレッドボードやジャンプワイヤもあると便利です。
サーミスタ
ここではサーミスタについて解説します。
サーミスタとは
サーミスタとは、温度変化にともなって抵抗値が変化する抵抗器です。温度のthermalと抵抗器のresistorを合わせ、サーミスタという名称になりました。
温度センサに使用されるサーミスタは、NTC(negative temperature coefficient)といって、温度が上昇すると抵抗値が減少するタイプのものです。
温度が上昇すると抵抗値が上昇するものは、PTC(positive temperature coefficient)と呼び、ヒューズの役割として使ったり、一定温度を保つPTCヒーターに利用されます。
ちなみにこちらのPTCヒーターを使ってヨーグルトメーカーをつくったことがあります。興味のある方はそうだ!Arduinoでヨーグルトメーカーをつくろう!をご覧ください。
本記事では、温度センサとしてよく使われるNTCタイプのサーミスタを扱います。
NTCサーミスタの特性・近似式
サーミスタは、温度変化に対して抵抗値が変わる素子であることは説明しました。しかしながら、サーミスタと温度と抵抗の関係は非線形です。よって、サーミスタの抵抗値から温度を得るためには、NTCサーミスタの特性を近似させた次式を利用します。
$$R=R_0exp\{B(\frac{1}{T}-\frac{1}{T_0})\} \tag{1}$$
ここで、BはB定数と呼ばれるもので、サーミスタのデータシートに掲載されています。
また、Tの単位はケルビンになります。摂氏温度を取得するには次式で変換します。
$$T(K)=t(℃)+273.15 \tag{2}$$
さて、式1をTについて展開すると次のとおりです。
$$\frac{1}{T} = \frac{1}{T_0}+\frac{1}{B}ln\frac{R}{R_0} \tag{3}$$
式3の逆数をとれば、Tについて算出できます。
さらに高精度で近似させる「スタインハート式」というものがありますが、式3でも実用的な温度測定ができますので「スタインハート式」については省略します。
\スタインハート式を使った校正/
必要なパラメータ(103JT-050)
サーミスタで温度測定に必要なパラメータを確認しておきます。今回使用するサーミスタは103JT-050ですので、 データシート より各パラメータは次のとおりになります。
項目 | 値 | 備考 |
---|---|---|
B定数 | 3435K | ±1%(25℃の時) |
\(T_0\) | 273.15K | 0℃の時 |
\(R_0\) | 27.7kΩ | 0℃の時 |
\(R_{25}\) | 10kΩ | ±1%(25℃の時) |
抵抗・温度特性のシミュレーション
サーミスタ103JT-050の データシート から、理論値をプロットしてみました。また、式1の近似式と103JT-050のパラメータから抵抗値を計算し、抵抗と温度特性のシミュレーションをしてみました。
次のグラフは、サーミスタ103JTの抵抗・温度特性における、理論値と近似値の関係を表したものです。
さらに、0℃以上に絞ってみてみます。すると下図のとおり、かなり高い精度で近似できることが分かりました。
Pythonのソースコード
さきほどのグラフを作ったPythonのソースコードです。このプログラムを少し修正すれば、ラズパイでサーミスタを使う場合にも利用できると思うので、ご参考になさってみてください。
# -*- coding: utf-8 -*-
import math
import matplotlib.pyplot as plt
import japanize_matplotlib
"""
サーミスタ103JTの抵抗ー温度特性
抵抗値はkΩ
"""
list_temp = [-50, -40, -30, -20, -10, 0, 10, 20, 25, 30, 40, 50, 60, 70, 80,
85, 90, 100, 110, 120, 125]
list_R = [367.7, 204.7, 118.5, 71.02, 43.67, 27.70, 18.07, 12.11, 10.00, 8.301,
5.811, 4.147, 3.011, 2.224, 1.668, 1.451, 1.267, 0.9753, 0.7597, 0.5981, 0.5331]
T0 = 273.15
R0 = 27.70
B = 3435
list_r = [R0 * math.exp(B*(1/(t+273.15)-1/T0)) for t in list_temp] # [条件式 for 変数名 in リストなど]
def plot(t, R, r): # t温度、R理論値、r近似値
fig, ax = plt.subplots(facecolor="w")
plt.xlabel('温度 [℃]')
plt.ylabel('抵抗値 [kΩ]')
ax.plot(list_temp, list_R)
ax.plot(list_temp, list_r)
ax.legend(["理論値", "近似値"])
plt.show()
plot(list_temp, list_R, list_r)
# 0℃以上のデータのみ
del list_temp[:5]
del list_R[:5]
del list_r[:5]
plot(list_temp, list_R, list_r)
Arduinoでサーミスタを使う
実際にArduinoでサーミスタを使っていきましょう。
Arduinoとサーミスタの配線
こちらの図のように、Arduinoとサーミスタを配線します。
サーミスタと固定抵抗で分圧した値を、Arduinoのアナログ入力で読み取り、サーミスタの抵抗値を算出します。
サーミスタ103JT-050では、25℃のときに10kΩの抵抗値になりますので、固定抵抗を10kΩとしました。ここらへんは、測定したい温度範囲によって変えてもらって構いません。また、固定抵抗にはできるだけ誤差の少ない金属皮膜抵抗を使用しましょう。
センサにかける電圧は5Vを使用しました。
サーミスタで温度測定するソースコード
こちらが、Arduinoとサーミスタを使って温度を測定するソースコードになります。
#include <math.h>
#define THERMISTOR_PIN 0
const float DIVIDER = 10000.0; // 分圧抵抗10kΩ
const float T0 = 273.15;
const float R0 = 27700.0;
const float B = 3435.0;
float calcTemp(float Rt) {
float T_bar = 1/T0 + 1/B * log(Rt/R0);
return 1.0/T_bar - 273.15;
}
void setup() {
Serial.begin(9600);
pinMode(THERMISTOR_PIN, INPUT);
}
void loop() {
float Aout = float(analogRead(THERMISTOR_PIN));
// Serial.println(Aout);
float Rt = DIVIDER * Aout / (1024.0 - Aout);
float temp = calcTemp(Rt);
Serial.println(temp);
delay(1000);
}
ソースコードの解説
サーミスタの抵抗値Rtの算出
loop関数内では、アナログ入力値からサーミスタの抵抗値を算出しています。
抵抗値とADCの値の比を考えると、次式のようになります。
$$Aout:1024-Aout = R_t:10k \tag{4}$$
式4より、Rtについて解くと次式となります。
$$R_t=\frac{10k \times Aout}{1024-Aout} \tag{5}$$
居酒屋ガレージ日記さん にご指摘いただきまして、1023で割っていた式を1024に修正させていただきます。そもそもADコンバータで測れる値は、
$$V_{ref} - 1LSB = V_{ref} (1 - 1/1024)$$
という事らしいです。ですから厳密には、図中の5Vを\(V_{ref} - 1LSB\)にするのが正解なような気がします。
近似値の計算
calcTemp関数では、式3の近似値の計算式をそのままプログラミングしています。
サーミスタと分圧抵抗をステレオミニにまとめてはんだ付けしました。VccをTip、AoutをRing、GNDをSleeveに割り当てています。
ステレオミニですと、簡単にセンサのケーブルを延長できるので便利です。
サーミスタの温度校正
さて、ここまでの回路とプログラムを組んでサーミスタで温度測定してみると、製品の温度計と照らし合わせた時に温度がだいぶズレてしまうと思います。理論値はあくまで机上のものであることが分かります。そこでサーミスタの温度校正が必要になります。
温度が理論値からズレてしまう要因としましては、ADコンバータの精度、サーミスタの精度、基準となる製品の温度計の信頼性、温度観測ポイントのムラなどが挙げられると思います。ADコンバータのVref電圧にも気を使わないと、ArduinoやESP32などの内蔵ADコンバータで精度高く測定するのは難しいです。
そこで、サーミスタの温度精度をより上げるには、3点温度の抵抗値を測定してスタインハート式を使った温度校正をオススメします。詳しくはこちらの記事をご覧ください。
▼ Arduino初心者向きの内容となっています。ほかのArduino書籍と比べて図や説明がとてもていねいで、読みやすかったです。Arduinoで一通りのセンサーが扱えるようになります。
▼ 外国人が書いた本を翻訳したものです。この手の書籍は、目からうろこな発見をすることが多いです。
▼ Arduinoの入門書を既に読んでいる方で、次のステップを目指したい人向きの本です。C言語のプログラミングの内容が中心です。ESP32だけでなく、ふつうのArduinoにも役立つ内容でした。