[아두이노] 라이브러리 없이 SHT30 온습도 센서 직접 제어하기 (Arduino/I2C)
대부분 아두이노에서 센서를 다룰 때는 전용 라이브러리를 사용합니다.
하지만 산업 현장이나 임베디드 환경에서는 메모리 절약, 디버깅 편의성, 그리고 예외 처리 강화를 위해 데이터시트를 직접 해석하여 구현하는 경우가 많습니다.
특히 PLC, 산업용 제어기기, 펌웨어 개발에서는 라이브러리 의존성을 줄이는 것이 시스템 안정성 측면에서 큰 장점이 됩니다.
이번 글에서는 Wire.h만 사용하여 SHT30 센서를 직접 제어하는 방법을 정리해 보겠습니다.
1. SHT30의 통신 메커니즘 이해하기
SHT30은 I2C 기반 디지털 온습도 센서입니다.
라이브러리 내부에서 실제로 수행되는 동작은 생각보다 단순합니다.
MCU와 센서는 아래 순서대로 통신합니다.
Single Shot Mode 동작 순서
I2C START 조건 생성
센서 주소(
0x44) 전송측정 명령어(
0x2C06) 전송센서 내부 측정 완료까지 대기
측정 결과 6바이트 읽기
Raw 데이터를 온습도로 변환
즉, 라이브러리란 결국 이 과정을 함수로 감춰놓은 것에 불과합니다.
2. SHT30 기본 배선
Arduino UNO 기준
| SHT30 | Arduino UNO |
|---|---|
| VCC | 3.3V ~ 5V |
| GND | GND |
| SDA | A4 |
| SCL | A5 |
3. 중요한 특징: I2C 주소는 제조 단계에서 결정됨
SHT30 모듈은 일반적으로 아래 두 가지 주소 중 하나를 사용합니다.
| ADDR 핀 상태 | I2C 주소 |
|---|---|
| LOW | 0x44 |
| HIGH | 0x45 |
문제는 알리익스프레스 등에서 판매되는 일부 SHT30 모듈은:
ADDR 핀이 외부로 노출되지 않거나
PCB 내부에서 GND/VCC로 고정되어 있는 경우가 많다는 점입니다.
즉:
사용자가 주소를 변경할 수 없는 경우가 존재
제조 단계에서 주소가 사실상 결정됨
이라는 특징이 있습니다.
따라서 여러 개의 SHT30을 동시에 연결하려면:
0x440x45
주소 조합을 고려해야 하며,
동일 주소 센서를 여러 개 연결해야 하는 경우에는:
I2C 멀티플렉서(TCA9548A)
별도 I2C 버스
RS485 기반 센서
등을 고려해야 합니다.
4. 라이브러리 없이 직접 제어하기
아래 코드는 Wire.h만 사용하여 SHT30을 직접 제어하는 예제입니다.
#include <Wire.h>
void setup() {
Wire.begin();
Serial.begin(9600);
Serial.println("SHT30 Raw Control Start...");
}
void loop() {
// =====================================================
// 1. 측정 시작 명령 전송
// Command: 0x2C06
// High Repeatability + Clock Stretching Enabled
// =====================================================
Wire.beginTransmission(0x44);
Wire.write(0x2C);
Wire.write(0x06);
// 통신 종료 후 ACK 확인
if (Wire.endTransmission() != 0) {
Serial.println("Error: Sensor not found");
delay(2000);
return;
}
// =====================================================
// 2. 센서 측정 대기
// 데이터시트 권장: 약 15~20ms 이상
// =====================================================
delay(50);
// =====================================================
// 3. 센서 데이터 요청
// 총 6바이트:
// Temp MSB
// Temp LSB
// Temp CRC
// Humidity MSB
// Humidity LSB
// Humidity CRC
// =====================================================
Wire.requestFrom(0x44, 6);
if (Wire.available() == 6) {
// -----------------------------
// Temperature RAW
// -----------------------------
uint16_t t_raw =
(Wire.read() << 8) | Wire.read();
uint8_t t_crc = Wire.read();
// -----------------------------
// Humidity RAW
// -----------------------------
uint16_t h_raw =
(Wire.read() << 8) | Wire.read();
uint8_t h_crc = Wire.read();
// =====================================================
// 4. 데이터시트 공식으로 변환
// =====================================================
// Temperature:
// T = -45 + 175 * RAW / 65535
float temperature =
-45.0 +
(175.0 * (float)t_raw / 65535.0);
// Humidity:
// RH = 100 * RAW / 65535
float humidity =
100.0 *
(float)h_raw / 65535.0;
// =====================================================
// 5. 결과 출력
// =====================================================
Serial.print("Temp: ");
Serial.print(temperature, 1);
Serial.print(" C");
Serial.print(" | Hum: ");
Serial.print(humidity, 1);
Serial.println(" %");
}
delay(2000);
}
5. 핵심 이해 포인트
측정 명령 0x2C06
Wire.write(0x2C);
Wire.write(0x06);
이 두 바이트는:
측정 시작
고정밀 모드
Clock Stretching 사용
이라는 의미를 갖는 SHT30 전용 명령어입니다.
즉, 라이브러리는 결국 이런 명령어를 대신 보내주는 역할을 합니다.
6. Raw 데이터는 왜 16비트인가?
센서는 실제 온도를 바로 보내지 않습니다.
대신:
0 ~ 65535
범위의 디지털 값(Raw Data)을 전송합니다.
즉:
ADC 변환 결과
내부 보정값 적용 결과
센서 내부 DSP 처리 결과
등이 포함된 값입니다.
MCU는 이를 다시 물리량으로 변환해야 합니다.
7. 데이터시트의 Transfer Function
SHT30 데이터시트에는 아래 공식이 존재합니다.
온도 변환 공식:
T=-45+175\times\frac{S_T}{2^{16}-1}
습도 변환 공식:
RH=100\times\frac{S_{RH}}{2^{16}-1}
여기서:
S_T= Temperature Raw DataS_RH= Humidity Raw Data
입니다.
즉 센서는:
물리 세계
디지털 비트 세계
사이를 연결하는 변환 장치라고 볼 수 있습니다.
8. CRC 바이트의 의미
SHT30은 각 데이터 블록마다 CRC8 체크섬을 함께 전송합니다.
온도 데이터:
2바이트 + CRC1바이트
습도 데이터:
2바이트 + CRC1바이트
즉 총 6바이트를 전송합니다.
CRC는:
노이즈
EMI
배선 불량
통신 오류
등으로 데이터가 깨졌는지 검증하기 위한 용도입니다.
산업 환경에서는 이 CRC 검증이 매우 중요합니다.
9. 왜 라이브러리 없이 구현하는가?
① 데이터시트 이해 능력 향상
센서의 동작 원리를 깊게 이해하게 됩니다.
단순히 함수 호출이 아니라:
어떤 명령을 보내는지
어떤 데이터가 오는지
어떤 수식으로 변환되는지
를 직접 이해하게 됩니다.
② 시스템 최적화
전용 라이브러리는 범용성을 위해 코드가 무겁습니다.
하지만 직접 구현하면:
Flash 사용량 감소
RAM 사용량 감소
실행 속도 향상
효과를 얻을 수 있습니다.
특히 저사양 MCU에서는 큰 차이가 납니다.
③ 산업용 시스템 안정성
현장에서는:
통신 실패
CRC 오류
타임아웃
센서 Disconnect
같은 상황을 세밀하게 처리해야 합니다.
직접 구현하면 이러한 예외 처리 로직을 정교하게 설계할 수 있습니다.
마무리
라이브러리를 사용하는 것은 편리합니다.
하지만 센서와 MCU가 실제로 어떤 "비트 단위 대화"를 하는지 이해하는 순간부터 임베디드 개발 실력이 크게 성장하기 시작합니다.
특히 산업 자동화, PLC, 펌웨어 개발에서는:
데이터시트 해석 능력
프로토콜 이해 능력
Raw 데이터 처리 능력
이 매우 중요한 역량이 됩니다.
댓글
댓글 쓰기