问题描述
我用 C# 编写了一个用于测试产品的 WinForms 程序。目前,我正在操作机器的所有机械方面,即:将 UUT 移动到测试位置、接合测试探针等。我可以控制各个方面,这就是我进行测试序列的方式。
我正在使用 NI DAQ 和一些定制的 PCB,我在 SerialPort 上通过 UART 与 UUT 进行通信,我正在将一些数据收集到数据库中。
现在,我需要引进一个新世代。由PLC操作的机器,所以我的工作会更容易; PLC 将设置一切,然后我将与 PLC 通信以进行测试。我需要通过 TCP/IP 与 PLC 通信。
通过 TCP/IP 与 PLC 通信会涉及什么?显然我必须设置一个服务器,与 PLC 建立连接,并开发一些通信协议,这样我才能在我的屏幕上更新测试步骤等等。我从来没有做过任何 TCP/IP 通信。之前。
如果有帮助,那就是 omron PLC NX1P2,他们希望我重新使用他们在另一台机器上开发的协议,该协议与 LabVIEW 和 TestStand 交互。
这是他们用 StructuredText 写的;它在 PLC 上运行:
// Start sequence when Trigger changes to TRUE.
IF ( (Enable=TRUE) AND (DoTCP=FALSE) AND (_Eip_EtnOnlinesta=TRUE) ) THEN
DoTCP:=TRUE;
IF (TCP_Conn_Status = _CLOSED) OR (TCP_Conn_Status = _CLOSE_WAIT) OR (TCP_Conn_Status = _CLOSING) THEN //(TCP_Conn_Status <> _ESTABLISHED) THEN
Stage := 1; //try connect if not estabilished yet
ELSE
Stage:=2; //only check status,avoid open another port and lose sync.
END_IF;
SktTCPConnect_instance(Execute:=FALSE); // Initialize instance.
SktClearBuf_instance(Execute:=FALSE); // Initialize instance.
SktGetTcpstatus_instance(Execute:=FALSE); // Initialize instance.
SktTcpsend_instance( // Initialize instance.
Execute:=FALSE,SendDat:= dummy_dat[0]); // Dummy
SktTCPRcv_instance( // Initialize instance.
Execute:=FALSE,RcvDat :=dummy_dat[0]); // Dummy
SktClose_instance(Execute:=FALSE); // Initialize instance.
END_IF;
IF (DoTCP=TRUE) THEN
CASE Stage OF
1: // Request a connection.
SktTCPConnect_instance(
Execute :=TRUE,SrcTcpPort:=UINT#0,// Local TCP port number: Automatically assigned.
DstAdr :=IP_Address,// Remote IP address
DstTcpPort:=Remote_Port,// Destination TCP port number
Socket =>TCP_Conn_WkSocket); // Socket
IF (SktTCPConnect_instance.Done=TRUE) THEN
Stage:=INT#2; //check TCP status
ELSIF (SktTCPConnect_instance.Error=TRUE) THEN
error_ID := (SktTCPConnect_instance.ErrorID);
//TCP_Conn_Status := _CLOSED;
IF (error_ID = WORD#16#2008) THEN //never lock error to else state
Stage:=INT#6; //errorID=2008 - Socket Communications Resource Overflow
ELSE
Stage:=INT#2; // always check TCP status
END_IF;
END_IF;
2: //request status
SktGetTcpstatus_instance(
Execute:=TRUE,Socket :=TCP_Conn_WkSocket); // Socket
IF (SktGetTcpstatus_instance.Done) THEN
TCP_Conn_Status := SktGetTcpstatus_instance.Tcpstatus;
IF (TCP_Conn_Status <> _ESTABLISHED) THEN //(TCP_Conn_Status = _CLOSED) OR (TCP_Conn_Status = _CLOSE_WAIT) OR (TCP_Conn_Status = _CLOSING) THEN
Stage:=INT#0; //go to end
ELSE
Stage:=INT#3; //continue normal flow
END_IF;
ELSIF (SktGetTcpstatus_instance.Error=TRUE) THEN
error_ID:=(SktGetTcpstatus_instance.ErrorID);
Stage:=INT#20; // Error end
END_IF;
3: // sending message
Payload_local:= Payload_Client_IN;
Msg_size_byte := CRC_size_byte + ToAryByte(Payload_local,_LOW_HIGH,SendSocketDat[0]) + UINT#2; ////payload size + CRC (bytes)
Msg_size:= ToAryByte(Msg_size_byte,SendSocketDat[0]); //replace first two bytes with payload + CRC size
Msg_size_byte :=ToAryByte(Payload_local,SendSocketDat[2]); //replace rest of the array with palyload as bytes
Payload_CRC_send := AryCRCCCITT(SendSocketDat[0],(Msg_size_byte+Msg_size),WORD#0,_LOW_HIGH); //calculates (size +payload) CRC
Msg_size_CRC :=ToAryByte(Payload_CRC_send,SendSocketDat[Msg_size_byte+Msg_size]); //append CRC as bytes to the end of the array
SktTcpsend_instance(
Execute:=TRUE,Socket :=TCP_Conn_WkSocket,// Socket
SendDat:= SendSocketDat[0],// TCP_Message_Send[0],// Send data
Size := Msg_size_byte+Msg_size+Msg_size_CRC); // msg payload + payload size + CRC 16
IF (SktTcpsend_instance.Done=TRUE) THEN
Stage:=INT#4; // go to read buffer
SktTcpsend_instance( // reinitialize instance.
Execute:=FALSE,SendDat:= dummy_dat[0]);
SktTCPRcv_instance( //reset instance
Execute:=FALSE,RcvDat :=dummy_dat[0]);
ELSIF (SktTcpsend_instance.Error=TRUE) THEN
error_ID:=( SktTcpsend_instance.ErrorID);
IF (error_ID = WORD#16#2006) THEN // OR error_ID = WORD#16#2003) THEN
Stage:=INT#5; // time out - clear buffer only
ELSE
Stage:=INT#30; // Error end
END_IF;
END_IF;
4: // Request receiving message size only
SktTCPRcv_instance(
Execute:=TRUE,// Socket
TimeOut:=UINT#10,// Timeout time: 1 x (0.1 sec)
Size :=UINT#2,// Receive data size
RcvDat := RcvSocketDat[0]); // Receive data
IF (SktTCPRcv_instance.Done=TRUE) THEN
Stage:=INT#41; // normal end
SktTCPRcv_instance( //reset instance
Execute:=FALSE,RcvDat :=dummy_dat[0]);
ELSIF (SktTCPRcv_instance.Error=TRUE) THEN
error_ID:=(SktTCPRcv_instance.ErrorID);
IF (error_ID = WORD#16#2006) THEN // OR error_ID = WORD#16#2003) THEN
Stage:=INT#5; // time out - clear buffer only
ELSE
Stage:=INT#40;
END_IF;
END_IF;
41: // Request receiving payload
AryByteto (RcvSocketDat[0],UINT#2,Msg_size_byte_send); //convert byte array to message size
SktTCPRcv_instance(
Execute:=TRUE,// Timeout time 10 x 0.1s - 1sec
Size :=Msg_size_byte_send,// Receive data size
RcvDat := RcvSocketDat[2]); // Receive data
IF (SktTCPRcv_instance.Done=TRUE) THEN
Stage:=INT#5; // normal end
Payload_CRC_receive_recalc:= AryCRCCCITT(RcvSocketDat[0],Msg_size_byte_send,_LOW_HIGH); //calculate CRC from received message (add size,but exclude CRC on the payload)
AryByteto(RcvSocketDat[Msg_size_byte_send],Payload_CRC_receive);
IF (Payload_CRC_receive = Payload_CRC_receive_recalc) then
payload_received:=AryByteto(RcvSocketDat[2],Msg_size_byte_send - UINT#2,Payload_Server_OUT); //convert array of bytes to dta type,excluding msg size and CRC
END_IF;
ELSIF (SktTCPRcv_instance.Error=TRUE) THEN
error_ID:=(SktTCPRcv_instance.ErrorID);
IF (error_ID = WORD#16#2006) THEN // OR error_ID = WORD#16#2003) THEN
Stage:=INT#5; // time out - clear buffer only
ELSE
Stage:=INT#410;
END_IF;
END_IF;
5: // Clear receive buffer.
SktClearBuf_instance(
Execute:=TRUE,Socket :=TCP_Conn_WkSocket); // Socket
IF (SktClearBuf_instance.Done=TRUE) THEN
Stage:=INT#0; // check connection
ELSIF (SktClearBuf_instance.Error=TRUE) THEN
error_ID:=(SktClearBuf_instance.ErrorID);
Stage:=INT#50; // Error end
END_IF;
6: // Request closing.
SktClose_instance(
Execute:=TRUE,Socket :=TCP_Conn_WkSocket); // Socket
IF (SktClose_instance.Done=TRUE) THEN
Stage:=INT#0; // normal end
TCP_Conn_Status:= _CLOSED;
ELSIF (SktClose_instance.Error=TRUE) THEN
error_ID:=(SktClose_instance.ErrorID);
IF (SktClose_instance.ErrorID = WORD#16#2007) THEN//errrorID = 2007 --> Socket Handle Out of Range(closed)
Stage:=0;
//TCP_Conn_Status:= _CLOSED;
ELSE
Stage:=INT#60; // Error end
END_IF;
END_IF;
0: // normal end
DoTCP :=FALSE;
Done:= TRUE;
SktTcpsend_instance( // reinitialize instance.
Execute:=FALSE,SendDat:= dummy_dat[0]);
SktTCPRcv_instance( //reset instance
Execute:=FALSE,RcvDat :=dummy_dat[0]);
ELSE // Interrupted by error.
IF (error_ID = WORD#16#2003 OR error_ID = WORD#16#2008) THEN //Socket Status Error
//Stage:=UINT#2; //force reopen
//error_ID:=WORD#16#0;
TCP_Conn_Status:= _CLOSED;
//TCP_Conn_Status:= TCP_Conn_Status;
END_IF;
DoTCP :=FALSE;//use FALSE to reset states,use TRUE to trap error during debug
Done := FALSE;
SktTcpsend_instance( // reinitialize instance.
Execute:=FALSE,RcvDat :=dummy_dat[0]);
//END_IF;
END_CASE;
END_IF;
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)