[파이썬] SHT30 Modbus RS485 온습도 센서 제어 가이드 (결선부터 레지스터 분석까지)
산업용 현장이나 스마트 팜에서 정밀한 환경 데이터 수집을 위해 많이 사용되는 SHT30 Modbus RTU 센서.
이번 글에서는 이 센서를 아두이노가 아닌 PC에 직접 연결하여 파이썬(Python) 으로 데이터를 읽어오는 전체 과정을 정리해보겠습니다.
RS485 결선 방법부터 Modbus 레지스터 구조, 파이썬 코드, 실제 통신 패킷 분석까지 한 번에 이해할 수 있도록 구성했습니다.
1. 하드웨어 구성 및 물리적 결선
PC는 RS485 신호를 직접 읽을 수 없으므로 반드시 USB to RS485 컨버터가 필요합니다.
또한 센서의 안정적인 동작을 위해 외부 전원을 사용하는 것이 좋습니다.
준비물
SHT30 Modbus RS485 센서
USB to RS485 컨버터
DC 전원 공급 장치 (5V ~ 24V)
PC
점퍼선
상세 결선표
| 센서 선 색상 | 신호 명칭 | 연결 대상 | 비고 |
|---|---|---|---|
| 적색 (Red) | VCC | 외부 전원 (+) | DC 5V ~ 24V |
| 흑색 (Black) | GND | 외부 전원 (-) 및 컨버터 GND | 공통 접지 필수 |
| 황색 (Yellow) | RS485-A | USB 컨버터 A(D+) | 데이터 + |
| 백색 (White) | RS485-B | USB 컨버터 B(D-) | 데이터 - |
핵심 포인트: 공통 접지(Common GND)
RS485는 차동 신호 방식이라 노이즈에 강하지만, 실제 현장에서는 반드시 GND를 공통으로 연결하는 것이 안정적입니다.
즉:
센서 GND
외부 전원 GND
RS485 컨버터 GND
이 세 개를 서로 연결하는 것이 좋습니다.
2. Modbus 레지스터 구조 이해
SHT30 Modbus 센서는 내부 데이터를 Holding Register 형태로 저장합니다.
우리는 특정 주소(Register Address)를 읽어서 온도와 습도를 가져오게 됩니다.
레지스터 맵(Register Map)
| 주소 (HEX) | 내용 | 데이터 타입 | 처리 방식 |
|---|---|---|---|
| 0x0000 | 현재 온도 | 16-bit Signed Integer | 값 ÷ 10.0 |
| 0x0001 | 현재 습도 | 16-bit Unsigned Integer | 값 ÷ 10.0 |
3. 왜 10으로 나누는가?
Modbus 장비는 부동소수점(Float)을 사용하지 않는 경우가 많습니다.
따라서 실제 데이터를:
실제값 × 10
형태의 정수(Integer)로 변환하여 전송합니다.
예를 들어:
실제 온도 = 25.4℃
전송 데이터 = 254
즉, 수신 측에서는 다시:
temperature = raw_value / 10.0
형태로 복원해야 합니다.
4. 파이썬 환경 설정
먼저 필요한 라이브러리를 설치합니다.
pip install pymodbus pyserial
5. 전체 파이썬 코드
아래 코드는:
COM 포트 연결
Modbus RTU 통신
온도/습도 읽기
음수 온도 처리
실시간 출력
까지 모두 포함한 전체 예제입니다.
import time
from pymodbus.client import ModbusSerialClient as ModbusClient
# ---------------------------------------------------
# Modbus RTU 통신 설정
# ---------------------------------------------------
client = ModbusClient(
port='COM3', # 자신의 COM 포트로 수정
baudrate=9600,
parity='N',
stopbits=1,
bytesize=8,
timeout=1
)
# ---------------------------------------------------
# 센서 데이터 읽기 함수
# ---------------------------------------------------
def read_sht30_data():
# 연결 시도
if not client.connect():
print("RS485 컨버터 연결 실패")
return
# Holding Register 읽기
# address=0x00 : 시작 주소
# count=2 : 온도 + 습도 총 2개 읽기
# slave=1 : 센서 ID
response = client.read_holding_registers(
address=0x00,
count=2,
slave=1
)
# 정상 응답 확인
if not response.isError():
# 레지스터 데이터 추출
raw_temp = response.registers[0]
raw_humi = response.registers[1]
# -------------------------------------------
# 음수 온도 처리
# 16-bit Signed Integer 변환
# -------------------------------------------
if raw_temp > 32767:
raw_temp -= 65536
# 실제 값 복원
temperature = raw_temp / 10.0
humidity = raw_humi / 10.0
# 출력
current_time = time.strftime('%Y-%m-%d %H:%M:%S')
print(f"[{current_time}]")
print(f"Temperature : {temperature:.1f} C")
print(f"Humidity : {humidity:.1f} %")
print("-" * 40)
else:
print("데이터 읽기 실패")
# 연결 종료
client.close()
# ---------------------------------------------------
# 메인 루프
# ---------------------------------------------------
if __name__ == "__main__":
try:
while True:
read_sht30_data()
# 센서 안정화를 위해
# 2초 간격 권장
time.sleep(2)
except KeyboardInterrupt:
print("프로그램 종료")
6. 코드 동작 원리 분석
1) ModbusClient 생성
client = ModbusClient(
port='COM3',
baudrate=9600,
parity='N',
stopbits=1,
bytesize=8,
timeout=1
)
RS485 통신 조건을 설정합니다.
일반적인 SHT30 Modbus 기본값:
Baudrate = 9600
Data Bits = 8
Stop Bits = 1
Parity = None
입니다.
2) Holding Register 읽기
response = client.read_holding_registers(
address=0x00,
count=2,
slave=1
)
의 의미는:
시작 주소 0번부터
총 2개의 레지스터를
Slave ID 1번 장치에게 요청
한다는 뜻입니다.
3) 음수 온도 처리
온도는 Signed Integer 방식입니다.
즉:
-32768 ~ +32767
범위를 사용합니다.
따라서:
if raw_temp > 32767:
raw_temp -= 65536
과정을 통해 2의 보수(Two's Complement)를 복원합니다.
예시:
65526 → -10
즉:
-1.0℃
가 됩니다.
7. 실제 Modbus 통신 패킷 분석
실제 데이터 흐름을 보면 디버깅이 훨씬 쉬워집니다.
요청(Request) 패킷
01 03 00 00 00 02 C4 0B
의미:
| 바이트 | 의미 |
|---|---|
| 01 | Slave ID |
| 03 | Holding Register 읽기 |
| 00 00 | 시작 주소 |
| 00 02 | 읽을 개수 |
| C4 0B | CRC |
즉:
"1번 센서야, 0번 주소부터 2개 데이터 줘"
라는 뜻입니다.
응답(Response) 패킷
01 03 04 01 0E 02 58 BB D8
분석:
| 데이터 | 의미 |
|---|---|
| 01 0E | 온도 |
| 02 58 | 습도 |
HEX → DEC 변환:
0x010E = 270
0x0258 = 600
최종 변환:
270 / 10 = 27.0℃
600 / 10 = 60.0%
8. 통신이 안 될 때 체크리스트
1) A/B 선 반대로 연결됨
가장 흔한 문제입니다.
A ↔ B
B ↔ A
로 바꿔서 테스트해보세요.
2) COM 포트 확인
Windows 장치 관리자에서:
포트(COM 및 LPT)
항목 확인 후:
port='COM3'
부분 수정 필요.
3) Slave ID 불일치
센서 기본 ID가:
1
이 아닐 수도 있습니다.
제품 메뉴얼 확인 필요.
4) Baudrate 불일치
일부 제품은:
4800
19200
등을 사용하기도 합니다.
9. 데이터 로깅 확장 아이디어
이제 다음 단계로 확장 가능합니다.
CSV 자동 저장
SQLite 데이터베이스 저장
실시간 그래프 표시
웹 대시보드 구축
MQTT 연동
스마트팜 자동화
PLC 연동
등 다양한 환경 모니터링 시스템으로 발전시킬 수 있습니다.
마무리
SHT30 Modbus RS485 센서는:
높은 정밀도
장거리 통신 안정성
산업 현장 친화성
을 모두 갖춘 매우 강력한 센서입니다.
특히:
Modbus 레지스터 구조
RS485 결선
Signed Integer 처리
이 세 가지만 이해하면 대부분의 산업용 센서를 동일한 방식으로 제어할 수 있습니다.
이번 글이 RS485 및 Modbus RTU 입문의 좋은 출발점이 되길 바랍니다.
댓글
댓글 쓰기