[파이썬] SHT30 Modbus 센서 (SHA9D01): 단순 측정을 넘어 '제어'와 '교정'까지



알리익스프레스에서 흔히 판매되는 SHT30 Modbus RTU 온습도 센서 (이 글에서는 SHA9D01 모델 사용함.)는 단순히 데이터를 읽는 수준을 넘어, 실제 산업 환경에서 필요한 다양한 설정 기능을 제공합니다.

대표적으로:

  • 슬레이브 ID 변경

  • 통신 속도(Baudrate) 변경

  • 온도/습도 오차 보정(Calibration)

등을 지원하며, 이를 통해 여러 개의 센서를 하나의 RS485 라인에 연결하거나 현장 환경에 맞는 정밀 보정까지 수행할 수 있습니다.

이번 글에서는 이러한 고급 기능들을 실제 Modbus 레지스터 기반으로 상세히 분석해보겠습니다.


1. SHT30 Modbus 센서의 고급 기능

많은 입문자들이:

온도 읽기
습도 읽기

까지만 사용하지만, 실제 산업 환경에서는 센서 설정 기능이 훨씬 중요합니다.

예를 들어:

  • 공장 내부 여러 위치에 센서를 설치

  • 스마트팜 여러 구역 모니터링

  • PLC 기반 중앙 통합 제어

등을 하려면 센서마다 서로 다른 주소(ID)가 필요합니다.

또한 설치 환경에 따라 측정 오차가 발생할 수 있기 때문에 보정 기능도 매우 중요합니다.


2. Modbus 기능 코드(Function Code) 이해

SHT30 Modbus 모듈은 일반적으로 아래 기능 코드를 지원합니다.

기능 코드이름설명
03Read Holding Registers데이터 읽기
06Write Single Register단일 설정값 변경
16Write Multiple Registers여러 설정 동시 변경

Function Code 03

가장 많이 사용하는 읽기 명령입니다.

예:

온도 읽기
습도 읽기
ID 읽기
보드레이트 읽기

등에 사용됩니다.


Function Code 06

설정 변경 시 가장 중요합니다.

예:

슬레이브 ID 변경
온도 보정값 변경
습도 보정값 변경

등에 사용됩니다.


Function Code 16

여러 개의 레지스터를 동시에 수정할 때 사용합니다.

하지만 실제 현장에서는 안정성을 위해:

06번 명령으로 하나씩 수정

하는 경우가 많습니다.


3. 상세 레지스터 맵(Register Map)

제조사마다 약간 차이는 있지만, 대부분 아래 구조를 따릅니다.

주소 (HEX)기능R/W설명
0x0000현재 온도R실측값 × 10
0x0001현재 습도R실측값 × 10
0x0101슬레이브 IDR/W1~247
0x0102보드레이트R/W통신 속도
0x0103온도 보정값R/W단위 0.1℃
0x0104습도 보정값R/W단위 0.1%

4. 보드레이트(Baudrate) 값 체계

보통 다음과 같은 숫자 테이블을 사용합니다.

Baudrate
09600
114400
219200

일부 제품은:

  • 4800

  • 38400

  • 115200

등도 지원합니다.

반드시 판매 페이지나 메뉴얼 확인이 필요합니다.


5. 보정값(Calibration Offset)의 동작 원리

보정값은:

실제 측정값에 더해지는 오프셋(offset)

입니다.

예를 들어:

  • 실제 온도: 25.0℃

  • 센서 측정값: 25.7℃

라면:

-0.7℃

보정을 적용하면 됩니다.

센서는 내부적으로:

측정값 + 보정값

을 계산하여 최종 데이터를 반환합니다.


6. 파이썬 환경 준비

필요 라이브러리 설치:

pip install pymodbus pyserial

7. 전체 통합 테스트 코드

아래 코드는:

  • 데이터 읽기

  • 온도 보정

  • 슬레이브 ID 변경

까지 모두 포함한 실전 예제입니다.

import time
from pymodbus.client import ModbusSerialClient as ModbusClient

# -------------------------------------------------
# Modbus RTU 클라이언트 설정
# -------------------------------------------------

client = ModbusClient(
    port='COM3',
    baudrate=9600,
    parity='N',
    stopbits=1,
    bytesize=8,
    timeout=1
)

# -------------------------------------------------
# 메인 테스트 함수
# -------------------------------------------------

def run_test():

    # 연결 확인
    if not client.connect():
        print("RS485 연결 실패")
        return

    print("센서 연결 성공\n")

    # -------------------------------------------------
    # [1] 현재 온도/습도 읽기
    # -------------------------------------------------

    response = client.read_holding_registers(
        address=0x0000,
        count=2,
        slave=1
    )

    if not response.isError():

        raw_temp = response.registers[0]
        raw_humi = response.registers[1]

        # Signed 처리
        if raw_temp > 32767:
            raw_temp -= 65536

        temperature = raw_temp / 10.0
        humidity = raw_humi / 10.0

        print("현재 측정값")
        print(f"온도 : {temperature:.1f} ℃")
        print(f"습도 : {humidity:.1f} %")

    else:
        print("데이터 읽기 실패")

    # -------------------------------------------------
    # [2] 온도 보정값 설정
    # 예: -0.5℃
    # -------------------------------------------------

    print("\n온도 보정값 설정 중...")

    calibration_value = -5

    result = client.write_register(
        address=0x0103,
        value=calibration_value,
        slave=1
    )

    if not result.isError():
        print("온도 보정 완료 (-0.5℃)")
    else:
        print("온도 보정 실패")

    # -------------------------------------------------
    # [3] 슬레이브 ID 변경
    # -------------------------------------------------

    # 주의:
    # 실행 후에는 반드시
    # slave=2 로 접근해야 함

    # print("\n슬레이브 ID 변경 중...")
    #
    # result = client.write_register(
    #     address=0x0101,
    #     value=2,
    #     slave=1
    # )
    #
    # if not result.isError():
    #     print("ID 변경 완료 (1 -> 2)")
    # else:
    #     print("ID 변경 실패")

    client.close()

# -------------------------------------------------
# 프로그램 시작
# -------------------------------------------------

if __name__ == "__main__":

    run_test()

8. 왜 슬레이브 ID 변경이 중요한가?

RS485는 Multi-drop 구조를 지원합니다.

즉:

센서 여러 개를 하나의 통신선에 병렬 연결 가능

합니다.

예:

PC ───── Sensor1
   ├──── Sensor2
   ├──── Sensor3
   └──── Sensor4

하지만 모든 센서 ID가:

1

이라면 동시에 응답하게 되어 통신 충돌이 발생합니다.

따라서 반드시:

  • Sensor1 → ID 1

  • Sensor2 → ID 2

  • Sensor3 → ID 3

처럼 서로 다른 주소를 부여해야 합니다.


9. 실전 설치 시 주의사항

1) ID 변경은 반드시 한 대씩

처음에는 센서를 하나만 연결한 상태에서 ID를 변경해야 합니다.

여러 대를 동시에 연결한 상태에서 ID 변경 명령을 보내면 모든 센서가 같은 ID로 바뀔 수 있습니다.


2) RS485 종단저항(Termination)

케이블이 길어질 경우:

120Ω 종단저항

이 필요할 수 있습니다.

특히:

  • 수십 미터 이상

  • 공장 노이즈 환경

  • 고속 통신

에서는 매우 중요합니다.


3) A/B 반전 문제

제조사마다:

  • A(+)

  • B(-)

표기가 반대로 되어 있는 경우가 많습니다.

통신이 안 되면 가장 먼저 A/B를 서로 바꿔 테스트해보는 것이 좋습니다.


10. 실제 산업 현장에서의 활용

이러한 SHT30 Modbus 센서는:

  • 스마트팜

  • PLC 환경 모니터링

  • 서버실 온습도 감시

  • 반도체 장비 내부 환경 측정

  • 창고 환경 관리

  • 데이터 로깅 시스템

등에서 매우 많이 사용됩니다.

특히 RS485 기반이라:

  • 장거리 전송 가능

  • 노이즈에 강함

  • 다중 장치 연결 가능

이라는 큰 장점이 있습니다.


마무리

알리익스프레스에서 판매되는 SHT30 Modbus 센서는 단순한 저가형 센서를 넘어:

  • 산업용 RS485 통신

  • Modbus RTU 표준

  • 실시간 보정 기능

  • Multi-drop 네트워크 구성

까지 지원하는 매우 강력한 장치입니다.

특히:

  • 슬레이브 ID 구조

  • Register 기반 설정 방식

  • Calibration Offset 개념

을 이해하면 단순 데이터 수집을 넘어 실제 산업용 제어 시스템 수준까지 확장할 수 있습니다.

RS485와 Modbus RTU를 공부하는 입문자에게도 매우 좋은 학습용 장비가 될 수 있습니다.

댓글

이 블로그의 인기 게시물

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

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

NPN, PNP 트랜지스터 차이점

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

사각형의 넓이 공식의 증명

[아두이노] 가변저항(Potential Divider)과 전압분배(Voltage Divider)

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

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

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

[PLC] 릴레이와 전자 접촉기 (MC)