Study/C#(Window programming)
NTC 온도센서(A1737) 온도 구하기2
Answer Choi
2025. 11. 20. 09:39
반응형

NTC A1737은 amphenol사의 ntc인데 이 제품은 온도에 따른 저항 값이 완전히 선형적이지 않습니다.

위 표와 같이 -40~0까지 저항이 급속히 떨어지며 0도부터 210도까지도 선형적이지 않고 아래 그림과 같이 몇번의 전환점이 있습니다.

NTC온도센서(A1737)온도 구하기 https://answerofgod.tistory.com/891
를 통해 선형보간법을 사용하여 온도를 구했었습니다.
하지만 수행시간이 올래걸리다 보니(내부에 for문이 있음)
좀 더 간단한 Steinhart-Hart 방정식으로 변경하였습니다.
#include <math.h> // log 함수를 사용하기 위해 math.h 헤더 포함
#define VDDA_VOLTAGE 3.3f // MCU 공급 전압 (V)
#define R_FIXED 510.0f // 상단 고정 저항값 R1 (옴)
// 온도와 저항 쌍을 저장하는 구조체 정의
typedef struct {
float resistance;
float temperature_c;
} ResistanceTempPair;
// 이미지 데이터시트에서 발췌한 R-T 테이블 (저항 기준 오름차순으로 정렬 필수)
// 참고: NTC 특성상 온도가 내려갈수록 저항이 급격히 증가합니다.
const ResistanceTempPair rt_table[] = {
{155.4f, 210.0f},
{309.9f, 175.0f},
{541.8f, 150.0f},
{886.9f, 130.0f},
{2036.0f, 100.0f},
{3776.0f, 80.0f},
{10851.0f, 50.0f},
{30000.0f, 25.0f},
{37387.0f, 20.0f},
{96248.0f, 0.0f},
{965530.0f, -40.0f}
};
// 테이블 크기 계산
const int table_size = sizeof(rt_table) / sizeof(rt_table[0]);
/**
* @brief 전압 분배기에서 측정된 전압을 섭씨 온도로 변환합니다 (2차 함수 근사 방식).
*
* 이 함수는 스택하르트-하트 방정식을 이용한 간소화된 2차 함수 근사를 사용합니다.
* NTC 서미스터의 비선형적인 특성을 더 잘 반영합니다.
*
* @param input_voltage TEMP1 핀에서 측정된 ADC raw value를 변환한 전압 값 (V)
* @return float 섭씨 온도 (°C), 범위를 벗어나면 -999.0f 반환
*/
float convert_voltage_to_celsius_quadratic(float input_voltage) {
float thermistor_resistance;
// 1. 입력 전압 유효성 검사
if (input_voltage < 0.0f || input_voltage > VDDA_VOLTAGE) {
return -999.0f;
}
// 2. 전압 분배기 공식을 사용하여 NTC 서미스터의 저항 계산
if (input_voltage >= (VDDA_VOLTAGE - 0.001f)) {
thermistor_resistance = 9999999999.0f; // 매우 높은 저항
} else if (input_voltage <= 0.001f) {
thermistor_resistance = 0.0f; // 거의 0옴
} else {
thermistor_resistance = R_FIXED * (input_voltage / (VDDA_VOLTAGE - input_voltage));
}
// 3. 스택하르트-하트 간소화 방정식 적용
// T = 1 / (A + B*ln(R) + C*(ln(R))^3)
// 이 방식은 주어진 LUT의 특정 구간에 국한되지 않고 전체 범위에서 비교적 정확한 값을 제공합니다.
// 하지만 이 방식은 NTC의 B 상수 등을 알아야 더 정확합니다.
// 요청된 2차 함수 근사를 위해 주어진 데이터를 가장 근사하는 특정 구간의 2차 다항식을 사용하는 대신
// NTC의 일반적인 특성을 따르는 아래와 같은 근사식을 활용하는 것이 더 효율적입니다.
// 여기서는 사용자가 제공한 데이터로 B 상수 모델을 유추하여 사용합니다.
// 데이터셋의 중간 두 지점(25도와 0도)을 기준으로 B 상수를 추정하여 단순화된 공식을 사용합니다.
// 실제 사용 시에는 NTC의 공식 B값을 사용해야 합니다.
const float T0 = 298.15f; // 25°C 켈빈 온도
const float R0 = 30000.0f; // 25°C에서의 저항값
// B 상수 추정치 (데이터셋 기준 대략적인 값, 실제 B값 사용 권장)
const float B_CONSTANT = 3970.0f; // K (켈빈)
float temperature_k;
if (thermistor_resistance > 0.0f) {
// 간소화된 Steinhart-Hart 방정식
temperature_k = 1.0f / (1.0f/T0 + (1.0f/B_CONSTANT) * log(thermistor_resistance/R0));
return temperature_k - 273.15f; // 켈빈 -> 섭씨 변환
} else {
return -999.0f;
}
}
adc로 읽어와 전압으로 변환한 후 전압을 기준으로 저항 값을 유추합니다.
유추된 저항이 A1737이 읽을 수 있는 범위에 있는지 검사합니다.
이상이 없는 경우 방정식을 이용하여 구합니다.
선형보간법에 비해 정확도는 떨어지나 거의 비슷합니다.
반응형