From c78c3c6f283b8f3e28a7c12fda98e7d0337dec23 Mon Sep 17 00:00:00 2001 From: TAO Cheng Date: Wed, 12 Nov 2014 15:40:40 +0800 Subject: [PATCH] TCPIP SERVER --- .../Msi/Hsi/SevenOcean/So7_TCPIP_Server.cpp | 114 ++++++++++-------- .../Msi/Hsi/SevenOcean/So7_TCPIP_Server.h | 16 ++- .../UsbUtil/So7_Util_PLC_TCPIP_SERVER.cpp | 53 +++++++- .../UsbUtil/So7_Util_PLC_TCPIP_SERVER.h | 2 + .../Hsi/Tools/UsbUtility/UsbUtil_VS2010.suo | Bin 156160 -> 156160 bytes 5 files changed, 125 insertions(+), 60 deletions(-) diff --git a/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/So7_TCPIP_Server.cpp b/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/So7_TCPIP_Server.cpp index 58e76b6..e2935e7 100644 --- a/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/So7_TCPIP_Server.cpp +++ b/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/So7_TCPIP_Server.cpp @@ -62,10 +62,12 @@ CSo7_TCPIP_Server::CSo7_TCPIP_Server() m_TCPIPBuf[i]._hProtoPending = false; m_TCPIPBuf[i]._event = NULL; }; - for(int i=0;i=MAX_DM_PAGE_NUMBER) { - m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexData+2*i]=(iData>>8) & 0x0ff; - m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexData+2*i+1]=iData & 0x0ff; + _DataSize=MAX_DM_PAGE_NUMBER-_StartAddr; + } + for (int i=0;i<_DataSize;i++) + { + sData=DM5000[_StartAddr+i]; + m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexData+2*i]=(sData>>8) & 0x0ff; + m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexData+2*i+1]=sData & 0x0ff; } - m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexDataSize]=static_cast(DRW_SDataIndexData-DRW_SDataHeadDataSize+_datasize); - m_TCPIPBuf[CH_SEND]._size=DRW_SDataIndexData+_datasize*2; + m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexDataSize]=static_cast(DRW_SDataIndexData-DRW_SDataHeadDataSize+_DataSize); + m_TCPIPBuf[CH_SEND]._size=DRW_SDataIndexData+_DataSize*2; SendBuffer(); return TRUE; } //================================================================ -BOOL CSo7_TCPIP_Server::Response_Sensor_State(short _datasize) +BOOL CSo7_TCPIP_Server::Response_PLC_DM10000_R(short _StartAddr,short _DataSize) { if(m_ClientSocket[m_nActiveClient] == INVALID_SOCKET) { @@ -335,19 +343,28 @@ BOOL CSo7_TCPIP_Server::Response_Sensor_State(short _datasize) m_ClearSendBuf(); memcpy(m_TCPIPBuf[CH_SEND]._buffer,DRW_SData,sizeof(DRW_SData)); - for (int i=0;i<_datasize;i++) + short sData(0); + _StartAddr-=10000; + if ((_StartAddr+_DataSize)>=MAX_DM_PAGE_NUMBER) { - m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexData+i]=m_TCPIPServerState._PLCSensorState[i]; + _DataSize=MAX_DM_PAGE_NUMBER-_StartAddr; + } + for (int i=0;i<_DataSize;i++) + { + sData=DM10000[_StartAddr+i]; + m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexData+2*i]=(sData>>8) & 0x0ff; + m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexData+2*i+1]=sData & 0x0ff; } - m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexDataSize]=static_cast(DRW_SDataIndexData-DRW_SDataHeadDataSize+_datasize); - m_TCPIPBuf[CH_SEND]._size=DRW_SDataIndexData+_datasize*2; + m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexDataSize]=static_cast(DRW_SDataIndexData-DRW_SDataHeadDataSize+_DataSize); + + m_TCPIPBuf[CH_SEND]._size=DRW_SDataIndexData+_DataSize*2; SendBuffer(); + return TRUE; - } //================================================================ -BOOL CSo7_TCPIP_Server::Response_CCD_DATA(short _Addr,short _datasize) +BOOL CSo7_TCPIP_Server::Response_PLC_DM8000_W(short _StartAddr,short _DataSize) { if(m_ClientSocket[m_nActiveClient] == INVALID_SOCKET) { @@ -355,27 +372,26 @@ BOOL CSo7_TCPIP_Server::Response_CCD_DATA(short _Addr,short _datasize) } m_ClearSendBuf(); memcpy(m_TCPIPBuf[CH_SEND]._buffer,DRW_SData,sizeof(DRW_SData)); - - int iData(0); - BYTE DM_Data[4]={0,0,0,0}; - for (int i=0;i<_datasize;i++) + short sData(0); + _StartAddr-=8000; + if ((_StartAddr+_DataSize)>=MAX_DM_PAGE_NUMBER) { - iData=m_CCDData_D10000[_Addr+i/2]; - DM_Data[2]=(iData>>24) & 0x0ff; - DM_Data[3]=(iData>>16) & 0x0ff; - DM_Data[0]=(iData>>8) & 0x0ff; - DM_Data[1]=iData & 0x0ff; - m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexData+2*i]=DM_Data[2*(i%2)+0]; - m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexData+2*i+1]=DM_Data[2*(i%2)+1]; + _DataSize=MAX_DM_PAGE_NUMBER-_StartAddr; + } + for (int i=0;i<_DataSize;i++) + { + sData=DM8000[_StartAddr+i]; + m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexData+2*i]=(sData>>8) & 0x0ff; + m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexData+2*i+1]=sData & 0x0ff; } - m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexDataSize]=static_cast(DRW_SDataIndexData-DRW_SDataHeadDataSize+_datasize); - - m_TCPIPBuf[CH_SEND]._size=DRW_SDataIndexData+_datasize*2; + m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexDataSize]=static_cast(DRW_SDataIndexData-DRW_SDataHeadDataSize+_DataSize); + m_TCPIPBuf[CH_SEND]._size=DRW_SDataIndexData+_DataSize*2; SendBuffer(); - return TRUE; + } + //================================================================ BOOL CSo7_TCPIP_Server::_Send_Cmd_Write_State() { @@ -570,8 +586,8 @@ void CSo7_TCPIP_Server::m_ProcessSocketReadEvent(SOCKET s) bData[0]=m_TCPIPBuf[CH_RECV]._buffer[DRW_RDataIndexAddr1]; bData[1]=m_TCPIPBuf[CH_RECV]._buffer[DRW_RDataIndexAddr2]; iAddr=(bData[0]<<8)+bData[1]; - bData[0]=m_TCPIPBuf[CH_RECV]._buffer[DRW_RDataIndexAddr1]; - bData[1]=m_TCPIPBuf[CH_RECV]._buffer[DRW_RDataIndexAddr2]; + bData[0]=m_TCPIPBuf[CH_RECV]._buffer[DRW_RDataIndexCh1]; + bData[1]=m_TCPIPBuf[CH_RECV]._buffer[DRW_RDataIndexCh2]; iDataSize=(bData[0]<<8)+bData[1]; if (iAddr>=20000) @@ -580,17 +596,17 @@ void CSo7_TCPIP_Server::m_ProcessSocketReadEvent(SOCKET s) } else if (iAddr>=10000) { - Response_CCD_DATA((iAddr-10060),iDataSize); + Response_PLC_DM10000_R(iAddr,iDataSize); iPara=RESPONSE_READ_CCD_DATA; } else if (iAddr>=5000) { - Response_PLC_State(1); + Response_PLC_DM5000_R(iAddr,iDataSize); iPara=RESPONSE_READ_PLC_STATE; } else { - RESPONSE_UNKNOWN_State(); + RESPONSE_PLC_DM_UNKNOWN(); iPara=RESPONSE_UNKNOWN; } } @@ -603,17 +619,17 @@ void CSo7_TCPIP_Server::m_ProcessSocketReadEvent(SOCKET s) bData[0]=m_TCPIPBuf[CH_RECV]._buffer[DRW_RDataIndexAddr1]; bData[1]=m_TCPIPBuf[CH_RECV]._buffer[DRW_RDataIndexAddr2]; iAddr=(bData[0]<<8)+bData[1]; - bData[0]=m_TCPIPBuf[CH_RECV]._buffer[DRW_RDataIndexAddr1]; - bData[1]=m_TCPIPBuf[CH_RECV]._buffer[DRW_RDataIndexAddr2]; + bData[0]=m_TCPIPBuf[CH_RECV]._buffer[DRW_RDataIndexCh1]; + bData[1]=m_TCPIPBuf[CH_RECV]._buffer[DRW_RDataIndexCh2]; iDataSize=(bData[0]<<8)+bData[1]; if (iAddr>=8000) { - RESPONSE_UNKNOWN_State(); + RESPONSE_PLC_DM_UNKNOWN(); iPara=RESPONSE_WRITE_PLC_STATE; } else { - RESPONSE_UNKNOWN_State(); + RESPONSE_PLC_DM_UNKNOWN(); iPara=RESPONSE_UNKNOWN; } } diff --git a/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/So7_TCPIP_Server.h b/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/So7_TCPIP_Server.h index 5914097..f3042ff 100644 --- a/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/So7_TCPIP_Server.h +++ b/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/So7_TCPIP_Server.h @@ -16,6 +16,8 @@ #define PLC_MAX_SENSOR_STATE 20 #define MAX_CCD_ADDR 120 +#define MAX_DM_PAGE_NUMBER 1024 + enum OMRON_PLC_SENSOR { OMRON_PLC_CCD1_CAMERA1=0, @@ -93,17 +95,21 @@ public: static struct_so7_tcpip_buff m_TCPIPBuf[lChannelSize]; static s_tcpip_state m_TCPIPServerState; - int m_CCDData_D10000[MAX_CCD_ADDR]; + + short *DM5000; + short *DM8000; + short *DM10000; + BOOL StartServer(HWND _hWnd,short _nPort); BOOL StopServer(); BOOL _Send_Cmd_Write_State(); BOOL Response_Handshake(); - BOOL Response_PLC_State(short _datasize); - BOOL Response_Sensor_State(short _datasize); - BOOL Response_CCD_DATA(short _Addr,short _datasize); + BOOL Response_PLC_DM5000_R(short _StartAddr,short _DataSize);//PLC State + BOOL Response_PLC_DM10000_R(short _StartAddr,short _DataSize);//CCD + BOOL Response_PLC_DM8000_W(short _StartAddr,short _DataSize);//PC State - BOOL RESPONSE_UNKNOWN_State(); + BOOL RESPONSE_PLC_DM_UNKNOWN(); LRESULT OnSocket(WPARAM wParam, LPARAM lParam); private: diff --git a/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/So7_Util_PLC_TCPIP_SERVER.cpp b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/So7_Util_PLC_TCPIP_SERVER.cpp index 3b332d3..0c11358 100644 --- a/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/So7_Util_PLC_TCPIP_SERVER.cpp +++ b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/So7_Util_PLC_TCPIP_SERVER.cpp @@ -24,7 +24,10 @@ IMPLEMENT_DYNAMIC(CSo7_Util_PLC_TCPIP_SERVER, CDialog) CSo7_Util_PLC_TCPIP_SERVER::CSo7_Util_PLC_TCPIP_SERVER(CWnd* pParent /*=NULL*/) : CDialog(CSo7_Util_PLC_TCPIP_SERVER::IDD, pParent) { - + for(int i=0;iGetWindowText(str); cTempValue=T2A(str); g_pSo7_TCPIP_Server->m_TCPIPServerState._PLCRunningState=static_cast(atoi(cTempValue)); - + + BYTE DM_Data[4]={0,0,0,0}; + g_pSo7_TCPIP_Server->DM5000[0]=static_cast(g_pSo7_TCPIP_Server->m_TCPIPServerState._PLCRunningState); + for (int i=1;i<=8;i++) + { + DM_Data[0]=g_pSo7_TCPIP_Server->m_TCPIPServerState._PLCSensorState[(i-1)*2]; + DM_Data[1]=g_pSo7_TCPIP_Server->m_TCPIPServerState._PLCSensorState[(i-1)*2+1]; + g_pSo7_TCPIP_Server->DM5000[i]=(DM_Data[0]<<8)+DM_Data[1]; + } } @@ -201,11 +212,29 @@ void CSo7_Util_PLC_TCPIP_SERVER::m_UpdateListControl(int _type) { csTmp=m_DataList.GetItemText(iRow,iCol); cTmp=T2A(csTmp); - if (g_pSo7_TCPIP_Server) - { - g_pSo7_TCPIP_Server->m_CCDData_D10000[iRow]=atoi(cTmp); - } + m_CCDData_D10000[iRow]=atoi(cTmp); } + for (int iRow=0;iRow>24) & 0x0ff; + DM_Data[1]=(iData>>16) & 0x0ff; + DM_Data[2]=(iData>>8) & 0x0ff; + DM_Data[3]=iData & 0x0ff; + g_pSo7_TCPIP_Server->DM10000[StartAddr+2*i]=(DM_Data[2]<<8)+DM_Data[3]; + g_pSo7_TCPIP_Server->DM10000[StartAddr+2*i+1]=(DM_Data[0]<<8)+DM_Data[1]; + } + } + break; } default:break; @@ -224,6 +253,18 @@ void CSo7_Util_PLC_TCPIP_SERVER::OnBnClickedCancel() CDialog::OnCancel(); } //===================================================================================== +BOOL CSo7_Util_PLC_TCPIP_SERVER::PreTranslateMessage(MSG* pMsg) +{ + if(pMsg->message==WM_KEYDOWN) + { + if(pMsg->wParam==VK_RETURN || pMsg->wParam==VK_ESCAPE) + { + return TRUE; + } + } + return CDialog::PreTranslateMessage(pMsg); +} +//===================================================================================== //Print message on edit control void CSo7_Util_PLC_TCPIP_SERVER::OutputWithScroll(const CString &strNewText,CEdit &edtOutput) { diff --git a/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/So7_Util_PLC_TCPIP_SERVER.h b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/So7_Util_PLC_TCPIP_SERVER.h index ad475a5..dc865fd 100644 --- a/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/So7_Util_PLC_TCPIP_SERVER.h +++ b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/So7_Util_PLC_TCPIP_SERVER.h @@ -16,6 +16,7 @@ public: CString m_csMSG; CEdit m_edMSG; + int m_CCDData_D10000[MAX_CCD_ADDR]; protected: CEditableListCtrl m_DataList; @@ -30,6 +31,7 @@ public: afx_msg void OnBnClickedButtonPlcTcpipServerUpdatestate(); afx_msg void OnBnClickedButtonClearMsg(); afx_msg void OnBnClickedCancel(); + afx_msg BOOL PreTranslateMessage(MSG* pMsg); LRESULT OnSocket(WPARAM w, LPARAM p); diff --git a/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil_VS2010.suo b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil_VS2010.suo index 2dbd0d9803efffec9468ee0f996d5d3dc917ad2f..43d8cc7296a7c85775488531051f62c72d48b3be 100644 GIT binary patch delta 3803 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 G+kXK~^RJcw