[아두이노] 서미스터 온도 측정 완벽 워크플로우 (저항형 센서 감도 조절 및 캘리브레이션)


“비선형 데이터를 직선으로 펴고, 기울기와 절편까지 맞춘다”

아두이노로 온도를 측정할 때 가장 흔히 겪는 문제는 단순합니다.

  • 값이 둔감하다 (변화가 잘 안 보인다)

  • 값이 비선형이다 (온도와 비례하지 않는다)

  • 값이 부정확하다 (실제 온도와 다르다)

이 문제를 해결하는 가장 정석적인 방법이 바로 다음 3단계입니다:

① 하드웨어 튜닝 → ② 수학적 선형화 → ③ 캘리브레이션

이 글에서는 이 과정을 “엔지니어링 워크플로우” 관점에서 정리합니다.


1. 하드웨어 단계: 가변저항으로 “감도” 확보

핵심 개념

서미스터는 온도에 따라 저항이 변하지만,
우리가 측정하는 것은 “전압”입니다.

그래서 반드시 전압 분배 회로를 구성해야 합니다.

회로 구조

5V ── 가변저항(Rf) ── A0 ── 서미스터(Rs) ── GND

여기서 중요한 포인트는:

가변저항을 이용해 “측정 구간”을 중앙에 맞춘다


왜 이게 중요할까?

ADC(analogRead)는 0~1023 범위를 사용합니다.

하지만 잘못 설정하면:

  • 800~820만 왔다 갔다 → ❌ 해상도 낭비

  • 100~120만 사용 → ❌ 감도 낮음


최적화 방법

👉 목표:
측정하려는 온도 범위의 중앙값에서 ADC ≈ 512

예:

  • 측정 범위: 25~30°C

  • 기준 온도: 27°C

  • 목표: analogRead ≈ 512 (약 2.5V)

조정 방법

  1. 실제 온도를 27°C로 맞춘다

  2. 가변저항을 돌린다

  3. analogRead 값이 512 근처가 되도록 맞춘다


결과

  • 위쪽/아래쪽 변화 모두 감지 가능

  • Headroom 확보

  • 측정 해상도 최대화


⚠️ 매우 중요한 주의사항

한 번 맞춘 후 절대 건드리지 마세요

이 값이 바뀌면 이후 모든 계산이 틀어집니다.


2. 소프트웨어 단계: 로그 함수로 “선형화”

문제의 본질

서미스터는 이렇게 동작합니다:

  • 온도 ↑ → 저항 ↓ (비선형, 지수형)

즉,

온도 vs 저항 그래프는 곡선이다


해결 방법: 로그 변환

로그를 취하면:

곡선 → 직선에 가까워짐

이를 정밀하게 모델링한 공식이 바로:

Steinhart-Hart 방정식

1/T = A + B·ln(R) + C·(ln(R))³
  • T: 절대온도(K)

  • R: 서미스터 저항

  • A, B, C: 센서 계수


처리 흐름

1) ADC → 전압

Vout = raw × (Vin / 1023)

2) 전압 → 저항

Rs = Rf × (Vout / (Vin - Vout))

3) 저항 → 온도

logR = ln(Rs)
T(K) = 1 / (A + B·logR + C·logR³)
T(°C) = T(K) - 273.15

결과

  • 비선형 데이터 → 거의 직선화

  • 온도 계산 가능

하지만…

아직 정확하지 않다 ❗


3. 캘리브레이션: “정확도” 완성

왜 필요한가?

  • 가변저항 값 정확하지 않음

  • 센서 오차 존재

  • ADC 오차 존재

즉,

계산값 ≠ 실제값


해결 방법: 2점 보정 (Linear Calibration)

1) 데이터 수집

조건실제 온도계산 온도
저온 (T1)20.0°CTcalc1
고온 (T2)35.0°CTcalc2

2) 보정 공식

Treal = (Tcalc - Tcalc1)
        × (T2 - T1) / (Tcalc2 - Tcalc1)
        + T1

의미

이건 단순히:

직선의 기울기 + 절편 맞추기

입니다.


직관적으로 보면

  • 로그 단계 → “직선으로 펴는 작업”

  • 캘리브레이션 → “직선 위치 맞추는 작업”


4. 통합 아두이노 코드

#include <math.h>

const float V_IN = 5.0;
const float R_FIXED = 10000.0;

// Steinhart-Hart 계수
const float A = 0.001129148;
const float B = 0.000234125;
const float C = 0.0000000876741;

void setup() {
  Serial.begin(9600);
}

void loop() {
  int raw = analogRead(A0);

  // 1. 전압 계산
  float vOut = raw * (V_IN / 1023.0);

  // 2. 저항 계산
  float rSensor = R_FIXED * (vOut / (V_IN - vOut));

  // 3. 선형화
  float logR = log(rSensor);
  float tempK = 1.0 / (A + B * logR + C * pow(logR, 3));
  float tempC = tempK - 273.15;

  // 4. 캘리브레이션
  float calibratedTemp = fmap(tempC, 21.5, 36.2, 20.0, 35.0);

  Serial.print("Raw Temp: ");
  Serial.print(tempC);
  Serial.print(" | Calibrated: ");
  Serial.println(calibratedTemp);

  delay(1000);
}

// float용 map 함수
float fmap(float x, float in_min, float in_max, float out_min, float out_max) {
  return (x - in_min) * (out_max - out_min)
       / (in_max - in_min) + out_min;
}

5. 전체 워크플로우 정리

① 하드웨어 (가변저항)

👉 전압 변화 폭 최적화
👉 해상도 확보


② 수학 (로그 함수)

👉 곡선을 직선으로 변환
👉 선형성 확보


③ 캘리브레이션

👉 실제 값에 맞춤
👉 정확도 확보


핵심 한 줄 정리

센서 엔지니어링 =
“감도(하드웨어) + 선형화(수학) + 보정(실측)”


이 구조를 이해하면,

  • CdS 센서

  • 압력 센서

  • 가스 센서

같은 모든 저항형 센서에 그대로 적용할 수 있습니다.


원하면
👉 “왜 로그를 취하면 직선이 되는지 (수학적으로)”
👉 “가변저항 값에 따라 감도가 어떻게 변하는지 (그래프)”

이것도 이어서 깊게 파헤쳐 줄게.

댓글

이 블로그의 인기 게시물

공압 속도 제어: 미터인 vs 미터아웃

NPN, PNP 트랜지스터 차이점

[PLC] 센서 NPN, PNP 출력 타입별 결선방법 (OMRON E2E-X 시리즈 3선식 배선)

[주식] 한국거래소(KRX) 데이터 API 입문 가이드

[투자] ETF 투자 가이드 : 카테고리별 ETF 선택 전략

[PLC] PLC 아날로그 입출력 기본

[농사] 천연 식물성 살충제 종류 및 제조법

[PLC] 릴레이

[PLC] 서보 모터 브레이크 결선, 왜 릴레이 터미널을 써야 할까?

[PLC] 릴레이 자기유지 (Realy Latch or Sealing)