サーミスタによる温度測定
機器の温度監視で最も使われるセンサがNTCサーミスタです。安価で感度が高い一方、出力は抵抗値です。さらに温度に対して直線的に変化しないため、ADC値から温度へ変換する部分でつまずきがちです。本記事では、分圧回路の設計からB定数による温度変換、計算を軽くするテーブル方式、精度を左右するポイントまで、順に解説します。
- NTCサーミスタの基礎:抵抗値とB定数
- 分圧回路でADCにつなぐ
- ADC値から抵抗値を逆算する
- B定数式で温度に変換する
- logfの計算コストが高いときはテーブル+補間で
- 精度を左右する4つのポイント
- ありがちなトラブル
- まとめ
NTCサーミスタの基礎:抵抗値とB定数
NTCサーミスタは、温度が上がると抵抗値が下がる素子です。仕様は主に2つの値で表されます。1つは基準温度(通常25℃)での抵抗値で、10kΩ品が定番です。もう1つがB定数で、温度変化に対する抵抗値変化の感度(特性カーブの傾き)を表します。B定数は製品によって幅があり、実用上は3000K〜5000K程度がよく使われます(用途や品種によっては2000K〜6000K程度まで存在します)。2つの温度間の抵抗値から算出されるため「B25/85」のように算出温度を明示して表記されます。データシートでこの2つを確認することが出発点です。
※B定数は便宜上「定数」として扱いますが、材料や温度域によって見かけ上は変化します。
分圧回路でADCにつなぐ
サーミスタの抵抗値はそのままでは読めないため、固定抵抗と直列にして電圧に変換し、その分圧点をADCで読みます。本記事では「電源側に固定抵抗、GND側にサーミスタ」という構成で説明します。固定抵抗には、測定したい温度範囲の中心付近でのサーミスタ抵抗値と同程度(10kΩ品なら10kΩ)を選ぶと、感度のよい電圧範囲を使えます。
このとき大切なのが、ADCの基準電圧を分圧回路と同じ電源にしておくことです。分圧の出力は電源電圧との比で決まるため、基準電圧も同じ電源にすると電源変動が打ち消されます(レシオメトリック測定)。電源とは別の基準電圧を使うと、電源のふらつきがそのまま温度誤差になります。
※分圧回路の励起(VCC)とADCのVrefが同一電源で、両者が同じ変動を受ける構成で有効です(ノイズ成分は別途対策が必要)。
ADC値から抵抗値を逆算する
分圧の式を変形すると、ADC値からサーミスタの抵抗値が求まります。「固定抵抗が電源側」の構成では次のようになります(ADC_MAXは12ビットなら4095)。※以下は「電源側(VCC側)にR_FIX、GND側にR_th、ADCは中点」という構成の場合です。
R_th = R_FIX × adc ÷ (ADC_MAX − adc)
※ADC_MAXは「最大コード値」です(12ビットなら通常4095)。使用するADCドライバが「分解能(4096)」で扱う場合は読み替えてください。
adcがADC_MAXのときは分母が0になりゼロ除算が発生します。一方、adcが0のときは抵抗値が0となり、以降の対数計算が成立しません(いずれも断線・短絡時に起こり得ます)。そのため、コードでは範囲ガードを必ず入れる必要があります。実機ではノイズなどで端点付近に張り付くこともあるため、端点と完全に一致する値だけを異常とみなさず、しきい値(ガードバンド)を設けることで検出漏れや誤検出を減らせます。このガードバンド判定は、センサ異常(断線・短絡)の検出にもそのまま活用できます。
B定数式で温度に変換する
抵抗値と絶対温度の関係は指数関数で近似されます。B定数の定義式は下記のとおりです。この式をTについて解くと温度が求まります(コード内コメント参照)。ここでlnは自然対数(C言語ではlogf())です。温度は摂氏ではなくケルビンで計算する点にも注意が必要です。
B = ln(R/R0) ÷ (1/T − 1/T0)
※ここでのT、T0は絶対温度(ケルビン)です。
#include <math.h>
#include <stdint.h>
#define B_CONST 3435.0f /* B定数 [K](データシート値) */
#define R0_OHM 10000.0f /* 25℃での抵抗値 [Ω] */
#define T0_KELVIN 298.15f /* 基準温度 25℃ = 298.15K */
#define R_FIX 10000.0f /* 分圧の固定抵抗 [Ω] */
#define ADC_MAX 4095u /* 12ビットADC */
#define ADC_MIN_TH 20u /* 下限ガードバンド(断線・短絡判定) */
#define ADC_MAX_TH 4075u /* 上限ガードバンド(断線・短絡判定) */
float thermistor_to_celsius(uint16_t adc)
{
if ((adc <= ADC_MIN_TH) || (adc >= ADC_MAX_TH)) {
return -999.0f; /* 断線・短絡などの異常 */
}
/* ADC値からサーミスタ抵抗値を逆算 */
float r_th = R_FIX * (float)adc / (float)(ADC_MAX - adc);
/* B定数式: 1/T = 1/T0 + (1/B)・ln(R/R0) */
float inv_t = 1.0f / T0_KELVIN + logf(r_th / R0_OHM) / B_CONST;
return (1.0f / inv_t) - 273.15f; /* ケルビン → 摂氏 */
}
※このサンプルでは戻り値の-999.0fで異常を表現していますが、実装ではboolで成否を返して温度を出力引数にする、またはNANを返すなど、システムの方針に合わせてください。
logfの計算コストが高いときはテーブル+補間で
logf()と浮動小数点演算は、FPUのないマイコンでは処理時間もコードサイズも無視できません。温度範囲が決まっている用途では、5℃刻み程度で「ADC値→温度」の対応表をあらかじめ計算しておき、実行時は表引きと線形補間だけで済ませる方式が定番です。表はPCやスプレッドシートで生成してconst配列としてROMに置きます。テーブルと補間の実装は別記事「ルックアップテーブルと補間の実装」で詳しく扱います。
精度を左右する4つのポイント
- B定数式は2点間の近似:算出温度(B25/85なら25〜85℃)から離れるほど誤差が増えます。広範囲・高精度が必要ならSteinhart-Hart式(3定数近似)やメーカ提供のR/T表を使います。Steinhart-Hart式は、B定数式より広い温度域で近似精度を高めるために用いられます。
- 固定抵抗の精度:分圧の相方なので、固定抵抗の誤差はそのまま温度誤差になります。許容差1%以下の高精度品を使い、温度係数にも注意します。
- 自己発熱:サーミスタ自身に流れる電流による発熱で、実際より高い温度を示します。仕様書の熱放散定数(自己発熱で1℃上げるのに必要な電力)を確認し、測定電流を小さくするか、測定時だけ通電する設計にします。
- ノイズ:ADC値は複数回読んで平均やメディアンを取ります。
ありがちなトラブル
- 温度の動きが逆:固定抵抗とサーミスタの上下(電源側/GND側)が想定と逆になっています。逆算式が回路構成と一致しているか確認してください。
- 全体的にずれる:ケルビン換算(273.15)の入れ忘れ、B定数や25℃抵抗値の取り違え、基準電圧の不一致が定番です。
- 常に少し高めに出る:自己発熱を疑います。固定抵抗を大きくして電流を減らすと改善します。
まとめ
サーミスタの温度変換は「分圧→抵抗値逆算→B定数式」の3段階です。レシオメトリック測定・範囲ガード・自己発熱対策の3点を押さえれば、実用十分な温度計測がローコストで実現できます。

