FirmGod

모드버스 레지스터 디코더

모드버스 레지스터 쌍을 float32, int32, uint32로 해석합니다. ABCD, DCBA, BADC, CDAB 네 가지 바이트 순서를 모두 보여 줍니다.

레지스터 두 개면 32비트, 네 개면 float64로 해석합니다. 공백이나 쉼표로 구분하세요.

레지스터Hexuint16int162진수
00x42F617142171420100001011110110
10xE97959769-57671110100101111001

32-bit value in every byte order

One order produces a value in a normal engineering range. That is almost certainly the one your device uses.

순서float32int32uint32
ABCDlikely123.45600111234778811123477881
DCBA1.518500e+3520453760662045376066
BADC-9.861115e+32-1634155754131551721
CDAB-1.883367e+25-3779289703917038326
ABCD
— big endian, high word first (Modbus standard)
DCBA
— little endian, full byte reversal
BADC
— big endian with bytes swapped inside each word
CDAB
— word swap, bytes kept in order (very common on gateways)

모드버스 레지스터 두 개를 Float32로 변환하는 예

장비 화면에 약 123.456이 표시되는데, 읽어 온 레지스터가 42F6 E979라고 가정해 봅시다. 위 계산기에서 16진수를 선택하고 두 값을 읽은 순서대로 입력하면 다음처럼 비교할 수 있습니다.

  • ABCD — 42 F6 E9 79, 약 123.456
  • CDAB — E9 79 42 F6, 약 −1.88 × 1025
  • BADC — F6 42 79 E9, 약 −9.86 × 1032
  • DCBA — 79 E9 F6 42, 약 1.52 × 1035

이 예에서는 ABCD가 화면 값과 일치합니다. 실제 장비에서는 표시값이 바뀌었을 때 한 번 더 비교하세요. 네 결과가 모두 다르면 장비 문서에서 데이터 형식, 레지스터 주소, 배율을 확인하세요. 원시 RTU 응답만 있다면 모드버스 RTU 프레임 파서에서 데이터 바이트를 먼저 확인할 수 있습니다.

모드버스는 16비트까지만 정의합니다

모드버스의 레지스터는 16비트입니다. 온도나 유량처럼 소수점이 필요한 값은 그 안에 들어가지 않아서 레지스터 두 개를 묶어 32비트 float를 담는 것이 관행이 됐습니다.

문제는 표준이 그 방법을 정하지 않았다는 것입니다. 두 레지스터 중 어느 쪽이 상위인지, 레지스터 안의 두 바이트 중 어느 쪽이 먼저인지 모두 제조사 선택입니다.

네 가지 조합

원래 값의 네 바이트를 A, B, C, D라고 하면 전송 순서는 네 가지가 나옵니다.

  • ABCD — 빅 엔디언. 상위 워드 먼저, 워드 안에서도 상위 바이트 먼저.
  • DCBA — 리틀 엔디언. 완전히 뒤집힌 형태.
  • CDAB — 워드 순서만 뒤집음. 워드 안은 그대로.
  • BADC — 워드 안 바이트만 뒤집음.

CDAB가 특히 흔합니다. 장비 내부가 리틀 엔디언 프로세서인데 모드버스는 워드 단위로 빅 엔디언을 쓰도록 되어 있어 생기는 조합입니다.

순서가 틀리면 어떻게 보이나

틀린 순서로 읽으면 값이 조금 어긋나는 것이 아니라 완전히 다른 수가 나옵니다. 23.5를 잘못 읽으면 1.2e+28 같은 값이 되거나 NaN이 나옵니다.

이것이 오히려 다행입니다. 결과가 명백히 이상하므로 바이트 순서를 의심하게 되기 때문입니다. 어중간하게 비슷한 값이 나왔다면 훨씬 오래 헤맸을 것입니다.

문서에 없을 때 찾는 방법

제조사 문서가 순서를 명시하지 않은 경우가 많습니다. 그럴 때는 값을 알고 있는 레지스터로 맞춰 봅니다.

  • 상온의 온도 센서처럼 대략의 범위를 아는 값을 고릅니다.
  • 네 해석 중 물리적으로 말이 되는 하나를 찾습니다.
  • 다른 레지스터로 한 번 더 확인합니다.

0에 가까운 값은 피하세요. 여러 해석이 모두 0에 가깝게 나와 구분되지 않습니다. 크기가 뚜렷한 값이 판별에 유리합니다.

정수도 같은 문제를 겪습니다

32비트 정수도 두 레지스터에 나뉘므로 같은 네 가지 조합이 적용됩니다. 다만 정수는 틀린 순서로 읽어도 그럴듯한 값이 나올 수 있어 float보다 알아채기 어렵습니다.

적산 계량기처럼 값이 단조 증가하는 레지스터라면 두 번 읽어 증가하는지 확인하는 방법이 있습니다. 순서가 틀리면 증가가 불규칙하게 보입니다.

읽기 전에 확인할 것

32비트 값은 반드시 레지스터 두 개를 한 번의 요청으로 읽어야 합니다. 따로 읽으면 그 사이에 값이 바뀌어 상위 워드와 하위 워드가 다른 시점의 것이 섞일 수 있습니다.

프레임 구조 자체를 확인하려면 모드버스 프레임 파서를, 바이트 순서를 일반적으로 다루려면 진법 변환기를 쓰세요.

자주 묻는 질문

읽은 값이 터무니없이 큽니다.

바이트 순서가 틀렸을 가능성이 큽니다. 같은 4바이트라도 순서를 잘못 잡으면 23.5가 1.2e+28 같은 값으로 읽힙니다. 이 도구가 네 가지 순서를 한 번에 보여 주는 이유가 그것입니다. 네 값 중 물리적으로 말이 되는 하나가 장비가 쓰는 순서입니다.

왜 네 가지나 되나요?

모드버스는 16비트 레지스터 단위로만 정의되어 있고, 32비트 값을 두 레지스터에 어떻게 나눠 담을지는 표준이 정하지 않았습니다. 그래서 레지스터끼리의 순서와 레지스터 안 바이트 순서를 각각 뒤집을 수 있어 조합이 네 가지가 됩니다. 장비 제조사마다 선택이 다릅니다.

ABCD, CDAB 같은 표기가 무슨 뜻인가요?

원래 4바이트를 A, B, C, D로 놓고 전송 순서를 적은 것입니다. ABCD는 빅 엔디언, DCBA는 리틀 엔디언, CDAB는 워드만 뒤집은 것, BADC는 바이트만 뒤집은 것입니다. 제조사 문서에는 word swap, byte swap 같은 말로 적혀 있기도 합니다.

어느 순서인지 문서에 없습니다.

알고 있는 값을 읽어서 맞춰 보는 것이 가장 빠릅니다. 온도처럼 대략의 범위를 아는 값을 읽고 네 해석 중 합리적인 것을 고르면 됩니다. 0에 가까운 값은 여러 해석이 모두 그럴듯하게 나올 수 있으니 크기가 뚜렷한 값으로 확인하세요.

64비트 값도 되나요?

이 도구는 레지스터 두 개, 즉 32비트까지 다룹니다. 64비트는 레지스터 네 개를 쓰고 순서 조합이 훨씬 많아집니다. 그런 장비라면 문서에서 순서를 확인하는 편이 시행착오보다 빠릅니다.