· 

11.温度センサープロジェクト(1)ーRaspberry Pi Pico WindowsC言語入門

13.1.サーミスタによる温度計測

プロジェクト名:TempThermistor

プロジェクト概要

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;

次に、抵抗値を求めます。回路図から分圧抵抗R110Kです。

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抵抗                                         

GROVE16 x 2 LCD                                                                     スイッチサイエンス

 

配線図

ソースリスト

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℃程度高くなっておりますが、この誤差はリニアですので、補正をすることで、実用になると思います。ばらつきも安定しています。