PLC通讯实现-C#实现三菱PLC通讯(三)

PLC通讯实现-C#实现三菱PLC通讯MXComponent(三)

背景

本人近十年的工作都与工业软件相关、其中工控系统开发过程中有一个必要环节就是跟各大厂商的PLC进行通讯,而对于从互联网行业跨入工业互联网行业的从业人员来说要实现各型号PLC通讯还是需要一个过程的,本人在此对主流型号PLC通讯实现进行总结以便大家参考。

抽象设计

首先我们要进行一下抽象设计,先设计一个抽象类(接口也可以,此处因为还有其他业务使用了抽象类)BaseEquip,对PLC的常规操作进行定义,即Open、Read、Write、Close,业务代码调用BaseEquip进行PLC的读写,然后在实现各型号的Equip类,对Open、Read、Write、Close进行实现,根据配置在业务代码中对BaseEquip进行实例化,这样后期更改PLC型号后,只需修改配置即可,不用修改业务代码。

三菱PLC通讯实现MXComponent

实现语言C#

安装MxComponent通讯组件,并在MxComponent通讯组件中根据向导创建逻辑站。在C#通讯项目中增加对ACTMULTLib的引用,如果没有安装MxComponent则不能引用。

抽象基类BaseEquip

已标记关键词 清除标记
以下代码是用C++和PLC通信,但是我看不懂C++,能帮我把这段代码用C#的形式写出来吗? 或者有能直接和PLC网络通信的C#源码,感谢各位高手,谢谢,非常感谢~~~ ------------------------------------------------------------------------ #include "stdafx.h" #include "SensorMounter.h" #include "SocketThread.h" IMPLEMENT_DYNCREATE(CSocketThread, CWinThread) CSocketThread::CSocketThread() : m_sIPAddress(_T("")) { m_nSocketPort = 0; m_bConnected = FALSE; m_nWtmE1 = 0; } CSocketThread::~CSocketThread() { } BOOL CSocketThread::InitInstance() return TRUE; } int CSocketThread::ExitInstance() { return CWinThread::ExitInstance(); } BEGIN_MESSAGE_MAP(CSocketThread, CWinThread) ON_THREAD_MESSAGE(WMU_SOCKET_CONNECT, OnSConnect) ON_THREAD_MESSAGE(WMU_SOCKET_SEND, OnSSend) ON_THREAD_MESSAGE(WMU_SOCKET_RECV, OnSRecv) ON_THREAD_MESSAGE(WMU_SOCKET_CLOSE, OnSClose) ON_THREAD_MESSAGE(WMU_SOCKET_QUIT, OnSQuit) END_MESSAGE_MAP() void CSocketThread::OnSConnect(UINT wParam, LONG lParam) { TRACE("CSocketThread::OnSConnect: start\n"); BOOL bRC = SocketConnect(); _ST_SEND *pSend = (_ST_SEND *)wParam; if (!pSend) return; pSend->nDoneSize = (bRC ? 0 : -1); if (pSend->hwndDone) ::SendMessage(pSend->hwndDone, WMU_SOCKET_DONE, (WPARAM)pSend, (LPARAM)pSend->nDoneSize); if (pSend->hEvDone) SetEvent(pSend->hEvDone); } void CSocketThread::OnSSend(UINT wParam, LONG lParam) { TRACE("CSocketThread::OnSSend: start\n"); _ST_SEND *pSend = (_ST_SEND *)wParam; if (!pSend) return; if (!m_bConnected) { pSend->nDoneSize = -1; if (pSend->hwndDone) ::SendMessage(pSend->hwndDone, WMU_SOCKET_DONE, (WPARAM)pSend, (LPARAM)(-1)); if (pSend->hEvDone) SetEvent(pSend->hEvDone); return; } pSend->nDoneSize = 0; switch (pSend->nDataType) { case _ST_DATA: pSend->nDoneSize = SocketSendData(pSend->nAddr, *((WORD *)pSend->pData), pSend->bDebugDisp); break; case _ST_MULTIBYTE: pSend->nDoneSize = SocketSendMultiByte(pSend->nSize, pSend->nAddr, pSend->pData, pSend->bDebugDisp); break; case _ST_MULTIWORD: pSend->nDoneSize = SocketSendMultiWord(pSend->nSize, pSend->nAddr, (WORD *)pSend->pData, pSend->bDebugDisp); break; case _ST_MULTIBYTE_BIN: pSend->nDoneSize = SocketBinSendMultiByte(pSend->nSize, pSend->nAddr, pSend->pData, pSend->bDebugDisp); break; case _ST_MULTIWORD_BIN: pSend->nDoneSize = SocketBinSendMultiWord(pSend->nSize, pSend->nAddr, (WORD *)pSend->pData, pSend->bDebugDisp); break; default: break; } if (pSend->hwndDone) ::SendMessage(pSend->hwndDone, WMU_SOCKET_DONE, (WPARAM)pSend, (LPARAM)(pSend->nDoneSize)); if (pSend->hEvDone) SetEvent(pSend->hEvDone); } void CSocketThread::OnSRecv(UINT wParam, LONG lParam) { _ST_SEND *pSend = (_ST_SEND *)wParam; if (!pSend) return; if (!m_bConnected) { pSend->nDoneSize = -1; if (pSend->hwndDone) ::SendMessage(pSend->hwndDone, WMU_SOCKET_DONE, (WPARAM)pSend, (LPARAM)(-1)); if (pSend->hEvDone) SetEvent(pSend->hEvDone); return; } BOOL bRC; switch (pSend->nDataType) { case _ST_DATA: bRC = SocketReceiveData(pSend->nAddr, (WORD *)pSend->pData, pSend->bDebugDisp); pSend->nDoneSize = (bRC ? sizeof(WORD) : 0); break; case _ST_MULTIBYTE: break; case _ST_MULTIWORD: bRC = SocketReceiveMultiWord(pSend->nSize, pSend->nAddr, (WORD *)pSend->pData, pSend->bDebugDisp); pSend->nDoneSize = (bRC ? pSend->nSize : 0); break; case _ST_MULTIWORD_BIN: bRC = SocketBinReceiveMultiWord(pSend->nSize, pSend->nAddr, (WORD *)pSend->pData, pSend->bDebugDisp); pSend->nDoneSize = (bRC ? pSend->nSize : 0); break; default: break; } if (pSend->hwndDone) ::SendMessage(pSend->hwndDone, WMU_SOCKET_DONE, (WPARAM)pSend, (LPARAM)(pSend->nDoneSize)); if (pSend->hEvDone) SetEvent(pSend->hEvDone); } void CSocketThread::OnSClose(UINT wParam, LONG lParam) { TRACE("CSocketThread::OnSClose: start\n"); SocketDisconnect(); } void CSocketThread::OnSQuit(UINT wParam, LONG lParam) { TRACE("CSocketThread::OnSQuit: start"); // AfxEndThread(0); ::PostQuitMessage(0); } BOOL CSocketThread::SocketConnect() { BOOL bRet; bRet = m_SW.Socket(m_nSocketPort); if (!bRet) { CString msg; msg.Format("[NG] port:%d code = %d:%d", m_nSocketPort, m_SW.m_nErrorCode, m_SW.m_nLastError); MessageBox(NULL, (LPCTSTR)msg, _T("CSocketThread::SocketConnect: Connect"), MB_ICONERROR); return (m_bConnected = FALSE); } bRet = m_SW.Connect((LPCTSTR)m_sIPAddress); if (!bRet) { CString msg; msg.Format("[NG] Host Connect Error \n HostName:%s code = %d:%d", (LPCTSTR)m_sIPAddress, m_SW.m_nErrorCode, m_SW.m_nLastError); MessageBox(NULL, (LPCTSTR)msg, _T("CSocketThread::SocketConnect: Connect"), MB_ICONERROR); return (m_bConnected = FALSE); } return (m_bConnected = TRUE); } BOOL CSocketThread::SocketBinSendMultiByte(int nDataNum, UINT nAddress, BYTE ucData[], BOOL bDebugDisp) { BYTE pSendBuf[37] = { 0x50, 0x00, 0x00, 0xFF, 0xFF, 0x03, 0x00, 0xCC, 0xCC, 0x10, 0x00, 0x01, 0x14, 0x01, 0x00, 0xCC, 0xCC, 0xCC, 0x90, 0xCC, 0xCC, 0xD1, 0xD1, 0xD1, 0xD1, 0xD2, 0xD2, 0xD2, 0xD2, 0xD3, 0xD3, 0xD3, 0xD3, 0xD4, 0xD4, 0xD4, 0xD4 }; WORD wDataLength = 12 + nDataNum*4; DWORD dwDeviceAddr = nAddress + (0x90<<24); WORD wDeviceNum = nDataNum*8; memcpy( &pSendBuf[7], &wDataLength, 2); memcpy( &pSendBuf[15], &dwDeviceAddr, 4); memcpy( &pSendBuf[19], &wDeviceNum, 2); BYTE pBuf[4]; for (int i=0; i<nDataNum; i++) { for (int j=0; j<4; j++) { pBuf[j] = 0x00; if( (ucData[i]&(0x01<<j*2)) ) pBuf[j] |= 0x10; if( (ucData[i]&(0x01<<(j*2+1))) ) pBuf[j] |= 0x01; } memcpy( &pSendBuf[21+i*4], &pBuf, 4); } int nSend = m_SW.SendBin( pSendBuf, 21+nDataNum*4 ); if (nSend < 0) { SocketDispErrorCode(_T("SendMultiByte(send)")); return FALSE; } if(m_nWtmE1 > 0) Sleep(m_nWtmE1); BYTE pReceiveBuf[11]; long nReceive = m_SW.ReadBin( pReceiveBuf, 11); if ( nReceive < 1 ) { SocketDispErrorCode(_T("SendMultiByte(receive)")); return FALSE; } if ( pReceiveBuf[0]==0xD0 && pReceiveBuf[1]==0x00 && pReceiveBuf[2]==0x00 && pReceiveBuf[3]==0xFF && pReceiveBuf[4]==0xFF && pReceiveBuf[5]==0x03 && pReceiveBuf[9]==0x00 && pReceiveBuf[10]==0x00 ) { if(pReceiveBuf[7]==2) return TRUE; else if(pReceiveBuf[7]==0) return FALSE; } nReceive = m_SW.ReadBin( pReceiveBuf, pReceiveBuf[7]-2); if ( nReceive < 1 ) { SocketDispErrorCode(_T("SendMultiByte(receive)")); return FALSE; } return TRUE; } BOOL CSocketThread::SocketBinSendMultiWord(int nDataNum, UINT nAddress, WORD wData[], BOOL bDebugDisp) { BYTE pSendBuf[33] = { 0x50, 0x00, 0x00, 0xFF, 0xFF, 0x03, 0x00, 0xCC, 0xCC, 0x10, 0x00, 0x01, 0x14, 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xA8, 0xCC, 0xCC, 0xD1, 0xD1, 0xD2, 0xD2, 0xD3, 0xD3, 0xD4, 0xD4, 0xD5, 0xD5, 0xD6, 0xD6 }; WORD wDataLength = 12+nDataNum*2; DWORD dwDeviceAddr = nAddress + (0xA8<<24); WORD wDeviceNum = nDataNum; memcpy( &pSendBuf[7], &wDataLength, 2); memcpy( &pSendBuf[15], &dwDeviceAddr, 4); memcpy( &pSendBuf[19], &wDeviceNum, 2); memcpy( &pSendBuf[21], &wData, nDataNum); for (int i=0; i<nDataNum; i++){ pSendBuf[22+i*2] = (wData[i]&0xFF00)>>8; pSendBuf[21+i*2] = wData[i]&0x00FF; } int nSend = m_SW.SendBin( pSendBuf, 21+nDataNum*2 ); if (nSend < 0) { SocketDispErrorCode(_T("SendMultiWord(send)")); return FALSE; } if(m_nWtmE1 > 0) Sleep(m_nWtmE1); BYTE pReceiveBuf[11]; long nReceive = m_SW.ReadBin( pReceiveBuf, 11); if ( nReceive < 1 ) { SocketDispErrorCode(_T("SendMultiWord(receive)")); return FALSE; } if ( pReceiveBuf[0]==0xD0 && pReceiveBuf[1]==0x00 && pReceiveBuf[2]==0x00 && pReceiveBuf[3]==0xFF && pReceiveBuf[4]==0xFF && pReceiveBuf[5]==0x03 && pReceiveBuf[9]==0x00 && pReceiveBuf[10]==0x00 ) { if (pReceiveBuf[7]==2) return TRUE; else if (pReceiveBuf[7]==0) return FALSE; } nReceive = m_SW.ReadBin( pReceiveBuf, pReceiveBuf[7]-2); if ( nReceive < 1 ) { SocketDispErrorCode(_T("SendMultiByte(receive)")); return FALSE; } return TRUE; } BOOL CSocketThread::SocketBinReceiveMultiWord(int nDataNum, UINT nAddress, WORD wData[], BOOL bDeviceCode) { BYTE pSendBuf[21] = { 0x50, 0x00, 0x00, 0xFF, 0xFF, 0x03, 0x00, 0xCC, 0xCC, 0x10, 0x00, 0x01, 0x04, 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x90, 0xCC, 0xCC }; WORD wDataLength = 12; DWORD dwDeviceAddr; if (bDeviceCode==FALSE) dwDeviceAddr = nAddress+(0x90<<24); else dwDeviceAddr = nAddress+(0xA8<<24); WORD wDeviceNum = nDataNum; memcpy( &pSendBuf[7], &wDataLength, 2); memcpy( &pSendBuf[15], &dwDeviceAddr, 4); memcpy( &pSendBuf[19], &wDeviceNum, 2); int nSend = m_SW.SendBin( pSendBuf, 21 ); if (nSend < 0) { SocketDispErrorCode(_T("SendMultiWord(send)")); return FALSE; } if(m_nWtmE1 > 0) Sleep(m_nWtmE1); BYTE pReceiveBuf[21]; int nReadLength; for (int i=0; i<21; i++) pReceiveBuf[i] = 0; long nReceive = m_SW.ReadBin( pReceiveBuf, 11); if ( nReceive < 1 ) { SocketDispErrorCode(_T("SendMultiWord(receive)")); return FALSE; } if ( pReceiveBuf[0]==0xD0 && pReceiveBuf[1]==0x00 && pReceiveBuf[2]==0x00 && pReceiveBuf[3]==0xFF && pReceiveBuf[4]==0xFF && pReceiveBuf[5]==0x03 && pReceiveBuf[9]==0x00 && pReceiveBuf[10]==0x00 ) { if(pReceiveBuf[7]==0 || pReceiveBuf[7]==2 ) return FALSE; else nReadLength = pReceiveBuf[7]-2; } else { return FALSE; } for (int i=0; i<21; i++) pReceiveBuf[i] = 0; nReceive = m_SW.ReadBin( pReceiveBuf, nReadLength); if ( nReceive < 1 ) { SocketDispErrorCode(_T("SendMultiByte(receive)")); return FALSE; } else { for(int i=0; i<nDataNum; i++) wData[i] = pReceiveBuf[2*i] + (pReceiveBuf[2*i+1]<<8); return TRUE; } } BOOL CSocketThread::SocketDisconnect(void) { return m_SW.Shutdown(); } void CSocketThread::SocketDispErrorCode(LPCTSTR strFunc) { CString strCode, strMsg; switch (m_SW.m_nErrorCode) { case 101: strCode="IDP_SOCKETS_INIT_FAILED"; break; case 1201: strCode="SW_ERR_NOERROR"; break; case 1202: strCode="SW_ERR_WSASTARTUP"; break; case 1203: strCode="SW_ERR_GETSERV"; break; case 1204: strCode="SW_ERR_GETHOSTNAME"; break; case 1205: strCode="SW_ERR_GETHOSTENT"; break; case 1206: strCode="SW_ERR_SOCK_STREAM"; break; case 1207: strCode="SW_ERR_BIND"; break; case 1208: strCode="SW_ERR_LISTEN"; break; case 1209: strCode="SW_ERR_ACCEPTTHREAD"; break; case 1210: strCode="SW_ERR_BUFFER_OVER"; break; case 1211: strCode="SW_ERR_READ"; break; case 1212: strCode="SW_ERR_SEND"; break; case 1213: strCode="SW_ERR_CONNECT"; break; case 1214: strCode="SW_ERR_ACCEPT"; break; case 1215: strCode="SW_ERR_RESUME_FAIL"; break; case 1216: strCode="SW_CONNECT_CLOSED"; break; } strMsg.Format(" Function : %s \n ErrorCode : %s \n LastError : %d", strFunc, strCode, m_SW.m_nLastError); MessageBox(NULL, (LPCTSTR)strMsg, _T("CSocketThread::SocketDispErrorCode"), MB_ICONERROR); }
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页