2011-08-12 1 views
2

저는 C++ 경험이 거의없는 대학생이라는 말로 시작하겠습니다. 그 말을 몇 번 들었 니? 나는 libnodave 라이브러리에서 testISO_TCP (단순화 된 버전) 테스트 프로그램을 가지고 일하고있다. 이 프로그램은 seimens 300 PLC에 연결된 동안 플래그 값과 데이터 블록을 간단히 읽습니다. 이 프로그램은 오류 자체를 발생시키지 않습니다. 내가하려고하는 일은 충돌로부터 읽기를 보호 할 코드를이 프로그램에 추가하는 것입니다. 좀 더 설명해 줄게. 예를 들어 코드에 구현 된 많은 읽기가 있다고 가정 해보십시오. 현재로서는 두 가지만 있습니다. 결국 나는이 코드를 더 많은 읽기와 함께 실행할 것이다. 이제, 테스트 프로그램을 실행 중이며 어떤 이유로 PLC와의 연결이 끊어 졌다고 해봅시다. 프로그램에 두 가지 중 하나를 수행하고 싶습니다. 1) 연결이 끊어지면 재 시도가 일정 시간 연결되고 시도가 끝나면 종료합니다. 또는 2) 모두 완료 될 때까지 어떻게 든 PLC에서 계속 읽습니다.읽기 루틴을 충돌로부터 보호하는 libnodave 테스트 프로그램 (testISO_TCP 단순화)에 코드를 추가하려면 어떻게해야합니까?

이 정보가 도움이되기를 바랍니다. 이 코드를 어떻게 효과적으로 수행하는지 전혀 모르고 오랫동안 내가 본 코드를 게시 할 것입니다. 모두에게 미리 감사드립니다.

#define PLAY_WITH_KEEPALIVE 
#include <stdlib.h> 
#include <stdio.h> 
#include "nodavesimple.h" 
#include "openSocket.h" 


#ifdef PLAY_WITH_KEEPALIVE 
#include <winsock.h> 
#endif 


int main(int argc, char **argv) { 
    int a,b,c,res, doRun, doStop, doRead, doreadFlag, useProtocol, useSlot; 
#ifdef PLAY_WITH_KEEPALIVE  
    int opt; 
#endif  
    float d; 
    daveInterface * di; 
    daveConnection * dc; 
    _daveOSserialType fds; 
    doRun=0; 
    doStop=0; 
    doRead=0; 
    doreadFlag=0; 
    useProtocol=daveProtoISOTCP; 
    useSlot=2; 


fds.rfd=openSocket(102, argv[1]); 
    #ifdef PLAY_WITH_KEEPALIVE 
    errno=0;  
    opt=1; 
    //res=setsockopt(fds.rfd, SOL_SOCKET, SO_KEEPALIVE, &opt, 4); 
    //LOG3("setsockopt %s %d\n", strerror(errno),res); 
    #endif 
fds.wfd=fds.rfd; 

    if (fds.rfd>0) 
     { 
     di =daveNewInterface(fds,"IF1",0, daveProtoISOTCP, daveSpeed187k); 
     daveSetTimeout(di,5000000); 
     dc =daveNewConnection(di,2,0, 2); // insert your rack and slot here 



      if (0==daveConnectPLC(dc)) 
       { 
        printf("Connected.\n"); 

       res=daveReadBytes(dc,daveFlags,0,0,16,NULL); 
       if (0==res) 
       { 
         a=daveGetU32(dc); 
         b=daveGetU32(dc); 
         c=daveGetU32(dc); 
         d=daveGetFloat(dc); 
        printf("FD0: %d\n",a); 
        printf("FD4: %d\n",b); 
        printf("FD8: %d\n",c); 
        printf("FD12: %f\n",d); 
       }//end 0==res 

       }//end daveConnectPLC 


      else 

      { 
     printf("Couldn't connect to PLC.\n Please make sure you use the -2 option with a CP243 but not with CPs 343 or 443.\n");  
     //closeSocket(fds.rfd); 
     //return -2; 
      } 

    }//end fds.rfd 



    fds.rfd=openSocket(102, argv[1]); 
    fds.wfd=fds.rfd; 

    if (fds.rfd>0) 
     { 
     di =daveNewInterface(fds,"IF1",0, daveProtoISOTCP, daveSpeed187k); 
     daveSetTimeout(di,5000000); 
     dc =daveNewConnection(di,2,0, 2); // insert your rack and slot here 


      if (0==daveConnectPLC(dc)) 
       { 
        printf("Connected.\n"); 

       res=daveReadBytes(dc,daveDB,1,0,64,NULL); 
       if (0==res) 
       { 

        a=daveGetU16(dc); 
        printf("DB1:DW0: %d\n",a); 
        a=daveGetU16(dc); 
        printf("DB1:DW1: %d\n...\n",a); 
        a=daveGetU16At(dc,62); 
        printf("DB1:DW32: %d\n",a); 


       }//end 0==res 

        return 0; 

       }//end daveConnectPLC 
      else 

      { 
     printf("Couldn't connect to PLC.\n Please make sure you use the -2 option with a CP243 but not with CPs 343 or 443.\n");  
     closeSocket(fds.rfd); 
     return -2; 
      } 

    }//end fds.rfd 






    else 
    { 
    printf("Couldn't open TCP port. \nPlease make sure a CP is connected and the IP address is ok. \n");  
     return -1; 
    }  



}// end main 

답변

1

daveReadBytes 함수의 반환 값을 확인해야합니다. 가 0이 아닌 경우 는 뭔가 잘못 가서 당신은 적절한 오류 메시지를 얻기 위해 daveStrerror 기능을 사용할 수 있습니다

printf ("error: %s\n", daveStrerror(res));

후에는 (단순히 읽기 또는 분리를 시도 하나에 결정하는 당신에게 달려 있음 closeSocket (...))을 사용하여 시작한 다음 처음부터 새 연결을 만듭니다. 어떤 오류 코드가 있는지 문서를 확인하십시오. 재 시도 (예 : 존재하지 않는 데이터 블록을 읽으므로)하여 일부 오류를 해결할 수 없습니다.

+1

답변 해 주셔서 감사합니다. 그러나, 나는 질문이있다. 오류 메시지 이후에 연결을 반복하는 방법은 무엇입니까? 나는 그 모든 코드를 반복하지 않기를 바래요. (연결하고 읽으십시오). 코드를 반복하도록 프로그램에 알리는 더 짧은 방법이있는 것처럼 보입니다. 이 작업을 수행하는 데는 여러 가지 방법이있을 것입니다. 올바른 방향으로 안내해 주시겠습니까? 다시 감사합니다. 또한 설명서에는 PDU 오류 코드에 대한 정보 만 있습니다. 아주 기본적인 정보는 함수 문서의 일부입니다. – Rey

+0

레이, 상황이 그렇게 작동하지 않습니다. 당신은 upvote와 어떤 대답을 보상하지 않았으며 이미 기존의 질문에 새로운 질문을합니까? 두 대답 모두 귀하의 질문에 유효합니다. 그러나 귀하가해야하는 일의 양이 마음에 들지 않으므로이를 무시하고 새로운 하위 질문을하십시오. 그렇다면 완전히 새로운 질문을하십시오. 그러나 가장 먼저 좋아하는 대답을 수락하고 도움이되는 모든 대답을 취소하십시오. – avra

+0

아브라, 먼저, 내가 처음 이래로 어떻게 여기에서 일들이 어떻게 돌아가는지 알지 못한다는 사실에 대해 당신이 옳다고 말하려합니다. 도움이 되었기 때문에 답변을 투표하는 데 문제가 없습니다. 투표 프로세스를 알지 못했습니다. 둘째로, 나는 내가해야 할 일의 양이 맘에 들지 않는다는 말로 당신이 틀렸다는 생각이 든다. 본질적으로 복사와 붙여 넣기 만하면됩니다. 대답은 반환 값에 따라 오류 메시지를 표시하는 데 도움이되기 때문에 도움이되었습니다. – Rey

0

통신이 끊어짐을 감지하는 데 필요한 모든 정보는 설명서에 있습니다.

+1

파일 중 해당 정보가있는 파일을 알 수 있습니까? 덕분에 – Rey

+0

daveReadBytes.html이 말한다 :이 함수는 성공시 0을 반환한다. daveStrerror()에 0이 아닌 반환 코드를 전달하여 발생한 문제에 대한 텍스트 설명을 얻을 수 있습니다. 일반적으로 긍정적 인 오류 코드는 PLC에 의해보고 된 오류를 나타내며, 부정적 오류 코드는 LIBNODAVE에 의해 감지 된 오류를 나타냅니다. PLC로부터의 응답 없음. – avra

+0

감사합니다. 게시 한 정보가있는 파일이 있습니다. – Rey

1

루프가 3 회 연결 시도가 실패하면 정상적으로 종료합니다. 연결이 작동하고 있는지, 그리고 PLC가 가동 중인지 먼저 확인하기 위해 다른 코드를 작성할 수 있습니다. 일반적으로 esond가 아닌 IP 주소에 연결하려고하면; 그것은 거기에 매달리고 자원을 묶을 것입니다 ...

1

저는 또한 새로운 프로그래머입니다.하지만 그 말을하고 싶습니다. 먼저 TCP/IP 연결을 ethernet 카드 ISO_TCP으로 구분해야합니다. openSocket() 함수는 주어진 포트/서비스 (102 ISO_TCP)에서 원격 IP 주소에 대한 연결을 수행합니다. 다음에 함수 daveNewInterface()을 호출하면 PLC에 연결하기위한 특정 인터페이스가 초기화됩니다. 그 후, daveNewConnection() 함수는 주어진 MPI 주소에서 연결을 열려고합니다. 매우 중요한 것은 지정된 랙과 슬롯입니다. 이 함수가 값 0을 반환하면 daveConnectPLC() 함수를 호출하여 PLC에 연결합니다. 이 때 이더넷 연결과 PLC 연결이 설정됩니다. libnodave 라이브러리의 모든 기능을 사용하여 데이터를 읽거나 쓰거나, PLC를 중지하거나 실행할 수 있습니다.

실제로 단순화 된 TCP_ISO 코드에는 어댑터 연결을 끊거나 PLC와의 연결을 닫는 기능이 없습니다. 코드에는 closeSocket() 기능과 -2를 반환하는 기능이 있습니다. 코드가 어떤 줄에서 끊어 지는지 확인하십시오. 예를 들어 모든 함수 다음에 로그를 입력하여 반환 값을 확인하십시오.

관련 문제