Embedded/RaspberryPI

Raspberry Pi CM4에 ModbusTCP Server 설치해 보기 - 1편(ModbusTCP 기본지식)

변화의 물결1 2024. 11. 19. 10:33

 

 

안녕하세요.

 

 ModbusTCP Server 샘플을 만들어 보기 전에 간단하게 ModbusTCP 이해가 필요할 것 같아서 자료를 찾아보았습니다. 다음 시간에 실제적으로 설치하고 프로그래밍하는 내용을 남겨보려고 합니다.

 


 

1. Modbus 프로토콜 개요

 

 Modbus는 산업용 통신 프로토콜로, 공정 자동화에서 주로 사용되며 특히 장비 간의 간단하고 신뢰성 있는 데이터 교환을 위해 설계되었습니다. Modbus는 Master-Slave 방식으로 동작하며, 주로 센서, PLC(Programmable Logic Controller), SCADA(Supervisory Control and Data Acquisition) 시스템과 같은 장치들이 Modbus를 통해 서로 데이터를 주고받습니다.

 

 

 

<주요 특징>

 

 통신 구조: Modbus는 Master(주)와 Slave(종)의 통신 구조를 사용합니다. Master가 명령을 주도하며, Slave는 요청에 응답하는 방식으로 동작합니다. 주로 마스터(Client)에는 산업용 터치 HMI 기기, 또는 PC와 같은 상위 기기가 되고 슬레이브(Server)에는 센서 임베디드나 PLC 등 값을 저장 및 반영하고 응답해 주는 장치가 됩니다.

 

 

 

 데이터 전송 단위: 16비트 워드 단위로 데이터를 주고받으며, 디지털 또는 아날로그 데이터의 상태를 표현할 수 있습니다.

 

 기본 데이터 타입: Modbus에서는 주로 코일(Coils), 디지털 입력(Discrete Input), 홀딩 레지스터(Holding Registers), 입력 레지스터(Input Registers) 등 네 가지 데이터 타입을 사용합니다.

  

 

2. Modbus 데이터 타입과 그 역할

 

Modbus 프로토콜에서의 주요 데이터 타입은 아래와 같습니다.

 

 

 

1) Coil (코일)

 

코일은 디지털 출력 상태를 나타내는 1비트 크기의 데이터입니다. 보통 ON(1) 또는 OFF(0) 상태로 설정하여 장치의 스위치 상태를 제어하는 데 사용됩니다.  이 영역을 통해 장치의 외부 디지털 출력 장치를 제어하거나 모니터링할 수 있습니다. 예시) 릴레이 스위치의 On/Off 상태, 펌프 제어 신호

 

 

2) Discrete Input (입력 디지털)

 

디지털 입력 상태를 나타내는 1비트 크기의 데이터입니다. 보통 센서나 스위치와 같은 장치의 상태를 읽어오는 데 사용되며, 이 영역은 읽기 전용입니다. 예시) 센서의 상태(활성화/비활성화), 버튼 입력 신호

 

 

3) Holding Register (홀딩 레지스터)

 

레지스터는 16비트(2바이트) 크기의 데이터를 저장하며, 주로 아날로그 값을 표현하거나 명령어, 상태 등의 데이터를 전송하는 데 사용되며 읽기/쓰기 가능한 메모리입니다. 주로 아날로그 출력 명령이나 상태 데이터를 저장하는 데 사용됩니다. 예시) 온도 설정 값, 모터의 속도 값

 

 

4) Input Register (입력 레지스터)

 

레지스터는 16비트(2바이트) 크기의 데이터를 저장하며, 주로 아날로그 값을 표현하거나 명령어, 상태 등의 데이터를 전송하는 데 사용되며 읽기 전용 메모리입니다. 장치의 아날로그 입력 데이터를 읽어오는 데 사용됩니다. 예시) 온도 센서의 측정값, 압력 센서 값

 

 

3. Modbus 프로토콜 종류 및 구조

 

Modbus 프로토콜에는 주요 통신 방식으로 Modbus RTU, Modbus ASCII, 그리고 ModbusTCP가 있습니다. 이 중 ModbusTCP는 TCP/IP 기반 네트워크 환경에서 Modbus 프로토콜을 사용할 수 있도록 개발된 확장 프로토콜입니다.

 

1) Modbus RTU : RS-232, RS-485 등 직렬 통신 기반에서 사용하는 Modbus 프로토콜. 바이너리 데이터 프레임 구조를 가집니다.

 

2) Modbus ASCII : ASCII로 인코딩 된 Modbus 프로토콜로, 읽기 쉽지만 RTU 방식보다 느립니다.

 

<일반적인 MODBUS 프레임 구조>

 

PDU(Protocol Data Unit ) : 하위계층과 관계없이 독립적 데이터 구조

ADU(Application Data Unit) : 하위 계층에 따라 최종 결정되는 데이터 구조

 

3) ModbusTCP : TCP/IP 네트워크 기반에서 사용하는 Modbus로, 이더넷을 통해 데이터를 전송합니다.

 

 

4. ModbusTCP의 구조와 특징

 

ModbusTCP는 기본적인 Modbus 패킷에 MBAP (Modbus Application Protocol) Header를 추가하여 TCP/IP 네트워크 상에서 Modbus 패킷을 전송할 수 있도록 설계되었습니다. MBAP Header는 통신을 식별하는 역할을 하며, 각 요청을 명확하게 구분합니다.

 

1) ModbusTCP 패킷 구조

 

ModbusTCP 패킷 구조는 다음과 같이 구성됩니다:

 

 

 

 (1) MBAP 헤더

 

 MBAP는 Modbus Application Protocol의 약자로 헤더는 다음과 같이 4가지 항목으로 이루어져 있습니다

 

 - Transaction ID [2Bytes] : 마스터(Client)가 최초 0x0000 값부터 통신시작 시 1씩 증가시키며 슬래이브(Server)는 그 값을 그대로 복사해서 사용합니다. 쿼리 및 응답에 대해 한쌍으로 작업이 이루어졌는지를 확인합니다.

 

 - Protocol ID [2Bytes] : 프로토콜의 ID를 나타내며 MODBUS-TCP는 0x0000의 고정값을 사용합니다.

 

 - Length [2Bytes] : Length 필드위치에서 프레임 마지막까지의 길이를 나타냅니다. 즉 Unit ID ~ Data끝까지의 Byte의 수를 나타냅니다.

 

 - Unit ID [1 Byte] : TPC/IP가 아닌 다른 통신선로(예, 시리얼)의 연결되어 있는 Slave를 구분하는 정보입니다.

 

 (2) 함수 코드 (Function Codes)

 

 Function Code를 이용하여 슬레이브 Memory(Coil, Register)에 값을 읽어오거나 쓸 수 있도록 기능을 지정합니다. 업체와 제품의 펌웨어마다 조금씩 다를 수 있습니다.

 

 

  0x01     Read Coils (코일 읽기)

  0x02     Read Discrete Inputs (입력 디지털 읽기)

  0x03     Read Holding Registers (홀딩 레지스터 읽기)

  0x04     Read Input Registers (입력 레지스터 읽기)

  0x05     Write Single Coil (단일 코일 쓰기)

  0x06     Write Single Register (단일 레지스터 쓰기)

  0x0F     Write Multiple Coils (다중 코일 쓰기)

  0x10     Write Multiple Registers (다중 레지스터 쓰기)

 

 함수는 Modbus 프로토콜에서 실제 제공되는 서비스를 정의합니다. 함수는 Modbus 프레 임에서 1 바이트의 공간을 차지하고 있으므로 사용 가능한 영역은 1 ~ 255입니다.

 

 이중 실 제로는 1 ~ 127 사이의 값을 사용하며 128 ~ 255의 값은 에러가 발생할 때 사용되는 예외 응답을 위해 사용됩니다. 함수 코드 0은 사용할 수 없습니다. 일부 함수는 여러 동작 지원을 위해 서브 함수 코드가 추가로 사용될 수 있습니다.

 

 함수 종류는 그 목적에 따라 크게 3가지로 분류됩니다.

 

-  Public Function Codes

표준 문서에 정의되어 있는 함수입니다.

1 ~ 64, 73 ~ 99, 111 ~ 127

 

- User-Defined Function Codes

표준 문서에는 정의되어 있지 않고 장비 제조사에서 직접 구현한 기능과 관련된 함수

입니다.

65 ~ 72, 100 ~ 110

 

- Reserved Function Codes

Public 영역 중 일부 제조사의 구형 장비에 사용되는 함수로 공식적으로 사용이 불가

능한 함수입니다.

8/19, 8/21~65535, 9, 10, 13, 14, 41, 42, 90, 91, 125, 126, 127

 

 

 (3) 데이터(Data)

 

Data는 Function Code에 따라 그 구조가 조금씩 달라집니다. Data는 기본적으로 Start Address, Length, Byte Count, Data의 형태를 가지고 있습니다.

 

 - Start Address [2Bytes] : 접근하려는 메모리의 시작번지를 나타냅니다. 2Byte로 표현되면 상위 Byte 우선순입니다. (예 0x4001번지 접근 시 0x40 0x01)

 

 - Length [2Bytes] : 시작번지부터 값을 읽거나 쓸 길이를 나타냅니다.

Byte Count [1Bytes] : Request, Response에 따른 메모리 Data의 byte 수를 나타냅니다. 즉, 읽거나 쓸려는 메모리 데이터의 Byte의 개수를 말합니다.

 

 - DATA [N Byte] : Request, Response에 따른 메모리 Data의 값 나타냅니다. 즉, 읽거나 쓸려는 메모리 값입니다.

 

아래 그림은 Read Coil 예시이며, 프로토코별 Data 구조를 더 많이 확인하고 싶다면 하단 <참고 사이트 4> 참고하시면 됩니다.

 

 

 

4. I/O 메모리 구조

 

 MODBUS 장비의 메모리 구조는 MODBUS 프로토콜의 범위를 벗어나는 부분이므로 표준에 정의되어 있지 않습니다. 따라서 제조사의 구현 방식과 정책에 따라 그 구조가 달라질 수밖에 없습니다. 크게 보면 데이터 종류별로 블록을 각각 지정하여 4개의 데이터 블록을 사용하는 방식과 모든 데이터를 하나의 데이터 블록에 연결시켜 사용하는 방식 2가지를 들 수 있습니다.

 

1) 솔래시스템사의 I/O Gateway 메모리 구조

 

 

 

2) comfile사의 TCPPORT 제품의 메모리 구조

 

 

 

 ModbusTCP 자료들 정리 겸 짜깁기해 보았는데, 어색한 부분이 있습니다. 아래 참고 사이트들의 원본을 한번 더 보면 도움이 되지 않을까 합니다. 하나의 정보는 헷갈리는 부분들이 있는데, 여러 자료들을 보면서 부족한 부분이 채워가야 할 듯합니다.

 

감사합니다.

 

 

 

<참고 사이트>

1. Modbus Organization

https://www.modbus.org/

1. Introduction to Modbus and Raspberry PLC. Part 4

https://www.industrialshields.com/blog/raspberry-pi-for-industry-26/introduction-to-modbus-and-raspberry-plc-part-4-589

2. plantuml

https://www.plantuml.com/

3. MODBUS-TCP란

http://comfilewiki.co.kr/ko/doku.php?id=tcpport:modbus-tcp_%ED%94%84%EB%A1%9C%ED%86%A0%EC%BD%9C%EC%9D%B4%EB%9E%80:index

4. Function Code별 DATA 구조 및 디바이스 제어

http://comfilewiki.co.kr/ko/doku.php?id=tcpport:funtion_code%EB%B3%84_data_%EA%B5%AC%EC%A1%B0_%EB%B0%8F_%EB%94%94%EB%B0%94%EC%9D%B4%EC%8A%A4_%EC%A0%9C%EC%96%B4:index

5. ezTCP의 Modbus/TCP

https://www.sollae.co.kr/ko/download/pds_files/an_modbus_tcp_ko.pdf  

 

 

반응형