hyuko

MODUBS RTU 본문

프로토콜

MODUBS RTU

hyuko12 2024. 7. 19. 08:55
728x90
반응형

1. Modbus RTU 프로토콜의 형태

- 모든 통신은 프로토콜을 맞춰서 보내야 정상적인 요청과 응답이 가능하다.

- Modbus RTU 방식 또한 프로토콜을 아래의 그림처럼 제공하고 있다.

 

 

읽기에 대한 프로토콜과 쓰기에 대한 프로토콜은 조금씩 다르고 첫 번째로 읽기에 대한 프로토콜을 알아보도록 합니다.

MBAP HEADER MBAP HEADER DATA DATA DATA DATA CRC CRC
slave id function code start address hi start address lo quantity hi quantity lo crc lo crc hi
1byte 1byte 1byte 1byte 1byte 1byte 1byte 1byte

 

 

1.1 일반적으로 Modbus RTU 방식은 시리얼 통신에서 사용이 된다.

- 형태에 따라서 TCP / IP 패킷 위에 프로토콜을 올려서 보내는 MODBUS RTU over TCP 방식도 존재한다.

 

1.2 위의 표에 있는 부분들을 자세히 알아보자.

1. slave id

  - 기본적으로 1번이며 기기의 고유 id 값입니다.

2. function code

  - 읽기와 쓰기 두 개의 큰 분류로 나누어지며 읽기와 쓰기에 대해서도 코드가 나뉘게 된다.

    - 읽기

      - Read Holding Register: 0x03

      - Read Input Register: 0x04

    - 쓰기

      - Write Single Registers: 0x06 -> 한 개의 파라미터 값을 쓰기

      - Write Multiple Registers: 0x10 -> 연속된 파라미터들을 정해진 개수만큼 쓰기

3. Data

  - start address: 읽거나 쓰기를 하려는 파라미터의 시작 주소 (대체적으로 -1 한 값)

  - quantity: 이 부분은 읽기에만 해당하고 읽고자 하는 파라미터의 개수

  - value: 쓰기의 경우 quantity 부분에  value가 있으며 쓰고자 하는 값이다.

 

4. CRC

  - CRC가 중요한 것은 앞의 모든 프로토콜이 맞다 하더라도 해당 CRC에서 오류가 나게 되면 아무것도 일어나지 않는다.

 

CRC 란?
CRC(Cyclic Redundancy Check)는 데이터의 무결성을 검사하는데 널리 사용되는 알고리즘 중 하나이다.
이는 데이터의 전송 또는 저장 시 발생할 수 있는 오류를 감지하는 방법으로 사용이 된다.
간단히 말하면, CRC는 데이터 블록에 대한 검사합(Checksum)을 생성하고 이를 데이터 블록과 함께 전송
수신 측에서는 동일한 알고리즘을 사용하여 새로운 검사합을 생성하고, 이를 원래의 검사합과 비교하여 데이터의 무결성을 검증

 

  - 그중에서 우리가 이번에 알아보고 쓰는 알고리즘은 CRC-16 Modbus RTU 방식으로 16비트의 CRC를 이용해서 특정 다항식(0 xA001)을 사용한다.

 

계산 방식은 아래와 같다.

1. 초기 CRC를 0 xFFFF로 설정

2. 사용할 다항식을 0 xA001로 설정

3. 루프를 돌면서 각 바이트에 대해 다음을 수행

4. 현재 바이트와 CRC값을 XOR 연산

5. 8회 반복동안 다음을 수행

6. CRC의 최하위 비트가 1이면, CRC 값을 오른쪽으로 1비트 시프트 한 후 다항식과 XOR 연산

7. CRC의 최하위 비트가 0이면, CRC 값을 오른쪽으로 1비트 시프트만 수행

8. 마지막으로 계산된 16비트 CRC 값을 두 개의 8비트 바이트로 분할하여 반환

 

자바코드로 구현한 CRC 계산기

private byte[] calculateCRC16Modbus(byte[] data) {
        int crc = 0xFFFF;
        int polynomial = 0xA001;

        for (byte b : data) {
            crc ^= (int) b & 0xFF;
            for (int i = 0; i < 8; i++) {
                if ((crc & 0x0001) != 0) {
                    crc = (crc >> 1) ^ polynomial;
                } else {
                    crc >>= 1;
                }
            }
        }

        return new byte[]{(byte) (crc & 0xFF), (byte) (crc >> 8)};
    }

 

 

728x90
반응형

'프로토콜' 카테고리의 다른 글

Modbus TCP  (0) 2024.07.19
Modbus 프로토콜  (0) 2024.07.19