MODBUS 통신 드라이버

 

MODBUS는 미국의 Modicon PLC 등에서 사용하는 표준 프로토콜이다.

 

1. 읽기 설정

 

<그림 1>은 MODBUS 통신 드라이버를 사용할 때의 통신설정 예이다.

 

             <그림 1> MODBUS 시리얼 통신설정 예

 

<그림 1>의 DEVICE 설정은 연결된 통신포트(COM1), 통신속도( 9600 ), Parity Bit ( 0 ), Data Bit ( 8 ), Stop Bit ( 1 ), 순으로 장비에 설정된 값을 입력한다.

MODBUS 통신 드라이버의 옵션 부 에는 읽은 패킷의 CRC 체크 여부( 1 = 체크 함, 0 = 체크 안함 ), 비트 ON 쓰기 값 ( 기본 = 65280 ), MODBUS IP 프로토콜 사용여부( 1 = IP 프로토콜, 0 = 일반 시리얼 프로토콜 ) , 비트 OFF 쓰기 값 ( 기본 = 0 ), DWORD/FLOAT 등의 값을 읽을 때 읽을 크기를 WORD 단위 비 사용여부( 1 = 사용안함, 0 = WORD 단위로 계산, 기본 : 0 ), 멀티쓰기 사용여부(0 = 사용안함, 1 = 사용, 기본 : 0), 데이터 값 비교를 위한 상태값 저장위치(WORD 메모리 번지지정, 기본 : 1000) 순으로 콤마( , )로 구분하여 입력한다.

 

주의) DWORD/FLOAT 등의 값을 읽을 때 읽을 크기를 WORD 단위를 사용하지 않는 경우에는 통신 프로토콜 레벨에서 DWORD/FLOAT 1개의 데이터를 읽을 때 2개의 데이터를 요구하는 것이 아니라 1 개의 데이터를 요구하는 프로토콜 형식이다. ( GAS Micro iMaCS 등의 장비에서 사용함 )

 

 

참고) MODBUS IP 프로토콜은 Ethernet 등으로 연결된 시스템에서 사용하고 통신형식은 TCP/IP 또는 UDP/IP를 사용한다.

 

 

읽기 설정 방법

READ 스테이션 읽을 종류 읽을 시작주소 메모리 저장위치 읽는 개수
READ, 1, 3, 0, 0, 32,
DWORD, 1, 3d, 200, 0, 50,
DWORD, 1, 3d, 300, 50, 50,
DWORD, 1, 3F, 2000, 0, 50,

 

1) 스테이션 : 연결된 장비의 스테이션 (ID) 번호. ( 0 ~255 )

2) 읽을 종류 : 읽을 데이터 종류를 지정. (Function Code 번호, 일반적으로 Function Code 3 = 40000번 Register 대역, Function Code 4 = 30000번 Register 대역)

3 – WORD 단위의 데이터 읽기,

3D – DWORD 단위의 데이터 읽기 ( LO, HI 데이터 순 ),

3d – DWORD 단위의 데이터 읽기 ( HI, LO 데이터 순 ),

3lD, 3LD – 8 BYTE 단위의 데이터 읽기 ( LO, HI 데이터 순 ),

3ld, 3Ld – 8 BYTE 단위의 데이터 읽기 ( HI, LO 데이터 순 ),

3M – HI WORD x 10000 + LO WORD 형식의 DWORD 데이터 읽기 ( LO, HI 데이터 순 ),

3m – HI WORD x 10000 + LO WORD 형식의 DWORD 데이터 읽기 ( HI, LO 데이터 순 ),

3lM, 3LM – HI WORD x 10000 + LO WORD 형식의 8 BYTE 단위의 데이터 읽기 ( LO, HI 데이터 순 ),

3lm, 3Lm – HI WORD x 10000 + LO WORD 형식의 8 BYTE 단위의 데이터 읽기 ( HI, LO 데이터 순 ),

3s – 16 BYTE BCD ASCII 데이터 읽기,

3F – FLOAT 단위의 데이터 읽기 ( LO, HI 데이터 순 ),

3F2 – FLOAT 단위의 데이터 읽기 ( LO, HI 데이터 순 2 ),

3f – FLOAT 단위의 데이터 읽기 ( HI, LO 데이터 순 ),

3f2 – FLOAT 단위의 데이터 읽기 ( HI, LO 데이터 순 2 ),

3U – DOUBLE 단위의 데이터 읽기 ( LO, HI 데이터 순 ),

3u – DOUBLE 단위의 데이터 읽기 ( HI, LO 데이터 순 ),

1X, 2X – 비트 단위의 데이터 읽기 ( 1xxxx, 2xxxx Modbus 번지 )

1XB, 2XB – 비트 단위의 데이터 읽기, 비트 단위 읽기 개수 ( 1xxxx, 2xxxx Modbus 번지 )

3B – BYTE 단위의 데이터 읽기.

3) 읽을 시작주소 : 읽을 시작번지. (modbus 주소 –1 )

4) 메모리 저장 위치 : 읽어온 상태 값을 저장할 버퍼위치.

5) 읽는 크기: 읽을 크기.

3 – WORD 단위 개수,

3D, 3d, 3M, 3m, 3F, 3F2, 3f, 3f2 – 2 WORD 단위 개수,

3LD, 3ld, 3LM, 3lm, 3U, 3u – 4 WORD 단위 개수,

3s – 8 WORD 단위 개수,

1X, 2X – WORD 단위 개수,

1XB, 2XB – 비트 단위의 읽기 개수, ( 1 ~ 15 = 1 WORD, 16 ~ 31 = 2 WORD, …)

3B – BYTE 단위 개수.

 

<그림 1> 프로토콜 옵션부의 option 아이콘을 클릭하면 <그림 2>의 대화상자가 나타나는데 여기서도 READ 스케쥴을 작성할 수 있다.

 

<그림 2> MODBUS 드라이버의 통신 읽기 설정 대화상자

 

<그림 2>의 edit, add, delete 버턴과 리스트 박스를 이용하여 READ 스케쥴을 작성한다.

<그림 2>의 ‘Check CRC Error’ 부분에서 읽은 패킷의 CRC 체크여부, ‘Bit Write On Val’ 영역에 비트 ON 출력 시 쓰기 값( 기본 = 65280 ), ‘Use Modbus IP Protocol’ 에서 MODBUS IP 프로토콜 사용여부, ‘Bit Write Off Val’ 영역에 비트 OFF 출력 시 쓰기 값( 기본 = 0 ), ‘Don’t Use WORD Unit Read Size’ 영역에 DWORD/FLOAT 등의 값을 읽을 때 읽을 크기를 WORD 단위 비 사용여부를 설정할 수 있다.

 

<그림 3> MODBUS 드라이버의 통신 읽기 설정 READ 추가/편집 대화상자의 예

 

 

<그림 3>는 <그림 2>의 대화상자에서 READ 스케쥴을 추가 또는 편집할 때 나타나는 대화상자이다.

 

2. 쓰기 설정

출력은 SCAN File과 상관없이 컨트롤러의 직접 ADDRESS에 쓴다.

 

디지털 출력 설정법

디지털 출력으로 장비의 상태 값(reset 등)을 설정하거나 Relay 등을 제어할 수 있다.

 

디지털 출력 TAG 설정 시 필요한 요소

1) PORT           연결된 PORT 번호.

2) STATION      장비의 스테이션( ID ) 번호.

시리얼 통신 - 1 ~ 247,

TCP/IP – 100, 255 등.

3) Address      출력 번지. 10진수 단위의 출력번지. (Address, Modbus Register 번지 – 1 )

4) Extra1          출력하고자 하는 데이터 종류. (Function Code, 5 = Single Coil)

5 – WORD 단위의 데이터 쓰기,

5) Extra2          사용안함.

 

예1) Station : 1  Address : 0100  Extra1 : 5, EXTRA2 : 빈칸으로 설정하고 디지털 ON 출력을 하면 1번 Station MODBUS 장비의 100 번지 (Modbus 101번 Register 번지 ) 값을 통신 프로그램의 옵션창에서 설정한 Bit Write On Value 설정한 값(기본 65280, 0xFF00)으로 변경할 수 있다.

 

예2) Station : 1  Address : 0100  Extra1 : 5, EXTRA2 : 빈칸으로 설정하고 디지털 OFF 출력을 하면 1번 Station MODBUS 장비의 100 번지 (Modbus 101번 Register 번지 ) 값을 통신 프로그램의 옵션창에서 설정한 Bit Write On Value 설정한 값(기본 0, 0x0000)으로 변경할 수 있다.

 

아날로그 출력 설정법

아날로그 출력은 BYTE/WORD/DWORD/FLOAT 값을 메타에 쓰는 것을 말한다.

 

아날로그 출력 TAG 설정 시 필요한 요소

1) PORT           연결된 PORT 번호.

2) STATION      장비의 스테이션( ID ) 번호.

시리얼 통신 - 1 ~ 247,

TCP/IP – 100, 255 등.

3) Address      출력 번지. 10진수 단위의 출력번지. (Address, Modbus Register 번지 – 1 )

4) Extra1          출력하고자 하는 데이터 종류. (Function Code,  6 = Single Register, 16 = Multiple Register)

16 – WORD 단위의 데이터 쓰기,

16D – DWORD 단위의 데이터 쓰기 ( LO, HI 데이터 순 ),

16d – DWORD 단위의 데이터 쓰기 ( HI, LO 데이터 순 ),

16lD, 16LD – 8 BYTE 단위의 데이터 쓰기 ( LO, HI 데이터 순 ),

16ld, 16Ld – 8 BYTE 단위의 데이터 쓰기 ( HI, LO 데이터 순 ),

16M – HI WORD x 10000 + LO WORD 형식의 DWORD 데이터 쓰기 ( LO, HI 데이터 순 ),

16m – HI WORD x 10000 + LO WORD 형식의 DWORD 데이터 쓰기 ( HI, LO 데이터 순 ),

16lM, 16LM – HI WORD x 10000 + LO WORD 형식의 8 BYTE 단위의 데이터 쓰기 ( LO, HI 데이터 순 ),

16lm, 16Lm – HI WORD x 10000 + LO WORD 형식의 8 BYTE 단위의 데이터 쓰기 ( HI, LO 데이터 순 ),

16s – 16 BYTE BCD ASCII 데이터 쓰기,

16F – FLOAT 단위의 데이터 쓰기 ( LO, HI 데이터 순 ),

16F2 – FLOAT 단위의 데이터 쓰기 ( LO, HI 데이터 순 2 ),

16f – FLOAT 단위의 데이터 쓰기 ( HI, LO 데이터 순 ),

16f2 – FLOAT 단위의 데이터 쓰기 ( HI, LO 데이터 순 2 ),

16U – DOUBLE 단위의 데이터 쓰기 ( LO, HI 데이터 순 ),

16u – DOUBLE 단위의 데이터 쓰기 ( HI, LO 데이터 순 ), 

16B – BYTE 단위의 데이터 쓰기,

16H_TIME – HICM 장비에 컴퓨터의 현재시간 전송. (년, 월, 일, 시, 분, 초, 각 1워드씩 6워드를 전송, 아날로그 쓰기만 사용)

5) Extra2          멀티 아날로그 값 쓰기/비교 설정

1 = 멀티 쓰기 값 저장,  ( Extar1 영역은 상관안함 )

2 = 현재 저장된 값으로 멀티 쓰기 값 쓰기, ( 현재 설정한 번지부터 저장된 개수 만큼 연속 쓰기 )

3 = 멀티 쓰기 값으로 저장된 모든 내용을 삭제, ( Extar1 영역은 상관안함 )

4 = 현재 저장된 값과 PLC 메모리 번지 값을 비교, ( 현재 설정한 번지부터 저장된 개수 만큼 연속 쓰기 )

기타 값( 0 또는 4보다 클 때 ) = 일반( 하나의 ) 아날로그 값 쓰기

 

 

예1) Station : 1  Address : 0100  Extra1 : 16, EXTRA2 : 빈칸으로 설정하고 아날로그 출력을 하면 1번 Station MODBUS 장비의 100 번지 ( Modbus 101번 Register 번지 ) 값을 설정한 값으로 변경할 수 있다.

 

예2) Station : 1  Address : 5000  Extra1 : 16d, EXTRA2 : 빈칸으로 설정하고 아날로그 출력을 하면 1번 Station MODBUS 장비의 5000 번지 ( Modbus 5001번 Register 번지 ) 값을 설정한 값으로 변경할 수 있다.

 

 

멀티 워드 쓰기 설정을 위한 스크립트 작성 예)

$AO_0000.Extra2 = 3;                                            // 이전에 저장된 멀티 쓰기 값 삭제

@SetTagValue("AO_0000", 0);

 

$AO_0000.Extra2 = 1;                                            // 멀티 쓰기 값 저장으로 설정

for(i = 0; i < 50; i = i + 1) {

   @sprintf($AO_0000.Extra1, "%03d", i);               // Extra1 에 임의의 값을 넣어서 동일한 데이터를 무시하지 않도록 설정

   @SetTagValue("AO_0000", 5000);                      // 실제 출력 값 저장, 여기서는 5000 으로 임의 저장

}

@sprintf($AO_0000.Extra1, "16");              // 출력할 데이터 종류 = WORD 단위로 설정

$AO_0000.Extra2 = 2;                                            // 멀티 값 쓰기 지정

@SetTagValue("AO_0000", 1);                               // 값 쓰기, 50개 값을 지정한 번지부터 출력

 

 

PLC에 현재 값과 메모리 값이 동일한지를 확인하기 위한 스크립트 작성 예)

$AO_CHECK_MEM_SET = 2;                                     // 비교완료 확인을 위한 WORD 번지를 2로 설정

for(i = 0; i < 1; ) {

   if($AI_CHECK_WRITE_STATUS == 2) i = 10;           // 2의 값 쓰기가 완료되었다.

   @TagCheckLoop();                                             // 태그 값 변경 확인 함수

}

 

$AO_0000.Extra2 = 3;                                                // 이전에 저장된 데이터 값 삭제

@SetTagValue("AO_0000", 0);

 

$AO_0000.Extra2 = 1;                                                // 데이터 값 저장으로 설정

for(i = 0; i < 50; i = i + 1) {

   @sprintf($AO_0000.Extra1, "%03d", i);                   // Extra1 에 임의의 값을 넣어서 동일한 데이터를 무시하지 않도록 설정

   @SetTagValue("AO_0000", 5000);                         // 비교할 값 저장, 여기서는 5000 으로 임의 저장

}

@sprintf($AO_0000.Extra1, "16");                               // 비교할 데이터 종류 = WORD로 설정

$AO_0000.Extra2 = 4;                                                // 자료 값 비교 지정

@SetTagValue("AO_0000", 1);                                   // 지정한 번지부터, 입력한 수 만큼의 데이터를 비교하라는 명령

 

for(i = 0; i < 1; ) {

   if($AI_CHECK_WRITE_STATUS == 1) i = 10;           // 비교한 결과 1 = 동일 데이터

   if($AI_CHECK_WRITE_STATUS == 0) {                  // 비교한 결과 0 = 다른 데이터 존재

      @MessageBox("비교 자료의 내용이 서로 다릅니다.", "자료비교 에러", MB_OK);

      return;

   }

   @TagCheckLoop();                                             // 태그 값 변경 확인 함수

}

@MessageBox("비교한 자료의 내용이 동일합니다.", "자료비교 완료", MB_OK);

 

 

비교를 위한 스크립트 작성 시 주의점)

1) 비교 결과는 옵션에서 설정한 WORD 메모리 번지에 1 ( 동일 데이터 ), 0 ( 서로 다른 데이터 )으로 저장.

2) 장비의 현재 값과 비교하기 전에 설정한 WORD 번지에 1, 0 이외의 값을( 예 에서는 2의 값 ) 먼저 입력하여 비교결과를 확인.

3) AO_CHECK_MEM_SET 아날로그 출력태그는 옵션에서 설정한 WORD 번지를 강제로 출력하도록 설정 ( Extra1 = #MEM# 으로 설정 )

4) AI_CHECK_WRITE_STATUS 아날로그 입력태그는 PLC_SCAN 태그로 설정한 WORD 번지에 맞춘다.

 

 

블록 쓰기

블록쓰기는 스크립트의 PlcScanWriteBlock 함수를 사용하여 다음과 같이 설정한다.

스크립트 이름과 형식 : @PlcScanWriteBlock(int port, int station, int address, string extra1, string extra2, object array_value, int array_size);

   스크립트 작성 예

             ushort   writeVal[5];

 

            writeVal[0] = 1;

            writeVal[1] = 2;

            writeVal[2] = 3;

            writeVal[3] = 4;

            writeVal[4] = 5;

            @PlcScanWriteBlock(0, 1, 5, “16”, “”, writeVal, 5);

 

Modbus 통신 드라이브의 블록 쓰기의 Extra1 인자는 다음과 같은 종류 중에서 설정한다. (16 이외의 Function 도 설정 가능, Function 이 ‘0’ 이면 기본으로 16( 10h )으로 설정함)

16 – WORD 단위의 블록 데이터 쓰기,

16D – DWORD 단위의 블록 데이터 쓰기 ( LO, HI 데이터 순 ),

16d – DWORD 단위의 블록 데이터 쓰기 ( HI, LO 데이터 순 ),

16lD, 16LD – 8 BYTE 단위의 블록 데이터 쓰기 ( LO, HI 데이터 순 ),

16ld, 16Ld – 8 BYTE 단위의 블록 데이터 쓰기 ( HI, LO 데이터 순 ),

16M – HI WORD x 10000 + LO WORD 형식의 DWORD 블록 데이터 쓰기 ( LO, HI 데이터 순 ),

16m – HI WORD x 10000 + LO WORD 형식의 DWORD 블록 데이터 쓰기 ( HI, LO 데이터 순 ),

16lM, 16LM – HI WORD x 10000 + LO WORD 형식의 8 BYTE 단위의 블록 데이터 쓰기 ( LO, HI 데이터 순 ),

16lm, 16Lm – HI WORD x 10000 + LO WORD 형식의 8 BYTE 단위의 블록 데이터 쓰기 ( HI, LO 데이터 순 ),

16F – FLOAT 단위의 블록 데이터 쓰기 ( LO, HI 데이터 순 ),

16F2 – FLOAT 단위의 블록 데이터 쓰기 ( LO, HI 데이터 순 2 ),

16f – FLOAT 단위의 블록 데이터 쓰기 ( HI, LO 데이터 순 ),

16f2 – FLOAT 단위의 블록 데이터 쓰기 ( HI, LO 데이터 순 2 ),

16B – BYTE 단위의 블록 데이터 쓰기,

 

중요) 블록 쓰기는 10.1.4.3 이상의 프로그램에서만 지원한다. 한번에 최대 250개의 데이터 쓰기가 가능합니다.

 

[참고] MODBUS 프로토콜을 사용하는 장비

(주)중앙제어 - NV4016A