Zuviel Werbung? - > Hier kostenlos beim SPS-Forum registrieren

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 11

Thema: Mit B&R Schnittstelle (RS485) auslesen?

  1. #1
    Registriert seit
    11.03.2012
    Beiträge
    12
    Danke
    2
    Erhielt 1 Danke für 1 Beitrag

    Frage


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Hallo liebe Gemeinde!

    Ich bin gerade am verzweifeln, wär also nett wenn ihr mir weiterhelfen könntet

    Ich habe ein Projekt bei dem ich Daten mehrerer Regler über eine RS485- Schnittstelle auslesen muss.
    Als Hardware habe ich ein Power-Panel, das über X2X-Link mit einem Kommunikationsmodul (X20CS1030) verbunden ist.
    Die Regler sind untereinander über RS485 verbunden und die Leitung geht anschließend auf mein Kommunikationsmodul.

    Leider hab ich es bis jetzt noch nicht geschafft, das mir ein Regler eine Antwort zurückschickt (bin auch noch Neuling auf dem Gebiet)
    Zur Kommunikation verwende ich die "DVFrame"-Bibliothek. Nachstehend füge ich meinen Code und einen Auszug des Schnittstellenprotokolles der Regler ein, vielleicht fällt euch ja ein Lösungsansatz ein. Vielleicht mach ich auch grundsätzlich was falsch...

    Ausschnitt aus dem Schnittstellen-Protokoll (E-Link):

    ================================================================================ =====

    • Baudrate: 9600
    • Parität: Keine
    • Datenbits: 8
    • Stoppbits: 1




    • Für die Kommunikation steht das folgende Protokoll zur Verfügung:
    • <SOH> <Adr> <STX> <D1 D2 D3...Dn> <ETX> <Checksum> <EOT>
    • <SOH> = ^A (0x01)
    • <Adr> = 0x30 + Adresse des Gerätes von 0...78
    • <STX> = ^B (0x02)
    • D1 D2...Dn = Datenbereich (Abfrage= ? Programmierung = !, Bsp: Abfrage des Parameters 1000= ?1000
    • <ETX> = ^C (0x03)
    • Checksum = Checksumme: Adr xor D1 xor D2 xor D3...xorDn, Wenn Checkbyte <= 1: Checkbyte + 0x71
    • <EOT> = ^D (0x04)


    Beispiel für die Abfrage aller Laufvariablen: ^A~^B?9000^CH^D
    ================================================================================ ============



    Nun mein Code (zyklisch):
    ===================


    CASE step OF


    //WARTEN******************************************************************
    0:

    strcpy(ADR(Sendebuffer),ADR(''));

    IF (Open) THEN
    step := 1;
    END_IF


    //ÖFFNEN*******************************************************************
    1:

    FRM_xopen_0.enable := TRUE;
    FRM_xopen_0.device := ADR('IF2.ST2.IF1');
    FRM_xopen_0.mode := ADR('/PHY=RS485 /BD=9600 /DB=8 /PA=N /SB=1');
    FRM_xopen_0.config := 0;
    FRM_xopen_0.config := ADR(Schnittstellenparameter);

    Schnittstellenparameter.idle := 1000;
    Schnittstellenparameter.delimc := 1;
    Schnittstellenparameter.delim[0] := 4; //<EOT>
    Schnittstellenparameter.tx_cnt := 8;
    Schnittstellenparameter.rx_cnt := 8;
    Schnittstellenparameter.tx_len := 256;
    Schnittstellenparameter.rx_len := 256;
    Schnittstellenparameter.argc := 0;
    Schnittstellenparameter.argv := 0;

    FRM_xopen_0();

    IF (FRM_xopen_0.status = 0) THEN
    step := 2;
    strcpy(ADR(Sendebuffer), ADR('^A~B?9000^CH^D'));
    ELSIF (FRM_xopen_0.status = ERR_FUB_BUSY) THEN
    step := 1;
    ELSE
    step := 255;
    END_IF


    //SENDEBUFFER ANFORDERN***************************************************
    2:

    FRM_gbuf_0.enable := TRUE;
    FRM_gbuf_0.ident := FRM_xopen_0.ident;
    FRM_gbuf_0();


    IF (FRM_gbuf_0.status = 0) THEN
    memset(FRM_gbuf_0.buffer, 0, FRM_gbuf_0.buflng);
    strcpy(FRM_gbuf_0.buffer, ADR(Sendebuffer));
    step := 3;
    i := 0;
    ELSIF (FRM_gbuf_0.status = ERR_FUB_BUSY) THEN
    step := 2;
    ELSE
    step := 255;
    END_IF


    //SENDEN *****************************************************************
    3:

    FRM_write_0.enable := TRUE;
    FRM_write_0.buffer := FRM_gbuf_0.buffer;
    FRM_write_0.buflng := strlen(ADR(Sendebuffer));
    FRM_write_0.ident := FRM_xopen_0.ident;
    FRM_write_0();

    IF (FRM_write_0.status = 0) THEN
    step := 4;
    ELSIF (FRM_write_0.status = ERR_FUB_BUSY) THEN
    step := 3;
    ELSE
    step := 255;
    END_IF


    //LESEN ******************************************************************
    4:

    FRM_read_0.enable := TRUE;
    FRM_read_0.ident := FRM_xopen_0.ident;
    FRM_read_0();

    IF (FRM_read_0.status = 0) THEN
    step := 5;
    ELSIF (FRM_read_0.status = frmERR_NOINPUT) THEN
    step := 4;
    ELSE
    step := 255;
    END_IF


    //LESEBUFFER KOPIEREN ****************************************************
    5:

    memset(ADR(Readbuffer), 0, SIZEOF(Readbuffer));
    memcpy(ADR(Readbuffer), FRM_read_0.buffer, FRM_read_0.buflng);
    strcpy(ADR(ReceivBuffer),ADR(Readbuffer));

    IF (FRM_read_0.buflng > 0) THEN

    FRM_rbuf_0.enable := TRUE;
    FRM_rbuf_0.ident := FRM_xopen_0.ident;
    FRM_rbuf_0.buffer := FRM_read_0.buffer;
    FRM_rbuf_0.buflng := FRM_read_0.buflng;
    FRM_rbuf_0();


    IF FRM_rbuf_0.status = 0 THEN
    step := 0;
    ELSIF FRM_rbuf_0.status = ERR_FUB_BUSY THEN
    step := 5;
    ELSIF FRM_rbuf_0.status = frmERR_INVALIDBUFFER THEN
    step := 4;
    ELSE
    step := 255;
    END_IF
    ELSE
    step := 6;
    END_IF



    //SCHLIESSEN*************************************************************
    6:

    FRM_close_0.enable := TRUE;
    FRM_close_0.ident := FRM_xopen_0.ident;

    FRM_close_0();

    IF FRM_close_0.status = 0 THEN
    step := 0;
    ELSIF FRM_close_0.status = ERR_FUB_BUSY THEN
    step := 6;
    ELSE
    step := 255;
    END_IF

    //************************************************************************
    255:

    //ERROR


    END_CASE
    Zitieren Zitieren Mit B&R Schnittstelle (RS485) auslesen?  

  2. #2
    Registriert seit
    08.03.2010
    Ort
    BaWü
    Beiträge
    131
    Danke
    10
    Erhielt 13 Danke für 11 Beiträge

    Standard

    Hi

    hier vlt ein paar hilfreiche Fragen

    Wie sehen die Stais von den Bausteinen aus?
    Kommt hier ein Fehler zurück? Wen ja an welchem FUB und welcher Fehlernummer?

    Wie siehts an der LE Status an der CS Scheibe aus? Leuchtet die Tx beim Schreiben oder die Rx beim Lesen?

    Hast du Abschlusswiderstand am Anfang und Ende drin? An der CS Scheibe kannst den Einschalten, dann sollte auch die LED T leuchten.
    Verdrahtung ansonsten passt auch?
    Welches Funktionsmodel hast du am Modul eingestellt? Stream wäre der Richtige.

    Die Knotennummern der Slave sind eindeutig und richtig eingestellt?

    So im Querflug hat der Code eigentlich gepasst, wobei ich Detail jetzt nicht alles angesehen habe.

  3. Folgender Benutzer sagt Danke zu Sera für den nützlichen Beitrag:

    Ruddy (21.03.2014)

  4. #3
    Ruddy ist offline Neuer Benutzer
    Themenstarter
    Registriert seit
    11.03.2012
    Beiträge
    12
    Danke
    2
    Erhielt 1 Danke für 1 Beitrag

    Standard

    Hi

    Also nach dem Sendebefehl sendet der Baustein frmRead_0 den Status "frmERR_NOINPUT" zurück, die Schrittkette bleibt dann also im Leseschritt... Und das wars dann auch :P
    die Tx- LED leuchtet kurz, die rx-LED leuchtet jedoch nicht auf... Der Abschlusswiderstand an der CS1030 ist eingeschaltet. Den Rest kontrolliere ich morgen, da ich heute keine Gelegenheit mehr dazu hab. Danke schonmal für deine Hilfe!

  5. #4
    Registriert seit
    12.04.2010
    Beiträge
    300
    Danke
    22
    Erhielt 54 Danke für 52 Beiträge

    Standard

    Hallo,
    also ich könnte mir vorstellen das Problem liegt hier...

    Code:
    strcpy(ADR(Sendebuffer), ADR('^A~B?9000^CH^D'));
    Meiner Meinung nach müsste das so gehen

    Code:
    Sendebuffer[0] := $01
    SendeBuffer[1] := $30 + Adresse des Gerätes von 0...78
    SendeBuffer[2] := $02
    strcpy(ADR(Sendebuffer[3]), ADR('?9000'));
    ;
    checksum berechnen
    SendeBuffer[x] = checksum
    SendeBuffer[x+1] = $04
    Wenn du im String "^A" angibst sind das 2 Zeichen, also gänzlich unterschiedlich zu dem wie es sein soll.

    Physikalisch scheint es lt. Beschreibung ja soweit OK zu sein. Wahrscheinlich verstehen die Regler schlicht und ergreifend einfach nicht was da kommt...

    BG
    BB

  6. #5
    Ruddy ist offline Neuer Benutzer
    Themenstarter
    Registriert seit
    11.03.2012
    Beiträge
    12
    Danke
    2
    Erhielt 1 Danke für 1 Beitrag

    Standard

    Danke für deine Antwort!

    Klingt irgendwie logisch wie du das schreibst... Ich hätte dazu aber ein paar Fragen:


    1. Von welchem Datentyp muss das Array "SendeBuffer" sein?
    2. Kannst du mir erklären wie ich die Checksumme berechnen muss? Das versteh ich nicht...
    3. Wie übergebe ich dann den fertigen Sendebuffer an die Funktion? Das gesamte Array? (Funktion.buffer := ADR(SendeBuffer); Funktion.bufferlng := SIZEOF(SendeBuffer);


    Sorry für die vielen Fragen, ich blick da nicht ganz durch...

  7. #6
    Registriert seit
    12.04.2010
    Beiträge
    300
    Danke
    22
    Erhielt 54 Danke für 52 Beiträge

    Standard

    Zitat Zitat von Ruddy Beitrag anzeigen
    Danke für deine Antwort!

    Klingt irgendwie logisch wie du das schreibst... Ich hätte dazu aber ein paar Fragen:


    1. Von welchem Datentyp muss das Array "SendeBuffer" sein?
    2. Kannst du mir erklären wie ich die Checksumme berechnen muss? Das versteh ich nicht...
    3. Wie übergebe ich dann den fertigen Sendebuffer an die Funktion? Das gesamte Array? (Funktion.buffer := ADR(SendeBuffer); Funktion.bufferlng := SIZEOF(SendeBuffer);


    Sorry für die vielen Fragen, ich blick da nicht ganz durch...
    Hallo Ruddy,

    zu den Fragen

    1) muss ein USINT-Array sein
    2) ... siehe unten
    3) so wie du es angegeben hast, mit strlen(Sendebuffer), allerdings musst du am Beginn - bevor du irgendwas in den Sendebuffer schreibst, alles mit
    memset(adr(Sendebuffer), 0, sizeof(Sendebuffer)) initialisieren. Strlen gibt dann die Anzahl der Byte an von Beginn bis zur ersten 0 (null).

    Die Checksum einfach in einer Schleife berechnen, bist du sicher dass STX nicht in die Checksum eingerechnet wird ? Das ist zumindest ungewöhnlich da ja index=1, Lücke (index =2) und dann weiter mit index = 3...

    ACHTUNG: konnte das natürlich nicht testen, kannst du das mit Beispielen aus der Dokumentation des Gerätes verifizieren ?

    Code:
        memset(ADR(SendeBuffer), 0, SIZEOF(SendeBuffer));
        SendeBuffer[0] := 1;
        SendeBuffer[1] := Dev_Adr + 16#30;
        SendeBuffer[2] := 16#2;
        strcpy(ADR(SendeBuffer[3]), ADR('?9000'));
        
        send_len := strlen(ADR(SendeBuffer));
        checksum := SendeBuffer[1];
        FOR index := 3 TO send_len-1 BY 1 DO
            checksum := checksum XOR SendeBuffer[index];
        END_FOR        
        IF (checksum <= 1) THEN
            checksum := checksum + 16#71;
        END_IF
        SendeBuffer[send_len] := checksum;
        SendeBuffer[send_len+1] := 16#04;
    
    
        send_len := strlen(ADR(SendeBuffer));
    
    
    ...
    
    Funktion.buffer := ADR(SendeBuffer); 
    Funktion.bufferlng := send_len
    BG
    BB

  8. Folgender Benutzer sagt Danke zu bits'bytes für den nützlichen Beitrag:

    Ruddy (25.03.2014)

  9. #7
    Ruddy ist offline Neuer Benutzer
    Themenstarter
    Registriert seit
    11.03.2012
    Beiträge
    12
    Danke
    2
    Erhielt 1 Danke für 1 Beitrag

    Standard

    Hallo bits'bytes!

    Ich bin dir sehr dankbar für deine Hilfe! Hab's jetzt hinbekommen, läuft mit einer kleinen Anpassung (Das "C" hat noch vor der checksumme gefehlt) nun einwandfrei

    Ohne dich hätt ich wahrscheinlich den Hut drauf geworfen.
    Danke nochmal!

  10. #8
    Registriert seit
    12.04.2010
    Beiträge
    300
    Danke
    22
    Erhielt 54 Danke für 52 Beiträge

    Standard

    Hallo Ruddy,
    herzlichen Dank für das Feedback. Positives tut manchmal gut .!!

    Das mit dem ^C hab ich total übersehen - gut dass dir das gleich aufgefallen ist.

    Was ich noch sagen wollte - falls das bei dir zutrifft:

    Wenn du mehrere Geräte hast brauchst du ja nicht auf die Antwort eines Gerätes zu warten und danach erst das Nächste adressieren usw.

    In diesem Fall würde ich das ganze über ein entsprechendes Kommunikationsarray aufbauen (die Frame-Fubs brauchst du aber nur einmal, da nur eine Schnittstelle). Entsprechend viele Sende- und Empfangsbuffer und alle sonstigen Zwischenspeicher im Array unterbringen....

    Viel Spass
    BG
    BB

  11. #9
    Ruddy ist offline Neuer Benutzer
    Themenstarter
    Registriert seit
    11.03.2012
    Beiträge
    12
    Danke
    2
    Erhielt 1 Danke für 1 Beitrag

    Standard

    Hallo
    Ich habs bis jetzt so gemacht, das ich auf eine Antwort warte, und dann den nächsten Parameter oder Regler auslese... Ist also sicher noch ausbaufähig das ganze :P
    ich muss jedoch nach nach den ersten 2 Reglern sowieso die Schnittstelle erneut öffnen, weil die darauffolgenden Regler andere Schnittstellenparameter haben...

    LG, Rudi

  12. #10
    Registriert seit
    08.03.2010
    Ort
    BaWü
    Beiträge
    131
    Danke
    10
    Erhielt 13 Danke für 11 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Über /<hexwert des assci zeichens> sollte es doch auch mit dem string gehen oder nicht?

Ähnliche Themen

  1. Antworten: 0
    Letzter Beitrag: 16.02.2014, 14:04
  2. TIA V11 Kommunikation Mit RS485 Schnittstelle
    Von bremax im Forum Simatic
    Antworten: 0
    Letzter Beitrag: 28.11.2011, 12:06
  3. Antworten: 2
    Letzter Beitrag: 28.04.2011, 07:57
  4. Simatic S5 135U mit RS485 Schnittstelle
    Von captainchaos666 im Forum Simatic
    Antworten: 8
    Letzter Beitrag: 08.05.2008, 07:29
  5. Wetterstation mit RS485 Schnittstelle
    Von charly007 im Forum Sonstige Steuerungen
    Antworten: 5
    Letzter Beitrag: 23.04.2006, 10:11

Stichworte

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •