:: 진공에 대해 알려주마.

Access CC-LINK 본문

진공/노하우

Access CC-LINK

하이백 2022. 8. 31. 21:56

CC-LINK를 사용하는 설비를 서비스하게 되었다. 설비가 셋업 중이라 Main control program이 제대로 동작하지 않는다. 그래서 임시로 사용할 I/O Check 프로그램을 작성하였다. 이전에 작성한 것을 조금 수정하여 만들어 보았다. 

앞서 미쓰비시 제품 중 PC에 설치되는 scanner 보드에 접근하기 위한 방법은 모두 동일하다. 제공된 라이브러리를 이용하여 , 국번, 디바이스, 어드레스를 세팅하여 함수를 호출하면 된다.

 

MITSUBISHI IO-MODULE

 

MelsecNet-H, MelsecNet-G, CC-LICK 보드 모두 동일하며 읽고 쓰는 기본 단위가 8 비트, byte 사이즈로 되어 있다. PLC에 접근하다 보면 기본 단위가 WORD라는 것을 알게 된다. 초기에 byte라고 쓰여 있는데도 word로 착각하고... 

아래 제조사에서 제공하는 함수에서 보듯 mdOpen후 mdReceive를 이용하여 광카드, PLC, CC-Link IO 등 원하는 메모리의 값을 읽고 쓰고를 할 수 있다.  

글의 마지막에 MELSEC 디바이스를 설치하면 제공되는 sample code를 추가 하였다. 

 


 

여기에서 통신을 위한 명령을 샘플로 보여준다. 이게 통신은 전부 이다. mdOpen을 이용하여 통신을 열고 mdReceive, mdSend를 이용하여 값을 읽고 쓸 수 있다. 경우에 따라선 예제에서 처럼 mdReceiveEX를 사용할 수 있다. 

mdReceive는 파라메터가 short로 정의되어 있고 mdReceiveEX는 long으로 되어 있다. 결국 어디까지 읽을지에 따라 맞는 명령을 사용하면 된다. 사용하는 방식은 같다. 여기서는 mdReceive로 설명한다.

mdOpen(short Chan, short mode, ref int path);
mdReceive(int path, short Stno, short Devtyp, short DevNo, ref short Size_Renamed, ref short Buf);

메이커에서 제공하는 메뉴얼에 정의된 mdOpen()과 mdReceive() 함수의 원형은 다음과 같다.

 


함수설명 : mdOpen()

Format :
	ret = mdOpen(chan,mode,path);
Argument :
	short ret;	//Return value                              OUT
	short chan;	//Channel number of communication line      IN
	short mode;	//Dummy                                     IN
	long *path;	//Opened line path pointer                  OUT

Parameter 설명

chan은 다음과 같은 고유 ID를 가진다.

  • ID 51~54 까지는 광 이전의 사용하던 MELSEC Scanner(MelsecNet-H) 카드를 의미한다. 
    ID 151~154는 광카드(MelsecNet-G)를 의미한다. 역시 4개까지 설치 가능하며 번호는 자동 부여된다.
    ID 81~84는 PC에 설치되는 CC-LINK 보드를 의미한다. 
  • 위의 보드는 각각 최대 4개의 카드를 설치할 수 있으며 ID는 순서대로 자동 부여된다. 각각의 보드에 제공되는 유틸리티 프로그램으로 확인할 수 있다.

mode 별 의미가 없다. 

path는 보드의 ID가 리턴된다. 

연결을 위해 아래와 같이 사용된다. Open(연결) 후 receive를 이용하여 메모리를 읽어 오면 된다.

//const short m_ChanID = 51;		// for NET-H	51~54      
//const short m_ChanID = 151;		// for NET-G	151~154
const short m_ChanID = 81;	    	// for CC-LINK	81~84
private int m_Path;

// 
res = mdOpen(m_ChanID, -1, ref m_Path);
if (res != 0)
{
	return -1;				// Error
}

 

 


 

함수설명 : mdReceive()

Format :
	ret = mdReceive(path,stno,devtyp,devno,size,data);
Argument :
	short ret;    	//Return value                                   OUT
	long path;    	//Path of channel                                IN
	short stno; 	//Station number                                 IN
	short devtyp; 	//Device type                                    IN
	short devno; 	//Channel number                                 IN
	short *size; 	//Receive byte size                              IN/OUT
	short data[ ]; 	//Receive data with send source information      OUT

Parameter 설명

path는 51, 151, 81번의 장치 ID를 의미한다.

stno(Station No)는 읽고자 하는 모듈의 station 번호를 의미한다.
   const short m_ownrStn = 0xFF;      // Read from owner station
   const short m_otherStn = 0x01;     // Digital Input Module 32 Point
   const short m_otherStn = 0x05;     // Digital Output Module 16 Point

  • NetG 혹은 CC-Link등 PC에 설치되는 scanner 카드를 사용하는 이유는 하위 모듈에서 값을 읽어오는 수고를 scanner 카드가 대신해 준다. 다시 말하면 유틸리티 프로그램에서 설정한 대로 하위 모듈에서 값(상태)을 읽어와 PC Scanner 카드의 메모리에 실시간 저장해 둔다. 이는 거의 실시간이며 수 ms 정도이다.
  • 이 항목에 onwer station을 의미하는 0xFF를 설정하면 위에서 말한 실시간으로 저장해둔 메모리를 바로 읽어 온다는 의미이다. 이는 상대적으로 짧은 시간을 소비하여 접근 시간의 속도를 거의 실시간으로 처리할 수 있다. 
  • 반면에 집적 해당 스테이션의 번호를 입력하면 해당 모듈에 접근하여 필요한 값을 가져오는 forced reading으로 시간을 많이 소비한다. 채널수가 많을수록 시간은 더 많이 소비한다. 


devtype(Device Type) 중 자주 사용하는 형식을 적어본다. (샘플 코드에 전체 목록이 있음)
   #define DevX   (1)
   #define DevY   (2)
   #define DevL    (3)
   #define DevM   (4)
   #define DevD    (13)
   #define DevB    (23)
   #define DevW   (24)

devno(Device No)는 주소를 의미한다.
   Station 1번에 Digital input Module의 5번째 신호를 알고 싶은 경우 devype DevX(1)을 devno에 4를 지정하여 함수를 호출하면 된다.

*size는 읽을 byte수를 의미한다.

data[ ]는 읽어온 데이터가 리턴된다. bit 단위 처리하여 내용을 확인하거나 수치로 변환할 수 있다. 

 


CC-Link에 접근할수 있는 코드를 핵심 부분을 C#으로 구현해 보았다. 접속(mdOpen) 후 mdReceive / dmSend 명령을 이용하여 읽고 쓰면 된다. 읽고 쓰는 단위는 byte 이다. 대개는 WORD(2byte), DOUBLE WORD(4byte)로 이루어 진다.

[DllImport("MDFUNC32.DLL", EntryPoint = "mdopen", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
private static extern short mdOpen(short Chan, short mode, ref int path);

[DllImport("MDFUNC32.DLL", EntryPoint = "mdclose", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
private static extern short mdClose(int path);

[DllImport("MDFUNC32.DLL", EntryPoint = "mdsend", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
private static extern short mdSend(int path, short Stno, short Devtyp, short DevNo, ref short Size_Renamed, ref short Buf);

[DllImport("MDFUNC32.DLL", EntryPoint = "mdreceive", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
private static extern short mdReceive(int path, short Stno, short Devtyp, short DevNo, ref short Size_Renamed, ref short Buf);



const short cChanID = 81;               // CC-Link #1

const short cOwnerStn = 0xFF;           // Read from owner station
const short cRemoteStn = 0x02;          // Read from remote station

const short DevX = 1;
const short DevY = 2;
const short RwSize = 2;                 // 2 BYTE

int m_Path;

short ret;
short rwBuffer;

//
ret = mdOpen( cChanID, -1, ref m_Path );

//
short pDevType = DevX;
short pDevAddr = 0x000;
//
ret = mdReceive( m_Path, cOwnerStn, pDevType, pDevAddr, ref RwSize, ref rwBuffer );

//
rwBuffer = 0x1F;
ret = mdSend( m_Path, cOwnerStn, pDevType, pDevAddr, ref RwSize, ref rwBuffer );

 


 

아래는 메이커에서 제공하는 표준 C++ Read/Write 샘플 코드 이다.

/****************************************************************/
/*                                                             */
/*   Test program for Communication functions                  */
/*                                                             */
/*  Copyright (C) 1996 MITSUBISHI Electric Corporation         */
/*  All Rights Reserved                                        */
/***************************************************************/
/********************************************
*       Include files                       *
********************************************/
#include        <windows.h>
#include        <stdio.h>
#include        "mdfunc.h"

/*******************************************
*       Common define                      *
********************************************/
#define __VC2005__  (_MSC_VER >= 1400)  /* VC2005 check macro */

/*************************************************************
* Reads in device "D" of specified No. on station No.1       *
* Do open processing and the close processing once.          *
* The open and the close need not be done at each            *
* md function execution.                                     *
*************************************************************/
void main(void)
{
    long    path;                             /*  variable to save path       */
    short   data = 0;                         /*  buffer to receive data      */
    short   ret;                              /*                              */
    long    netno,size,lret;                  /*                              */
    long    stno,devtyp,devno;                /*                              */

    ret = mdOpen(81,-1,&path);                /*  open 1st CC-Link board      */
    if(ret != 0){
        printf("mdOpen error[%04x]\n",ret);
    }
    netno   = 0x00;                           /*  network No 0 fixed          */
    stno    = 0x00;                           /*  station No 0 fixed          */
    devtyp  = 13;                             /*  device type "D" fixed       */
    for(;;){                                  /*                              */
        printf("Device No. (quit if less than 0) = ");
#if __VC2005__
        scanf_s("%d",&devno);                 /*  input device No.            */
#else
        scanf("%d",&devno);                   /*  input device No.            */
#endif
        if(devno < 0){                        /*  quit if less than 0         */
            ret = mdClose(path);              /*  close channel               */
            if(ret != 0){
                printf("mdClose error[%04x]\n",ret);
            }
            printf("End\n");
            exit(0);
        }
        size = 2;                             /*  size to read in = 2 bytes   */
        lret = mdReceiveEx( path, netno, stno, devtyp, devno, &size, &data);
        if(lret != 0){                        /*  error check                 */
            printf("mdReceiveEx error[%04x]\n",lret);
        }
        printf("data[%04x]\n",data);          /*  display data                */
    }

}

 

 

'진공 > 노하우' 카테고리의 다른 글

VIEW MON of RS-485  (0) 2022.11.20
시리얼 통신  (4) 2022.09.17
Install WINDOWS XP  (2) 2022.04.27
오실로스코프  (0) 2022.02.14
INTERLOCK  (0) 2020.12.27
Comments