프로그래밍/C, C++, Java, Python

Modbus TCP 통신을 위한 프로토콜 파헤치기 & 예제 코드

포도알77 2021. 2. 2. 13:44

Modbus TCP 통신을 위한 프로토콜 파헤치기 & 예제코드

 

링크 : Modbus TCP/IP 프로토콜 가이드 문서

 

1. Modbus 프로토콜

 Modbus 프로토콜은 프로세스 자동화와 SCADA(Supervsory Control and Data Acquisition)에 사용되는 통신 프로토콜으로, 원하는 장치에 정보를 가져오거나 전달할 수 있다. 크게는 Modbus TCP/IP, Modbus RTU가 있고, 그외 Modbus ASCII나 PLUS같은 것이 존재한다. 

 

 Modbus는 open protocol이라, 제품에서 지원하게 된다면 서로 다른 제품이라도 하나의 프로토콜을 이용하여 데이터 통신을 수행할 수 있다. 또한 우리가 주로 사용하는 TCP/IP 프로토콜을 지원하기 때문에 네트워크 망을 이용하여 장비의 데이터 통신을 같이 사용할 수 있다는 장점도 있다.

 

 

2. Modbus RTU와 Modbus TCP/IP 데이터 유닛

 RS485, RS232, RS422등의 시리얼 통신을 통하여 데이터를 송수신하는 Modbus RTU 프로토콜은 아래와 같이 Slave ID, Function Code, Data, CRC로 구성되어있다. (Slave ID : 장치 ID)

 

 Modbus RTU에서는 위의 4개의 데이터를 하나의 데이터 유닛으로 생성하고, 이를 시리얼 통신을 통해 장치에 전달한다. 반면 Modbus TCP/IP는 MBAP, Function Code, Data를 하나의 데이터 유닛으로 생성하고 전달한다. (에러 체크는 application 단에서 수행하지 않음)

 

 

 MBAP은 Modbus Application Protocol Header로, Tranaction Identifier (해당 패킷의 ID, 2byte), Protocol Identifier  (프로토콜 ID, 2byte), 길이(1byte), Slave Unit ID(1byte)로 구성된다. 
 

 Modbus TCP/IP에서는 TID, PID를 모두 0으로 세팅하고, Slave Unit은 각 제조사별 설정 방법(Serial 뒤자리 또는 특정 값 고정)에 맞춰주면 된다.

 

 

 

 

 

3. Modbus TCP 연결

  앞서 언급된 바와 같이 Modbus TCP/IP에서 우리는 ADU라고 불리는 어플리케이션단 데이터 포맷을 맞춰주면 되고, 나머지 TCP/IP 헤더 등은 TCP 소켓을 생성하여 전달하면 아래의 레이어단에서 알아서 처리되게 된다.

 

 즉, 이름이 어렵게보일 뿐 Modbus TCP/IP는 장치와 소켓을 하나 열어서 통신하는 것과 다를바가 없다. 이를 위해서 해당 장치의 RJ45(랜)을 공유기나 기타 로컬 네트워크에 연결해주면 된다.

 

 

4. 파이썬 예제 코드

import socket

ip="192.168.1.200"
port="502"

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((ip, port))

adu = struct.pack('>HHHBBHH', 
	0, 0, # TID/ PID
	6, 3, # Length / Unit ID 
	3, 30001, 2) # Function Code / Data (Reg addr, Count)

sock.write(adu)

rsp = sock.recv(512)

 

페이스북으로 공유카카오톡으로 공유카카오스토리로 공유트위터로 공유URL 복사