TCP/IP .NET 与 PLC 通讯

问题描述

我用 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 (将#修改为@)