데이터/PLC

미쓰비시 PLC 데이터 교신 형태 (QnA호환3E )

쿠와와 2021. 2. 25. 17:28

부디 이것 때문에 머리 아픈 사람이 나밖에 없기를 바라며 - 미쓰비시 PLC 에서 modbus 호환 모델이 없을 경우 c에서 데이터를 받아오자 

 

먼저 자신의 프레임 종류를 알아야 한다.

나는 Q시리즈E71를 사용하고 있다. -> QnA호환3E프레임

LRESULT CMFCApplication1Dlg::WMUSER_SEND_DATA(WPARAM wParam, LPARAM lParam)
{
	CString SUB_HEAD;
	CString NETWORK_NO;
	CString PLC_NO;
	CString IO_NO;
	CString STATION_NO;
	CString DATA_LENGTHW;
	CString DATA_LENGTHR;
	CString CPU_WATCHDOG;
	CString W_COMMAND;
	CString R_COMMAND;
	CString SUB_COMMAND;
	CString DEVICE_CODE;
	CString DEVICE_ADDRESS;
	CString DEVICE_ADDRESSR;
	CString DATA_COUNTW;
	CString DATA_COUNTR;

	SUB_HEAD = _T("5000");
	NETWORK_NO = _T("00");
	PLC_NO = _T("FF");
	IO_NO = _T("03FF");
	STATION_NO = _T("00");
	DATA_LENGTHR = _T("0018");
	CPU_WATCHDOG = _T("0010");
	R_COMMAND = _T("0401");
	SUB_COMMAND = _T("0000");
	DEVICE_CODE = _T("D*");	
	DEVICE_ADDRESSR = _T("000100");	
	DATA_COUNTR = _T("0011");

	CString str = SUB_HEAD + NETWORK_NO + PLC_NO + IO_NO + STATION_NO + DATA_LENGTHR + CPU_WATCHDOG + R_COMMAND + SUB_COMMAND
		+ DEVICE_CODE + DEVICE_ADDRESSR + DATA_COUNTR;

	int send = str.GetLength();
	if (send <= 0) return false;
	
	if (m_bSockConnect4)
		send = m_pClient4->Send(str, send);	

	return 0L;
}

문서 : 

delphi.borlandforum.com/impboard/attach/0000148028/Q%EB%8C%80%EC%9D%91%20MELSEC%20%EC%BB%A4%EB%AE%A4%EB%8B%88%EC%BC%80%EC%9D%B4%EC%85%98%20%ED%94%84%EB%A1%9C%ED%86%A0%EC%BD%9C%20%EB%A0%88%ED%8D%BC%EB%9F%B0%EC%8A%A4%20%EB%A7%A4%EB%89%B4%EC%96%BC.pdf

다운이 안될 시 댓글에 이메일 남겨두세요.

 

내용을 좀 추출해보고 위에 있는 코드를 분석해보자

 

58페이지.

 

(a) ASCII 코드로 교신할 경우 

1. 상대기기가 자국 PLC CPU의 데이터를 읽는 경우 

2. 상대기기 자국 PLC CPU의 데이터를 쓰는 경우

즉 위에 있는 두 개를 비교해 본 결과 위의 코드를 분석해보자면


	// 메뉴얼에 나와있는 대로 작성 -> page 60
	SUB_HEAD = _T("5000");
	NETWORK_NO = _T("00");
	PLC_NO = _T("FF");
	IO_NO = _T("03FF");
	STATION_NO = _T("00");
	DATA_LENGTHR = _T("0018");
	CPU_WATCHDOG = _T("0010");
	// 여기서부터 커맨드
	R_COMMAND = _T("0401");		// 일괄 읽기
	// 서브 커맨드
	SUB_COMMAND = _T("0000");	// WORD 형 DATA
	// 요구 데이터 부 
	DEVICE_CODE = _T("D*");		// 메모리 D에서부터 
	DEVICE_ADDRESSR = _T("000100");		//주소 100부터
	DATA_COUNTR = _T("0011");		// 16진수로 17개 요구

void CMFCApplication1Dlg::WinsockReceive4(CWinsockClient4* pClient4)
{
	int         nSize = 0;
	_u8         pBuf4[1024] = { 0x00 };
	CString		strPacket;
	CString     filename;
	CString     str;

	nSize = pClient4->Receive(&pBuf4, 1024);	// 디버그 집는 부분

	if (nSize == 0)
	{
		return;
	}	
	else if (nSize == 90)
	{
		memcpy(&recv4_buf500, pBuf4, nSize);
		for (int ii = 0; ii< 90; ii++)
		{		
			str += (BYTE)recv4_buf500[ii];
		}
		
		Proc4(str);		// 디버그 집는 부분
		OnDataSave4();

		memset(&recv4_buf500, 0x00, 1024);
	}
	else   // if (nSize == SOCKET_ERROR)    // 소켓 오류시 발생 
	{
		m_ListLog4.InsertString(0, _T("수신오류 > 전문 수신중 오류가 발생하여 접속을 종료합니다."));
		SendMessage(WM_USER_WINSOCK_CLOSE3, 0, 0);
	}
	strPacket.Format(" 수신 사이즈 %d", nSize);
	if (m_ListLog4.GetCount() > 500)
	{
		m_ListLog4.ResetContent();
	}
	m_ListLog4.InsertString(0, strPacket);
	EventLog(strPacket);	
}

 

문론 나는 PLC에 어떠한 것도 저장해두지 않아서 따로 들어오는 데이터 값은 없지만 오류 없이 0값을 받아오는 것을 확인해볼 수 있었다. 

'데이터 > PLC' 카테고리의 다른 글

PLC 개념, 기능  (0) 2021.02.02