모드버스(Modbus) 응용 개발을 위한 준비
모드버스(Modbus) 프로토콜은 PLC를 비롯한 다양한 장비들 간의 정보 소통을 위한 표준 통신 프로토콜로 요즘 나오는 대부분의 PLC들은 대부분 모드버스 프로토콜을 지원하고 있고 스카다나 BEMS, MES와 같은 대형 소프트웨어에서도 장비나 타 시스템과의 통신을 위해 모드버스 프로토콜을 지원하고 있다. 이렇게 모드버스 프로토콜이 표준으로 자리 잡을 수 있었던 배경에는 일치감치 상세한 프로토콜 스펙이 오픈되고 연관한 오픈소스 라이브러리가 공개되어 안정적으로 성능을 발휘한 까닭이 아닌가 싶다.
1979년 처음 프로토콜이 등장할 당시만 해도 시리얼 통신 프로토콜이었으나 지금은 TCP/IP로도 사용할 수 있다. 모드버스 프로토콜을 접하려면 우선 어떤 방식을 채용할지를 확인해야 한다. 소프트웨어 개발자의 시작에서 필요한 내용만 정리하면 다음과 같다.
- MODBUS TCP
PLC 또는 특정 장비와 TCP/IP 통신한다. 당연히 장비의 IP 주소와 포트번호(통상 502)를 알아야 한다. - MODBUS RTU
RS-485 시리얼 통신과 비슷하게 하나의 통신 라인에 최대 247개의 노드가 붙어서 통신할 수 있다.
시리얼 통신 파라미터(포트, 속도, 패리티 등등), 슬레이브 노드 아이디(1-247) - MODBUS ASCII
RTU와 마찬가지로 시리얼통신 방식이지만 패킷이 모두 문자열로 전달된다. 시리얼은 대부분 RTU를 사용.
모드버스를 사용하며 제일 많이 혼동하는 것이 서버/클라이언트, 마스터/슬레이브 용어인데 일반적인 서버는 모드버스 슬레이브 노드로 일반적인 클라이언트는 모드버스 마스터로 이해하면 된다. 클라이언트의 요청에 서버가 반응하여 다양한 서비스를 제공하듯이, 모드버스 마스터(Master)의 요구에 따라 모드버스 슬레이브(Slave)는 요청한 데이터를 제공하거나 전달한 데이터를 장치에 반영한다. MODBUS RTU의 경우에는 RS-485 통신처럼 하나의 시리얼 통신 라인을 통해서 여러 개의 PLC나 기타 장비와 연결할 수 있으므로 이때 중요한 것이 통신할 노드의 아이디로 1-247 사이의 값이다. 만약 노드 아이디를 잘 모르는 경우에도 기본값은 0이 아니라 1 임에 주의해야 한다. 0으로 하면 연결된 모든 슬레이브에게 전달하는 브로드케스트 메시지가 된다.
테이블 이름 | 주소 범위 | 유형 | 동작 방식 |
discrete_output_coils | 1-9999 | 디지털 | 입출력 |
discrete_input_contacts | 10001-19999 | 디지털 | 입력 |
analog_input_registers | 30001-39999 | 아날로그 | 입력 |
analog_output_holding_registers | 40001-49999 | 아날로그 | 입출력 |
모드버스 라이브러리를 활용하여 장치에 접속하는 과정까지 진행했다면 그다음에 하는 작업은 어떤 곳의 데이터를 읽겠다는 요청 하거나, 특정 데이터를 어떤 곳에 출력하라는 요청 해야 하는데, 입력 또는 출력할 장소를 가리키는 주소 영역을 모드버스에서는 위의 표와 같이 크게 네 가지 영역으로 분류하여 테이블(Table)이라 지칭한다. 결과적으로 어떤 테이블의 몇 번째 데이터인지를 알아야 한다. 위의 표에서 각각에 대하여 절대 주소가 있는데 디지털은 한 주소에 1비트, 아날로그는 한 주소에 2바이트를 가리킨다.
개별 데이터의 주소 지정 방식은 사용하는 모드버스 라이브러리에 따라서 다를 수 있으므로 사용 전에 미리 확인하는 과정이 필요하다. 정상적인 개발 과정을 거쳤음에도 불구하고 주소 확인 과정을 누락하면 불필요한 혼란을 만들 수 있다. 모드버스 프로토콜은 개별 읽기/쓰기도 있지만 연속적인 데이터에 대하여 블록 읽기/쓰기도 지원하므로 라이브러리의 기능을 확인하여 블록 읽기로 성능을 높일 필요가 있다. 도구에 따라서는 사용자의 요청을 분석하여 개별 읽기 또는 블록 읽기를 자동으로 선택하는 경우도 있는데 블록 읽기를 선택하는 기준은 요청한 주소의 연속성이므로 한 장비에서 읽을 데이터가 여러 개라면 주소를 연속적으로 배치시키는 것도 성능을 높이는 주요 방법이다.
데이터 읽고 쓰기까지 되었다면 그다음에는 자료를 처리하는 방식과 연관된 문제가 남아있다. 모드버스 테이블은 디지털과 아날로그로 나뉘어 있지만, 아날로그 자료를 비트 스트링으로 처리하는 경우도 있다. 이런 것은 모드버스 통신 이전 또는 이후의 문제이므로 라이브러리가 자료 변환을 지원하지 않는다면 데이터의 변환과 활용은 온전히 프로그래머의 몫이다. 아날로그 한 주소 영역의 데이터가 2바이트이지만 앞서 언급한 것처럼 16개의 비트 자료로 개별적으로 사용할 수도 있고, 부호화 16비트 정수, 부호 없는 16비트 정수로 취급할 수 있으며, 두 개의 주소 영역을 합쳐서 32비트 정수나 실수값을 저장할 수도 있고 4개의 주소 영역을 합쳐서 64비트 정수로 사용할 수도 있는 것이다. 그러므로, 장비와 접속이 성공했다면 자료를 읽어보아서 장비에서 인식하는 값과 통신으로 전달된 값이 동일한지를 확인하는 과정이 반드시 필요하다.
다소, 혼란스러운 지점은 빅 엔디안(big endian), 리틀 엔디안(little endian)이라 부르는 바이트 저장 순서(byte order)가 시스템 간에 차이가 나는 경우인데, 장치의 값과 통신으로 전달된 값이 일치하지 하지 않는다면 일단 양쪽 시스템의 엔디안이 일치하는지를 먼저 살펴본다. 엔디안 변환으로 해결되지 않는 경우도 있는데 엔디안이 혼합되어 바이트의 순서를 교체해야 하는 경우도 있다.
프로그램을 개발하기 위해서는 통상 테스트 장비를 두고 작업을 진행하는 것이 좋겠지만, 많은 경우에는 그런 상황이 허락되지 않는 경우가 많다. 그래서, 실제 장비가 아닌 모드버스 슬레이브 역할을 시뮬레이터를 활용하면 실제적인 테스트를 진행하면서 효율적인 개발을 수행할 수 있다. 모드버스 마스터 프로그램을 개발할 때 유용하다.
위의 그림은 MOD_RSSIM(https://modrssim.sourceforge.net/)으로 무료로 사용할 수 있는 모드버스 슬레이브 시뮬레이터이다. MODBUS TCP, MODBUS RTU를 모두 지원한다. 소스코드도 배포하고 있다. GPLv3 라이선스로 배포하고 있다. 편리함을 위해서 파일을 첨부해 놓는다. 이 시뮬레이터에 대해서 모드버스 마스터 프로그램을 개발하여 값을 읽거나 저장할 수 있다. 시뮬레이터에서 값을 변경한 것이 프로그램에서도 그대로 읽히는지 확인하고, 프로그램에서 쓰기 요청한 값이 시뮬레이터에 그대로 반영되었는지 확인할 수 있다.
반대로 모드버스 프로토콜을 지원하는 장비 자체를 개발하거나 모드버스 슬레이브 역할을 하는 서버를 개발하는 경우에는 자동으로 또는 대량으로 데이터 요구를 하는 모드버스 마스터가 필요한데 위의 그림은 RMMS라는 모드버스 마스터 시뮬레이터로 MODBUS TCP와 MODBUS RTU를 모두 지원한다. 특정 범위의 데이터를 대량으로 동시에 테스트할 수 있다. 트래픽의 정상 전송 여부와 데이터 내용을 확인할 수 있다. 무료로 사용할 수 있으며 아래에 프로그램을 첨부해 놓는다.