2

まず、私はC++の経験がほとんどない大学生です。その権利を何回聞いたことがありますか?libnodaveライブラリのテストプログラムtestISO_TCP(簡易バージョン)を使用しています。このプログラムは、seimens 300 PLCに接続されている間、フラグ値とデータブロックの単純な読み取りを行います。プログラム自体はエラーを発生させません。私がやろうとしているのは、読み取りがクラッシュしないように保護するコードをこのプログラムに追加することです。もう少し詳しく説明させてください。たとえば、コードに多くの読み取りが実装されているとします。現在のところ、読み取りは2つだけです。最終的には、このコードをさらに多くの読み取りで実行します。ここで、テストプログラムを実行していて、何らかの理由でPLCへの接続が失われたとします。プログラムに次の2つのいずれかを実行させたいと思います。1)接続が失われたら、一定回数接続を再試行し、試行回数がなくなったら終了します。または2)すべてが完了するまで、どういうわけかPLCから読み取りを続けます。

これが助けを得るのに十分な情報であることを願っています。これを効果的に行う方法がわからないまま、私が長い間見てきたコードを投稿します。よろしくお願いします。

#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
4

4 に答える 4

1

daveReadBytes関数の戻り値を確認する必要があります。ゼロでない場合は、問題が発生しているため、daveStrerror関数を使用して適切なエラーメッセージを取得できます。

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

その後、読み取りを再試行するか、(closeSocket(...)を使用して)切断し、最初から新しい接続を作成するかを決定するのはあなた次第です。存在するエラーコードに関するドキュメントを確認してください。一部のエラーは、再試行しても解決できません(たとえば、存在しないデータブロックを読み取ろうとしたため)。

于 2011-08-16T06:52:31.810 に答える
1

3回接続を試み、失敗した場合は正常に終了するループがあります。他のコードを記述して、接続がアップしているかどうか、およびPLCがアップしているかどうかを最初に確認できる場合があります。通常、esondしないIPアドレスに接続しようとした場合。そこにぶら下がってリソースを拘束します...

于 2011-09-28T15:10:25.510 に答える
1

私も新しいプログラマーですが、言いたいのですが。まず、カードとのTCP/IP接続を区別する必要があります。この関数は、指定されたポート/サービス(102 ISO_TCP)のリモートIPアドレスへの接続を行います。次に関数を呼び出すと、PLCへの接続を行うための特定のインターフェイスが初期化されます。この後、関数は特定のMPIアドレス、そして非常に重要な特定のラックとスロットで接続を開こうとします。この関数が値0を返す場合、PLCに接続するために関数を呼び出します。この時点で、イーサネット接続とPLC接続が確立されています。これで、ライブラリのすべての機能を使用して、データの読み取りまたは書き込み、PLCの停止または実行などを行うことができます。ethernetISO_TCPopenSocket()daveNewInterface()daveNewConnection()daveConnectPLC()libnodave

実際に簡略化されたTCP_ISOコードには、アダプタを切断したり、PLCとの接続を閉じたりする関数はありません。コードには、closeSocket()-2を返す関数と関数があります。コードが壊れている行を見つけます。たとえば、すべての関数の後にログを導入して、戻り値を確認します。

于 2012-06-06T22:27:32.230 に答える
0

通信の喪失を検出するためのすべての情報は、ドキュメントにあります。

于 2011-08-15T12:30:01.010 に答える