Quantcast
Channel: SPS-Forum - Automatisierung und Elektrotechnik
Viewing all articles
Browse latest Browse all 49537

[TC3] RxBuffer bei EL6001 bleibt leer

$
0
0
Hallo,

ich sitze mal wieder an der SPS und habe ein Problem mit der EL6001 Klemme. Ich bin in der Lage Befehle mittels RS232 und einer COM Schnittstelle zu senden. Allerdings bleibt der Receive Buffer komplett leer. Ich sitze da jetzt schon laenger immer mal wieder dran und mir gehen die Loesungsansaetze aus. Da es meine erster Kommunikationsbaustein fuer RS232 ist liegt der Fehler bestimmt bei mir.

Das der Fehler im Code und nicht an nicht gesendeten daten liegt konnte ich unter anderem durch ein Oszilloskop bestaetigen auf dass ich die ASCI Antwort ablesen konnte.

Da das Gesamtsystem eine Zykluszeit von 10ms hat, wird die Kommunikation ueber einen zweiten schnelleren Task mit einer Zykluszeit von 1ms aufgerufen (BackgroundEL). BackgroundEL ist dabei komplett einem Beckhoff Beispiel entnommen.

Hier die drei relevanten aber teils gekürzte Codeteile die benutzt werden. Ziel ist es einen Befehl an den Kommunikationspartner zu schicken. Dieser sendet immer eine Antwort. Sobald die Antwort kommt ist der Sendeprozess erfolgreich abgeschlossen.

Code:


PROGRAM BackgroundEL
VAR
    (* background communication with the EL6001 terminal *)
    fbEL6001Ctrl        : SerialLineControl;
    bEL6001CtrlError    : BOOL;
    eEL6001CtrlErrorID    : ComError_t;
    (*    I/O variables for a EL6001 terminal*)
    stIn_EL6001 AT %I*    : EL6inData22B;    (* linked to the EL6001 in the TwinCAT System Manager *)
    stOut_EL6001 AT %Q*    : EL6outData22B;(* linked to the EL6001 in the TwinCAT System Manager *)
END_VAR


________________


(*
The SerialLineControl function block is supposed to be called in every PLC cycle.
It communicates with the serial line hardware device and transmits or receives data.
The SerialLineControl can be called in the standard task (e.g.for PcCOM port usage)
or in a separate fast task (e.g.for terminal usage) as well.
A fast separate task will be necessary at high baud rates or with KL6001 terminals
which have a small process image (3 or 5 data bytes only)
*)


(* background communication with the EL6001 terminal *)
fbEL6001Ctrl(    Mode        := SERIALLINEMODE_EL6_22B,
                pComIn        := ADR(stIn_EL6001),
                pComOut        := ADR(stOut_EL6001),
                SizeComIn    := SIZEOF(stIn_EL6001),
                Error=>    ,
                ErrorID=>    ,
                TxBuffer    := TxBufferEL,
                RxBuffer    := RxBufferEL );
               
IF fbEL6001Ctrl.Error THEN
    bEL6001CtrlError    := TRUE;
    eEL6001CtrlErrorID    := fbEL6001Ctrl.ErrorID;
END_IF


In der "normalen" Main Task geht die Kommunikation ueber den FB_SerialCom und soll jeweils dann abgeschlossen sein wenn eine Antwort des Kommunikationspartners kam.

Code:

FUNCTION_BLOCK FB_SerialCom
VAR_IN_OUT
    TxBuffer    : ComBuffer;
    RxBuffer    : ComBuffer;
END_VAR
VAR_OUTPUT
    nfinished    : UDINT;
    sStatus        : STRING;
END_VAR
VAR_INPUT
    aSendBytes    : ARRAY[0..MAX_STRING_LENGTH] OF BYTE;
    nLength        : UDINT;
END_VAR


VAR
....
END_VAR


// Method to data using the Serial Communication with EL6001


CASE nSwitchSend  OF
    0:   
    ... ein par abfragen ob ein neuer Befehl gesendet werden darf
    nSwitchSend        := 10;




    10:
    fbReceive(    Prefix            := '',
                Suffix        := '',
                Timeout        := T#10S,
                ReceivedString    := sReceivedString,
                RXbuffer        := RxBufferEL,
                StringReceived    => bStringReceived,
                Busy            => bReceiveBusy,
                Error            => ,
                RxTimeout        => bReceiveTimeout );
               
    IF fbReceive.Error <> COMERROR_NOERROR THEN
        eReceiveErrorID := fbReceive.Error;
    END_IF
   
    IF bStringReceived THEN
        nReceiveCounter    := nReceiveCounter + 1;
        sLastReceivedString := sReceivedString;
        bStringReceived    := 0;
    END_IF




    IF NOT bSent THEN
        fbSendData(    pSendData    := ADR(aSendBytes),
                    Length        := SIZEOF(aSendBytes),
                    Busy        => bSendBusy,
                    Error        => eSendErrorID,
                    TXbuffer    := TxBuffer);
        IF fbSendData.Error <> COMERROR_NOERROR THEN // if the error message is not "No Error" write error ID
            eSendErrorID        := fbSend.Error;
            bError                :=TRUE;
        END_IF
        IF NOT fbSendData.Busy THEN
            bSent            := TRUE;
            nSendCounter    := nSendCounter+1;
        END_IF;
    END_IF;


    IF (bSent AND nSendCounter=nReceiveCounter AND nSendCounter>nLastSendCounter) THEN
        nSwitchSend            := 20;
    END_IF
   
    20: (*Reset sent function and prepare for next send command*)
    nLastSendCounter:= nSendCounter;
    bSent            := FALSE;
    nSwitchSend        := 30


    30:
    bBusy            := FALSE;
    nfinished        := 1;
    nSwitchSend        := 0;
END_CASE

Aufgeruffen wird die Instanz vom SerialCom baustein wie folgt:

Code:


....
    nSwitchInitialise    := 10;
    10:
    aSendBytes[0]    := 16#01;            //<PRE>
    aSendBytes[1]    := F_ToASC('1');    //<ADR>        '1'
    aSendBytes[2]    := F_ToASC('R');    //<CODE1>    'R'
    aSendBytes[3]    := F_ToASC('Z');    //<CODE2>    'Z'
    aSendBytes[4]    := F_ToASC('3');    //<CODE2>    '3'
    aSendBytes[5]    := F_ToASC('0');    //<CODE2>    '0'
   
    LRC:= 16#00;
    FOR i:=1 TO 5 BY 1 DO
        LRC:= LRC XOR aSendBytes[i];
    END_FOR
    LRC:= LRC OR 16#80;
   
    aSendBytes[6]:= LRC;        //<LRC>
    aSendBytes[7]:= 16#0D;        //<POST>    'CR'
    fbCOMDispenser(    aSendBytes    := aSendBytes,
                    nLength        := 8,
                    TxBuffer    := TxBufferEL,
                    RxBuffer    := RxBufferEL,
                    nfinished    => nSent);
    IF nSent=1 THEN
        nSwitchInitialise:=999;
    END_IF

Aktuell habe ich keine Ahnung wie ich das Problem weiter eingrenze kann. Wie würdet ihr vorgehen? Oder gibt es direkt einen sichtbaren Fehler meiner Herangehensweise?

Viewing all articles
Browse latest Browse all 49537


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>