[TC3] RxBuffer bei EL6001 bleibt leer

Pneumatik

Level-2
Beiträge
46
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
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?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Oliver,

ja die Inputs sind gemappt und ich habe das bereits auch einmal gelöscht und neu gemappt.
Selber Problem wie vorher.

Da das senden funktioniert kann es ja eigentlich auch nicht an den Konfigurationsparametern liegen.

Am fehlenden Zuweisen von Prefix und Suffix kann es auch nicht liegen oder? Ich müsste ohne die beiden Werte sogar mehr empfangen als ohne, richtig?


Unbenannt.PNG
 
In den Data bits sehe ich nichts ankommen oder abgehen. Da der Empfänger allerdings die Befehle ausführt bin ich davon ausgegangen, dass die einfach zu schnell zurückgesetzt werden und ich deshalb immer nur eine null sehen.

Beim COM Output ändert sich Ctrl bei senden der Befehle an der Empfänger.
Bei COM Input gibt es überhaupt gar keine Änderung. Aus diesem Grund hatte ich dann das Oszilloskop angeschaltet um zu sehen ob überhaupt etwas ankommt. Am Oszilloskop habe ich das Signal bekommen, an der Verkabelung kann es also nicht liegen. Es gibt hier anscheinend etwas was ich übersehen. Allerdings weiß ich nicht was
 
Wenn du erfolgreich sendest (Werteänderung im Output für Ctrl und Data) MUSS sich auch auf der Eingangsseite der Status ändern.
Ctrl und Status verhält sich hier quasi wie ein Spiegel (mache versus "habe gemacht").

Auf der Eingangsseite werden im Data-Bereich auch niemals Werte gelöscht sondern immer nur überschrieben. Wenn du also hier 0-Werte hast wurde noch nie etwas empfangen.

Also:
Status änderungen (wenn du z.B. etwas sendest) und Data sind 0-Werte : -> Verkabelung oder RS232 Konfig Probleme
Status: Keine Änderung wenn du etwas sendest: -> erstell mal ein neues Projekt und schaue ob es dort funktioniert. Den Fall kann ich mir aber quasi nicht vorstellen.

Guga
 
Zurück
Oben