13.1.サーミスタによる温度計測
プロジェクト概要
SEMITEC株式会社のATサーミスタ10kΩ-103ATを使用した温度計測のプロジェクトです。秋月電子通商から販売されています。
抵抗値(25℃):10kΩ±1%
B定数(25-85℃):3435K±1%
熱放散定数(25℃):約2mW/℃
熱時定数(25℃):約15s
定格電力(25℃):10mW
使用温度範囲:-50~+110℃
温度の求め方は以下です。
//ADC
const float ConversionFactor = 3.3f / (1 << 12);
//Ntc thermistor
const float Bvalue = 3435; //B定数の設定
const float Ktemp25 = 298.15; //摂氏25度のケルビン温度
const float Resi25 = 10000; //摂氏25度のサーミスタ抵抗
const float R1 = 10000; //分圧測定のための抵抗
まず、12bitのバイナリ電圧値を、Volt電圧に変換します。
F loat thVolt = (float)adc_read() * ConversionFactor;
次に、抵抗値を求めます。回路図から分圧抵抗R1は10Kです。
float thResi = (thVolt * R1)/(3.3f - thVolt);
メーカーから提供されているB定数、25℃のケルビン定数、および25℃の抵抗値からケルビン温度を求めます。
float ktemp = 1.0f/(1.0f/Bvalue * log(thResi/Resi25) + (1.0f/Ktemp25));
最後にケルビン温度から摂氏の温度を求めます。
float ctemp = ktemp -273.15f;
本プロジェクトでは、同時にPico内蔵のオンボード温度センサーでの温度も計測し、表示します。比較することで、サーミスターの温度の誤差、ノイズ等を確認できます。
部品リスト
SEMITEC APサーミスタNTCサーミスタ10kΩ103AT-2 1 秋月電子通商
1/4W 10K抵抗 1
GROVEの16 x 2 LCD 1 スイッチサイエンス
配線図

ソースリスト
include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "pico/stdlib.h"
#include "hardware/i2c.h"
#include "pico/util/datetime.h"
#include "hardware/rtc.h"
#include "hardware/adc.h"
//#define PICO_DEFAULT_LED_PIN 25
#define LED_PIN PICO_DEFAULT_LED_PIN
#define ADC0_PIN 26
#define I2C_PORT i2c0
#define I2C_SDA 8
#define I2C_SCL 9
//ADc
const float ConversionFactor = 3.3f / (1 << 12);
//Ntc thermistor
const float Bvalue = 3435; //B定数の設定
const float Ktemp25 = 298.15; //摂氏25度のケルビン温度
const float Resi25 = 10000; //摂氏25度のサーミスタ抵抗
const float R1 = 10000; //分圧測定のための抵抗
//10.1章参照-----
int WaitTerminalStartup(int timeout_msec) {
void ScanI2CBus() {
//------------------
void InitAdc()
{
adc_init();
adc_set_temp_sensor_enabled(true);
adc_gpio_init(ADC0_PIN);
}
float ReadOnBoardTemperature()
{
adc_select_input(4);
float tempV = (float)adc_read() * ConversionFactor;
float tempC = 27.0f - (tempV - 0.706f) / 0.001721f;
return tempC;
}
float ReadThermistorTemperature()
{
adc_select_input(0);
float thVolt = (float)adc_read() * ConversionFactor;
float thResi = (thVolt * R1)/(3.3f - thVolt);
float ktemp = 1.0f/(1.0f/Bvalue * log(thResi/Resi25) + (1.0f/Ktemp25));
float ctemp = ktemp -273.15f;
return ctemp;
}
//10.3章参照-----
void InitRtc()
//10.2章参照
//lcd -------------
int main()
{
stdio_init_all();
gpio_init(LED_PIN);
gpio_set_dir(LED_PIN, GPIO_OUT);
gpio_put(LED_PIN, 0);
i2c_init(I2C_PORT, 400*1000);
gpio_set_function(I2C_SDA, GPIO_FUNC_I2C);
gpio_set_function(I2C_SCL, GPIO_FUNC_I2C);
gpio_pull_up(I2C_SDA);
gpio_pull_up(I2C_SCL);
WaitTerminalStartup(30*1000);
printf("\nTerminal connected\n");
ScanI2CBus();
printf("I2C Scan completed\n");
lcd_init();
InitAdc();
InitRtc();
char buf[128];
datetime_t nowdt;
int presec = -1;
while (1) {
rtc_get_datetime(&nowdt);
if(presec != nowdt.sec)
{
sprintf(buf, "%02d/%02d %02d:%02d:%02d", nowdt.month, nowdt.day, nowdt.hour,nowdt.min, nowdt.sec);
lcd_set_cursor(0, 0);
lcd_string(buf);
float btemp = ReadOnBoardTemperature();
float ttemp = ReadThermistorTemperature();
sprintf(buf, "TH:%4.1f ADC:%4.1f", ttemp, btemp);
lcd_set_cursor(1, 0);
lcd_string(buf);
printf("%4d/%02d/%02d %02d:%02d:%02d thermistor:%4.1f onborad:%4.1f\n", nowdt.year, nowdt.month, nowdt.day,
nowdt.hour,nowdt.min, nowdt.sec, ttemp, btemp);
}
presec = nowdt.sec;
sleep_ms(200);
}
return 0;
}

オンボード温度センサーに比べて5℃程度高くなっておりますが、この誤差はリニアですので、補正をすることで、実用になると思います。ばらつきも安定しています。
コメントをお書きください