Modbus-RTU 드라이버 개념과 가상테스트 가이드

Modbus-RTU 드라이버 개념과 가상테스트 가이드

Modbus-RTU는 공장이나 설비 현장에서 오래전부터 쓰여 온 통신 방식이라 자료도 많고 실제로 접할 일도 잦습니다. 하지만 회선을 직접 연결해 눈으로 확인해 보려면 RS-485 컨버터나 실제 장비가 있어야 해서 막상 손에 잡히지 않는 경우가 많습니다.

이 포스팅에서는 Modbus 개념을 먼저 짧게 정리하고, 실제 장비 없이 PC 안에서만 com0com(가상 시리얼 포트)과 Modbus Poll/Modbus Slave(테스트용 프로그램) 두 가지로 통신을 직접 만들어 보는 방법을 다루겠습니다.

1. Modbus란?

Modbus는 1979년에 처음 만들어진 뒤 지금까지도 산업 현장에서 가장 널리 쓰이는 통신 프로토콜입니다. PLC, 센서, 계측기, 인버터 같은 장비들이 서로 다른 제조사여도 이 규격만 맞추면 통신이 가능해서, 아직도 신규 장비에 계속 채택되고 있습니다.

Modbus의 통신 구조는 항상 '마스터(Master)'와 '슬레이브(Slave)'로 나뉜다. 마스터가 먼저 요청을 보내야만 슬레이브가 응답하는 방식이라, 슬레이브가 스스로 데이터를 먼저 보내는 일은 없습니다. 하나의 마스터 아래에 여러 슬레이브가 붙을 수 있고, 각 슬레이브는 고유한 슬레이브 ID(1~247)로 구분됩니다.

이 마스터-슬레이브 대화가 물리적으로 어떤 회선을 타고 오가는지에 따라 Modbus는 크게 두 갈래로 나뉩니다.

구분

Modbus TCP

Modbus RTU

물리 계층

이더넷(랜선)

RS-232 / RS-485 시리얼

주소 구분

IP 주소 + 포트

슬레이브 ID(1~247)

프레임 구성

MBAP 헤더 + PDU

슬레이브 ID + PDU + CRC16

특징

네트워크 구성이 쉽고 빠름

배선이 저렴하고 길게 뻗을 수 있어(RS-485는 1.2 km, 최대 32대) 현장 계측기·구형 장비에 여전히 많음

RTU 프레임은 아래처럼 아주 단순한 구조입니다.

Slave ID (1바이트)

Function Code (1바이트)

Data (가변 길이)

CRC16 (2바이트)

요청을 받을 장비 번호

무엇을 할지 (읽기/쓰기 등)

레지스터 주소, 개수, 값 등

오류 검출용 체크섬

자주 쓰이는 Function Code 몇 가지만 알아도 대부분의 실습을 이해할 수 있습니다.

  • 03 (Read Holding Registers) — 레지스터 값을 읽는다. 실습에서 가장 많이 쓴다.

  • 06 (Write Single Register) — 레지스터 하나에 값을 쓴다.

  • 01 (Read Coils) — On/Off 값(비트)을 읽는다.

  • 16 (Write Multiple Registers) — 여러 레지스터에 한 번에 값을 쓴다.

RTU 통신이 되려면 마스터와 슬레이브가 다음 네 가지 통신 파라미터를 정확히 똑같이 맞춰야 합니다: Baud Rate(전송 속도, 예: 9600), Parity(패리티, 보통 None), Data Bits(보통 8), Stop Bits(보통 1). 이 중 하나라도 다르면 아예 응답이 없거나 깨진 값이 옵니다.

정리: RTU는 '누가(슬레이브 ID) 무엇을(함수코드) 어디서(주소) 몇 개나(개수) 주고받는지'를 아주 짧은 바이트 나열로 표현하고, 끝에 CRC로 오류를 검증하는 단순한 프로토콜이다.

2. 가상 시리얼 포트로 테스트하는 이유

RTU를 눈으로 확인해 보려면 원래는 RS-485 컨버터, 케이블, 그리고 응답해 줄 실제 슬레이브 장비가 필요합니다. 하지만 '통신 자체가 정상적으로 오가는지'만 먼저 확인하고 싶다면 이런 하드웨어 없이도 PC 안에서 재현할 수 있습니다. com0com은 윈도우에서 무료로 쓸 수 있는 오픈소스 가상 널모뎀 드라이버로, 설치하면 서로 내부적으로 연결된 COM 포트 쌍을 만들어 줍니다. 한쪽 포트에 쓴 바이트가 그대로 반대쪽 포트의 수신 버퍼에 도착하기 때문에, 실제 케이블로 두 장치를 연결한 것과 똑같은 상황이 만들어집니다.

이 가상 포트 쌍의 양쪽 끝에 프로그램을 하나씩 붙이면 마스터와 슬레이브 역할을 각각 맡길 수 있습니다.

  • Modbus Slave — 가짜 필드 장비 역할. 특정 주소에 값을 채워 두고 요청이 오면 응답한다.

  • Modbus Poll — 마스터 역할. 슬레이브에게 주기적으로 값을 읽어오거나 쓴다.

두 프로그램 모두 Witte Software(modbustools.com)에서 배포하는 짝지어진 윈도우 유틸리티로, 무료 평가판으로도 기본적인 테스트에는 충분합니다.

3. com0com 설정

  1. com0com을 다운로드해 관리자 권한으로 설치합니다.

  2. 설치 시 기본적으로 CNCA0 ↔ CNCB0 라는 이름의 포트 쌍이 하나 생깁니다. 설정 화면에서 이름을 원하는 COM 번호로 바꿀 수 있다 — 이 글에서는 COM7(슬레이브 쪽)과 COM8(마스터 쪽)로 바꿨다고 가정합니다.

  3. 포트 옵션 중 '보레이트 에뮬레이션'을 켜 두는 것을 권장합니다. 꺼져 있으면 실제 시리얼 회선과 달리 데이터가 전송 속도와 무관하게 즉시 전달되는데, 일부 프로그램은 프레임이 끝났는지를 '문자 사이 공백 시간'으로 판단하기 때문에 타이밍이 실제 장비와 비슷하게 흘러가는 편이 테스트에 더 안전합니다.

  4. 설정을 저장한 뒤, 윈도우 장치 관리자의 '포트(COM & LPT)' 목록에 COM7, COM8이 나타나는지 확인합니다.

image1.png

com0com 설정 화면 예시 — COM7 ↔ COM8 포트 쌍 및 옵션 (실제 화면은 버전에 따라 다를 수 있음)

image2.png

장치 관리자 화면 예시 — COM7, COM8 포트 확인

4. Modbus Slave로 가짜 장비 만들기

Modbus Slave를 실행해 COM7에 연결하고, 통신 파라미터를 정해 둔 값으로 맞춥니다.

  • Port: COM7

  • Baud Rate / Parity / Data Bits / Stop Bits: 9600 / None / 8 / 1

  • Slave ID: 1

연결되면 레지스터 값을 편집할 수 있는 표가 함께 나타납니다. Setup 메뉴에서 Function을 03 Holding Registers로, 시작 주소를 40001로, 개수를 몇 개 잡아 둔 뒤, 표의 값을 더블클릭해 임의의 테스트 값(예: 40001번지에 1234)을 입력해 둡니다.

image3.png

Modbus Slave 화면 예시 — 좌: Connection 설정(COM7, 9600-N-8-1, Slave ID 1) / 우: 레지스터 값(40001=1234)

5. Modbus Poll로 값 읽어보기

이번엔 Modbus Poll을 실행해 반대쪽 포트인 COM8에 연결합니다. 통신 파라미터는 Modbus Slave와 완전히 동일하게 맞춥니다.

  • Port: COM8

  • Baud Rate / Parity / Data Bits / Stop Bits: 9600 / None / 8 / 1 (Slave와 동일)

  • Slave ID: 1 (Slave와 동일)

Setup 메뉴에서 Read/Write Definition을 열어 Function을 03 Holding Registers로, 시작 주소를 40001, 개수를 Modbus Slave와 맞춰 설정하면, Modbus Poll이 주기적으로 COM8 → (com0com) → COM7 → Modbus Slave 순서로 요청을 보내고 응답을 받아 화면에 표시합니다. 앞서 Slave 쪽에 입력해 둔 값(1234)이 그대로 나타나면 통신이 정상적으로 이루어진 것입니다.

image4.png

Modbus Poll 화면 예시 — 좌: Connection/Read 설정(COM8) / 우: 응답 결과(40001=1234, Slave와 일치)

Modbus Slave 쪽 화면에서 값을 다시 바꿔 보면, Modbus Poll 쪽 화면도 다음 폴링 주기에 갱신되는 것을 볼 수 있습니다. 이 둘이 서로 어긋남 없이 값을 주고받는 걸 확인했다면, RTU 프레임 송수신부터 통신 파라미터 매칭까지 실제 장비 없이도 검증이 끝난 셈입니다.

6. 문제가 있을 때 확인할 것들

  • 응답이 계속 없을 때(타임아웃): Modbus Poll과 Modbus Slave의 Baud Rate·Parity·Data Bits·Stop Bits가 정확히 같은지, Slave ID가 일치하는지 확인합니다.

  • 포트가 열리지 않을 때: 다른 프로그램이 같은 COM 포트를 이미 점유하고 있지 않은지 확인합니다. (포트 하나는 한 프로그램만 열 수 있음)

  • 값이 이상하게 나올 때(CRC 오류 등): com0com의 보레이트 에뮬레이션 옵션과, 양쪽의 시작 주소·개수 설정이 같은 레지스터를 가리키는지 확인합니다.

7. 결론

정리하면, RTU는 결국 '슬레이브 ID + 함수 코드 + 데이터 + CRC'라는 짧은 바이트 나열을 정해진 통신 파라미터로 주고받는 것이 전부입니다. 그리고 그 흐름은 실제 배선이 없어도 com0com으로 가상 COM 포트 쌍을 만들고, 그 양 끝에 Modbus Slave(가짜 장비)와 Modbus Poll(마스터)을 하나씩 붙이는 것만으로 RS-485 배선이나 실제 필드 장비 없이도 Modbus-RTU 통신 전체 흐름 — 요청 프레임 생성, 시리얼 전송, 응답, CRC 검증, 값 표시 — 을 눈으로 확인할 수 있습니다. 요청 프레임이 만들어지고, 시리얼로 전송되고, 응답이 오고, 값이 화면에 찍히는 전 과정을 눈으로 직접 봤다면 RTU 통신의 핵심은 이미 다 확인한 셈입니다.

지금까지 Modbus 드라이버를 활용하여 가상 포트를 통해 테스트하는 과정을 실습하셨습니다. 이제 실제 RS-485 장비가 준비되면 남는 일은 많지 않습니다. com0com 대신 진짜 RS-485 컨버터를 물린 COM 포트로, Modbus Poll 대신 실제 사용할 마스터 장비나 소프트웨어로 바꾸고, Baud Rate·Parity·Slave ID 같은 통신 파라미터를 그 장비의 스펙에 맞게 다시 맞추기만 하면 됩니다.

참고자료

Luna

Site footer