피드로 돌아가기
Why Your Schneider PLC's Float32 Reads 1.4e-41 Instead of 25.5 C
Dev.toDev.to
Infrastructure

Modbus Float32 Byte-swap 트랩 해결을 통한 데이터 디코딩 정밀도 확보

Why Your Schneider PLC's Float32 Reads 1.4e-41 Instead of 25.5 C

Phil Yeh2026년 5월 5일6intermediate

Context

1979년 제정된 Modbus 표준의 16-bit unsigned integer 제약으로 인해 Float32와 같은 대용량 데이터 전송 시 다중 레지스터 분할 방식 채택. 제조사별로 Word 및 Byte 순서에 대한 표준 정의가 없어 데이터 디코딩 시 값 왜곡이 발생하는 구조적 한계 존재.

Technical Solution

  • IEEE-754 표준 32-bit float의 바이트 시퀀스를 기반으로 4가지 가능한 Byte Order 패턴 분석
  • Schneider M221/M241 등에서 빈번한 CDAB(Word-swap) 패턴의 데이터 재배열 로직 설계
  • Python struct 모듈을 활용해 16-bit 레지스터 쌍을 4바이트 raw 데이터로 팩킹 후 순서별 언팩 수행
  • ABCD(Big-endian), CDAB(Word-swap), BADC(Byte-swap), DCBA(Reverse)의 4가지 디코딩 경로 구현
  • 신규 디바이스 통합 시 4가지 패턴을 동시 출력하여 실제 값과 대조하는 런타임 검증 프로세스 도입

1. 신규 PLC 통합 시 'Print all 4 orders' 테스트를 통한 Byte Order 확정

2. 비정상적인 지수 표기법(예:

1.4e-41) 또는 거대 음수 발생 시 Endianness 설정 우선 검토

3. pymodbus 등 라이브러리의 추상화된 API보다 struct 모듈을 통한 명시적 Byte 조작 권장

4. Float32 외에 Int32, Double 등 Multi-register 타입에 동일한 스왑 로직 적용 여부 확인

원문 읽기