1. 모드버스란?
- Modbus는 원래 Modicon(현재 Schneider Electric )에서 PLC( Programming Logic Controller )와 함께 사용하기 위해 1979년에 발행한 데이터 통신 프로토콜이다.
- 모든 프로토콜이 만들어진 이유가 그렇듯 모드버스 또한 PLC 통신규약이 모두 달랐기에 편리성을 위해 통일시키고자 생겨났다.
- 처음에는 시리얼통신(RS-232, RS-485)을 기준으로 만들어졌으며 현재는 TCP, UDP에서도 구현할 수 있도록 확장되었다.
- 마스터/슬래이브 구조로 여러 주변 장비의 상태 정보를 모니터링할 수 있다. 네트워크 상에 연결된 모든 장비들이 요청을 받으나, 정해진 장비만 답을 하는 구조이다. RTU(Remote Terminal Unit), ASCII, TCP 통신을 지원하며, 각각 형식이 다르다. (*본 포스팅에 Modbus Ascii 내용은 제외한다.)
- 메시지 하나에 최대 크기는 260 Byte로 제한적이다.
(할당된 Byte에 비해 턱없이 부족하게 제한된 데이터가 있는데 맥시멈 크기 때문) - 1979년에 발행한 프로토콜인 만큼 구조가 간단하고 개발, 관리가 쉬우나 장비 연결 기기 개수에 제한되며(1~247개) 보안 기능이 없으며 자료형 등 편리성 또한 떨어진다.
- 빅 엔디안(Big-Endian) 형식이다.
2. 모드버스 구조
앞서 말했다시피 RTU, TCP, ASCII 등에 따라 구조가 다르다.
(이하 상세 설명)
- PDU(Protocol Data Unit)
데이터에 직접 관련된 타입으로 쓰기/읽기 등의 명령인 Function code와 실제로 읽고 쓰는 Data 구조로 되어있다.
(이하 상세 설명)
- ADU(Application Data Unit)
PDU를 포함하여 헤더와 같은 기능을 추가한 구조이다. ADU경우 통신 형태에 따라 다르다.
(이하 상세 설명)
2-1. ADU
[RTU 구조]
ADU | 항목 | 길이 | 설명 |
Additional address |
Slave address | 1 byte | Slave 장비의 국번(station) |
Error check | CRC16 | 2 byte | CRC16(Cyclic Redundancy Check) 참조 일종의 Checksum |
* 문서를 검색하다 보면 Start, End(각각 28bit)가 붙는 경우가 있는데 이게 뭐냐면 메시지와 메시지 사이에 3.5 charater time, 즉 28bit의 여유를 두고 전송하라는 뜻이다. 일반적으로 9600 baud를 사용하여 1초에 9600bit을 통신하니 28/9600 = 0.003초의 간격을 두고 메시지를 전송... 전송... 전송... 하라는 뜻
[TCP/IP 구조]
ADU | 항목 | 길이 | 설명 |
MBAP Header |
Transcation Identifier | 2 byte | 요청/응답 임의 번호 |
Protocol Identifier | 2 byte | Protocol ID로 0x0000 고정 | |
Length | 2 byte | Length이후 마지막 프레임까지의 길이(byte) | |
Unit Identifier | 1 byte | 여러 장비가 연결되어 있을 경우 사용하나 보통 TCP통신에서는 사용X |
(표가 왜 망가지는지 모르겠다...)
2-2. PDU
- 모드버스의 핵심이라 생각한다... 통신 형태에 상관없이 PDU는 고정!
- PLC마다 메모리 구조는 다 다르다. 어떤 PLC는 데이터를 한 공간에 전부 있는 반면 어떤 PLC는 세부적으로 영역이 나뉘어 있다. 그래서 Modbus에서의 bit/word 데이터 저장은 Slave 측의 명령어에 따른 메모리 설정에 따라 다르다. 이를 매핑이라 한다.
- 정말 자주 사용하는 명령어는 아래의 6가지이다.
Type | Bit | Word |
Only Read | Read Descrete inputs | Read Input Registers |
Write | Write Single Coil | Write Single Register |
Read | Read Coils | Read Holding Regsters |
- Only Read는 Master 측에서 수정할 수 없고 오로지 읽을 수만 있는 값이다.
예를 들면 아두이노 입력 핀에 읽기 명령어 digital/analogRead와 같다.
입력 센서 버튼이 눌러져서 1이 읽히고 있는데 그 값을 0으로 설정할 수 없는 것과 같다. - Write/Read는 출력 핀의 출력 값이다.
예를 들면 아두이노 출력 핀에 HIGH/LOW값을 digital/analogWrite 하거나, 출력 핀의 상태 값을 digital/analogRead 하는 것과 같다.
아래부터는 자주 사용되는 Function Code에 대한 Data값을 나열한다. 이외의 명령어를 사용하고 싶다면 가장 아래에 매뉴얼을 첨부할 테니 직접 찾아본다.
* 앞으로 나올 모든 값들은 16진수(Hex)이며 16진수 표기인 "0x"를 제외한다.
** 해당 명령어는 PDU(Function Code + Data)이다. Modbus통신을 테스트하고자 하면 ADU를 포함하여 전송하자.
*** 앞으로 나오는 Address는 0부터 시작하나 Coil 또는 Register의 단위는 1부터 시작한다.
**** 레이아웃 정리는 안 귀찮을 때 수정 예정
Read Coils(Function Code [이하 FC] : 01)
- Reqeust
Function Code
(1 byte)Address
(2 byte)Data Count
(2 byte)01 00 00 ~ FF FF 00 01 ~ 07 D0 - Response
Function Code
(1 byte)Byte count
(1 byte)Data
(N byte)01 N - - Error
Error Code
(1 byte)Exception code
(1 Byte)81 01 ~ 04 - Example
- Request
Function Code
(1 byte)Address
(2 byte)Data Count
(2 byte)01 00 13 00 13
-Response
Function Code
(1 byte)Byte count
(1 byte)Data
(N byte)01 03 CD 6B 05 CD 6B 05 address 27 26 25 24 23 22 21 20 35 34 33 32 31 30 29 28 - - - - - 38 37 36 Value 1 1 0 0 1 1 0 1 0 1 1 0 1 0 1 1 0 0 0 0 0 1 0 1
Read Discrete Inputs(FC 02)
- Reqeust
Function Code
(1 byte)Address
(2 byte)Data count
(2 byte)02 00 00 ~ FF FF 00 01 ~ 07 D0 - Response
Function Code
(1 byte)Byte count
(1 byte)Data
(N byte)02 N - Error
Error Code
(1 byte)Exception code
(1 byte)82 01 ~ 04 - Example
- Request
Function Code
(1 byte)Address
(2 byte)Data Cout
(2 byte)02 00 C4 00 16
-Response
Function Code
(1 byte)Byte count
(1 byte)Data
(N byte)02 03 AC DB 35 AC DB 35 address 204 203 202 201 200 199 198 197 212 211 210 209 208 207 206 205 - - 218 217 216 215 214 213 Value 1 0 1 0 1 1 0 0 1 1 0 1 1 0 1 1 0 0 1 1 0 1 0 1
Read Holding Registers(FC 03)
- Reqeust
Function Code
(1 byte)Address
(2 byte)Data count
(2 byte)03 00 00 ~ FF FF 00 01 ~ 00 7D - Response
Function Code
(1 byte)Byte count
(1 byte)Data
(2*N byte)03 2*N - Error
Error Code
(1 byte)Exception code
(1 byte)83 01 ~ 04 - Example
-Request
Function Code
(1 byte)Address
(2 byte)Data count
(2 byte)03 00 6B 00 03
-Response
Function Code
(1 byte)Byte count
(1 byte)Data
(2*N byte)03 06
(3 word = 6)02 2B 00 00 00 64
Address 108H 108L 109H 109L 110H 110L Value 02 2B 00 00 0 64
Read Input Registers(FC 04)
- Reqeust
Function Code
(1 byte)Address
(2 byte)Data count
(2 byte)04 00 00 ~ FF FF 00 01 ~ 00 7D - Response
Function Code
(1 byte)Byte count
(1 byte)Data
(2*N byte)04 2*N - Error
Error Code
(1 byte)Exception code
(1 byte)84 01 ~ 04 - Example
- Request
Function Code
(1 byte)Address
(2 byte)Data count
(2 byte)04 00 08 00 01
- Response
Function Code
(1 byte)Byte count
(1 byte)Data
(2*N byte)04 02
(1 word = 2)00 0A Address 9H 9L Value 00 0A
Write Single Coil(FC 05)
- Reqeust
Function Code
(1 byte)Address
(2 byte)Data
(2 byte)05 00 00 ~ FF FF 00 00 or FF 00
FF 00 : 1 bit를 뜻함 (다른 모든 값은 Coil에 영향 X) - Response
Function Code
(1 byte)Address
(2 byte)Data
(2 byte)05 00 00 ~ FF FF 00 00 or FF 00 - Error
Error Code
(1 byte)Exception code
(1 byte)85 01 ~ 04 - Example
-Request
Function Code
(1 byte)Address
(2 byte)Data
(2 byte)05 00 AC FF 00
-Response
Function Code
(1 byte)Address
(2 byte)Data
(2 byte)05 00 AC FF 00
Write Single Register(FC 06)
- Reqeust
Function Code
(1 byte)Address
(2 byte)Data
(2 byte)06 00 00 ~ FF FF 00 00 ~ FF FF - Response
Function Code
(1 byte)Address
(2 byte)Data
(2 byte)06 00 00 ~ FF FF 00 00 ~ FF FF - Error
Error Code
(1 byte)Exception code
(1 byte)86 01 ~ 04 - Example
- Request
Function Code
(1 byte)Address
(2 byte)Data
(2 byte)06 00 01 00 03
- Response
Function Code
(1 byte)Address
(2 byte)Data
(2 byte)06 00 01 00 03
Write Multiple Coils(FC 0F)
- Reqeust
Function Code
(1 byte)Address
(2 byte)Coil count
(2 byte)Data Count
(1 byte)Data
(N byte)0F 00 00 ~ FF FF 00 01 ~ 07 B0 N
address 27 26 25 24 23 22 21 20 - - - - - - 29 28 coil 1 1 0 0 1 1 0 1 0 0 0 0 0 0 0 1 - Response
Function Code
(1 byte)Address
(2 byte)Coil count
(2 byte)0F 00 00 ~ FF FF 00 01 ~ 07 B0 - Error
Error Code
(1 byte)Exception code
(1 byte)8F 01 ~ 04 - Example
- Request
Function Code
(1 byte)Address
(2 byte)Coil count
(2 byte)Data Count
(1 byte)Data
(N byte)0F 00 13 00 0A 02 CD 01
- Response
Function Code
(1 byte)Address
(2 byte)Coil count
(2 byte)0F 00 13 00 0A Address 27 26 25 24 23 22 21 20 - - - - - - 29 28 Coil 1 1 0 0 1 1 0 1 0 0 0 0 0 0 0 1
Write Multiple Registers(FC 10)
- Reqeust
Function Code
(1 byte)Address
(2 byte)Register count
(2 byte)Data Count
(1 byte)Data
(2*N byte)10 00 00 ~ FF FF 00 01 ~ 00 7B 2*N - Response
Function Code
(1 byte)Address
(2 byte)Register count
(2 byte)10 00 00 ~ FF FF 00 01 ~ 00 7B - Error
Error Code
(1 byte)Exception code
(1 byte)90 01 ~ 04 - Example
- Request
Function Code
(1 byte)Address
(2 byte)Register count
(2 byte)Data Count
(1 byte)Data
(4 byte)10 00 01 00 02 04 00 0A 01 02
- Response
Function Code
(1 byte)Address
(2 byte)Register count
(2 byte)10 00 01 00 02
Error Code
코드 | 이름 | 설명 |
01 | 잘못된 함수 (ILLEGAL FUNCTION) |
허용되지 않은 또는 구현되지 않은 함수를 요청 |
02 | 잘못된 데이터 주소 (ILLEGAL DATA ADDRESS ) |
존재하지 않는 데이터주소를 요청 |
03 | 잘못된 데이터 값 (ILLEGAL DATA VALUE) |
데이터 입력범위 초과 또는 예외 데이터 요청 |
04 | 서버 장치 오류 (SERVER DEVICE FAILURE ) |
요청한 작업을 수행하는 동안 서버에서 오류가 발생 |
아래는 모드버스 매뉴얼이며 50페이지 정도 된다.
많은 내용을 다 담을 수 없어 필요한 내용만 본 포스팅에 올렸고 자세한 건 각자 매뉴얼을 봐야 한다.
모드버스 매뉴얼 링크
'0. 이론' 카테고리의 다른 글
Blocking & Non-blocking I/O + Synchronous&Asynchronous I/O 차이점 (0) | 2023.01.10 |
---|---|
TCP 송/수신 원리 (0) | 2023.01.08 |
풀업&풀다운 (Pull-up&Pull-down)이란? (0) | 2022.04.26 |
Getter&Setter 사용 이유 8가지 (0) | 2022.03.30 |
플로팅(Floating)현상이란? (0) | 2022.03.22 |
댓글