컴퓨터/프로그래밍

모드버스 통신 오류 시 응답 방법

2022. 10. 14. 08:45

모드버스 통신 패킷 오류 시 응답? 무시?

한 개의 통신 라인에 여러 개의 디바이스가 물린 rs485에서 통신 패킷이 깨진 데이터를 수신했을 경우 다시 보내 달라고 요청해야 할까요? 아니면 무시하고 기다려야 할까요? 답부터 말씀드리면 요청하거나 응답해서는 안 됩니다. 어? rs485 통신의 대표 프로토콜인 모드버스에는 예외 상황 코드로 응답하는 내용이 있는데?라고 반문하실 수 있습니다. 그러나 모드버스의 예외 상황 코드에는 통신 패킷 오류에 대한 내용이 없습니다.

즉, 수신된 데이터가 올바른지 CRC 값을 확인했더니 틀렸다면 그 통신 패킷은 무시해야 합니다. 1:1 통신인 rs232에서는 다시 보내 달라고 요청할 수 있어도 1:N에서는 걸러내야 합니다. 이유는 통신 패킷에 오류가 있다면 슬레이브 주소가 변질될 수 있기 때문입니다. 나에게 보낸 패킷이 아닐 수 있으며 다른 슬레이브의 정상적인 응답을 방행할 수 있습니다.

CRC 오류 패킷에 대한 응답

예를 들어서 마스터가 3번 슬레이브에게 요청했고, 3번 슬레이브는 요청을 수행하고 응답합니다. 그런데, 3번 슬레이브가 아닌 4번 슬레이브가 수신한 통신 패킷에 오류가 생겼고, 하필 슬레이브 주소가 3이 아닌 4로 바뀌었습니다. CRC를 확인해 보니 당연히 값이 틀립니다. 4번 슬레이브는 자기에게 보낸 패킷이라고 생각하고 CRC 오류이니 마스터에게 다시 보내 달라고 요청한다면 3번의 응답을 방해할 것입니다. 그러므로 CRC 값이 틀린 통신 패킷에 대해서는 응답해서는 안 됩니다.

 

모드버스 예외상황 응답

모드버스 예외 코드

모드버스 얘기가 나왔으니 예외상황을 대해 잠시 알아보겠습니다. 우선 모드버스에서 사용하는 예외 상황 코드입니다. 모드버스 예외 코드에는 9번이 없는 10개의 예외 코드가 있습니다.

모드버스 예외상항 응답 예제

  • 마스터>> 01 04 00 0A 00 01 11 C8
    01: 슬레이브 번호
    04: Function Code
    00 0A : 요청 주소 0x000A
    00 01 : 요청 데이터 개수 0x0001
    11 C8 : CRC 0xC811

마스터가 1번 슬레이브에 4번 Function Code를 이용하여 10번 주소에서 1개의 레지스터 값을 요청했습니다. 그러나 1번 슬레이브는 10번에 해당하는 레지스터가 없습니다. 그러므로 마스터에게 요청한 레지스터 주소가 틀렸다는 것을 알려 주고 싶다면 아래와 같이 응답합니다.

  • 슬레이브>> 01 84 02 C1 C2
    01 : 슬레이브 번호
    84 : 요청한 Function Code의 MSB를 1로 세팅 0x04 + 0x80
    02 : Illegal Data Address
    C1 C2 : CRC 0xC2C1
 

예외 상황 코드 패킷에도 CRC 오류가 있다면?

여기서 다시 생각해 봅니다. 마스터가 슬레이브로부터 응답 데이터를 수신했는데 CRC가 틀립니다. 예를 들어서 [01 84 02 C1 C2]이 와야 하는데 [01 84 02 C1 A8]로 받았습니다. CRC 오류입니다. 그러나 앞부분을 보니 주소를 잘못 지정했다는 것을 알겠습니다. 그렇다면 이 응답을 인정해야 할까요? 역시 무시합니다. 오류 패킷으로 주소가 잘못되었다는 것을 알게 되었다고 하더라도 CRC가 틀린 오류 패킷이라면 보내온 02가 슬레이브가 알려주려는 예외 상황 코드인지 장담할 수 없기 때문입니다.

친절한 예외 상항 코드 응답

사족일 수 있습니다만, 예외 상황 코드를 충실히 응답해 주는 장비를 보면 감사할 정도입니다. rs485 통신을 경험해 보신 분은 아시겠지만, 외부 요인에 매우 취약합니다. 그래서 통신 라인을 깔고 장비를 연결하면 제일 먼저 통신 응답을 확인합니다. 모드버스를 지원하는 장비라면 3번 또는 4번 기능 코드로 읽기를 시도해 보는데요, 개발한 프로그램보다는 ModbusPoll처럼 외부 프로그램으로 확인합니다.

개발한 프로그램은 개발자가 직접 확인하거나 현장 작업자에게 교육을 해야 합니다. 그러나 무엇보다도 개발 프로그램에는 버그가 있을 수 있습니다. 아무리 확실하게 만들었다고 해도 현장에서, 업체에서 믿지 않을 수 있습니다. 특히, 제품을 납품한 업체에서는 개발자 잘못으로만 몰아갈 수 있습니다. ModbusPoll은 사용하기 쉬우면서 인지도가 높아서 많은 분이 애용합니다.

현장에서는 ModbusPoll 또는 애용하는 테스트 프로그램을 습관적으로 실행하고 기본으로 설정된 값으로 테스트하는 경우가 많습니다. 응답이 있으면 일단 통신 라인 O.K.라고 판단합니다.

ModbusPoll로 레지스터 값을 읽게 했습니다. 그런데 응답이 없습니다. 그래서 통신 라인에 문제가 있나, 어디 연결이 끊어졌나 다시 확인하고 또 확인하고, 장비 설정을 잘못했나 판매 회사에 물어보고 설정을 바꾸어 보면서 한참 헤매는데요, 아무리 해봐도 응답이 없어서 답답한 마음에 결국 어렵게 겨우겨우 업체를 통해 개발자와 통화까지 하게 됩니다.

문제는 통신 라인 때문이 아니었습니다. 개발자의 말이 레지스터 딱 한 개만 읽도록 하면 될 거랍니다. 즉, 데이터 길이를 1로 하면 된다는 것이죠. 이런~ ModbusPoll은 기본 요청 데이터 길이가 10이거든요.

만일 그 개발자가 왜 쓸데없이 10개를 읽느냐? 출력할 데이터가 고작 한 개뿐인 장비인데 하고 반론하기보다는 예외 코드 Illegal Data Address를 응답하도록 코딩해 주었다면 그 춥고 어두운 시간에 많은 분이 고생하지 않았을 것입니다.

데이터 주소와 개수뿐만 아니라 지원하지 않는 Function Code도 응답하지 않는 경우가 있습니다. 모드버스를 지원하는 장비라고 하더라도 모드버스의 모든 Function code를 지원하지 않습니다. 지원하지 않는 Function Code를 수신했을 때 01 번 Illegal Function 예외 코드로 응답해 주면 참 좋을텐데 아무런 응답이 없는 장비가 있습니다. 모드버스 장비라고 대단한 것이 아닙니다. 어차피 그 장비도 어느 누군가 사람이 만들었으니까요.

예외 상황 코드 응답도 중요하다는 것을 말씀드리기 위해 주저리 적었습니다. 혹시, 통신 라인은 이상이 없는 것 같은데 응답이 없다면 해당 장비가 지원하는 Function Code와 주소 영역을 확인해 보세요.

rs485 통신 오류 패킷 수신 시 처리 방법

모드버스뿐만 아니라 rs485 통신을 이용하는 프로토콜에서는 CRC 오류 시 응답해서는 안 됩니다. 그렇다면 전송에 실패했는데 어떻게 해야 할까요? 마스터가 부지런해야 합니다. 똑똑하게 처리해야 합니다. 마스터가 얼마나 부지런하고 똑똑한지에 따라 rs485 통신 시스템의 효율은 천지 차이가 됩니다.

요청을 했는데 응답이 없다면 다시 요청합니다. 또 못 받았다면 다시 요청해야 하는데, 슬레이브의 개수에 따라 재 요청 횟수와 반복 주기에 주의해야 합니다. 실패하면 될 때까지 통신하는 것이 확실하겠습니다만, 슬레이브가 두 대라고 해도 한 대만 고장이 나도 매우 느린 시스템이 될 것입니다. 반복하지 않고 다른 슬레이브로 바꾼다면, 응답을 같은 기회로 확인한다면 한 바퀴 돌 때까지 기다려야 합니다.

이 문제에 대한 자세한 내용을 rs485 시리얼 통신 구성 방법 및 주의 사항에 올렸습니다. 모드버스의 예외 상항 응답에 대해서만 다룬다는 것이 얘기가 커져 버렸네요. rs485 통신은 오래전에도, 지금도 많이 사용하는 통신이지만, 설치에서 시스템을 운영하는 소프트웨어 구현 방법까지 어렵고 생각할 것이 참 많은 통신 방식입니다.