TIA Kommunikation mit RS485-Teilnehmer - Empfangsbuffer bleibt leer

AlexTh

Level-2
Beiträge
112
Reaktionspunkte
2
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

ich habe ein Gerät, das ich über RS485 mit der SPS verbinden möchte, doch leider glaube ich einen Fehler in der Programmierung zu haben.

Parameter:
- 6ES7137-6AA00-0AB0 Kommunikationsmodul, HW-Kennung 262
- 2-Draht-Verbindung, angeschlossen auf Klemme 12 (A-) und 14 (B+) des Basismoduls
- Abschlusswiderstand 120 Ohm gesetzt
- 9600 Bit/s / 8 Datenbits / 1 Stoppbit / keine Parität
- Standardadresse meine Geräts ist die 1, diese gebe ich im Sendestring (30 31) mit

gesendet wird: 02 30 31 72 65 61 64 03
Klartext: STX 0 1 r e a d ETX
erwartet wird: 82 B9 C0 0D F6 18 04 00 (Empfangspuffer größer gemacht)

Zu Beginn steuere ich die Port-Konfiguration an, wobei ich mich frage, ob dies überhaupt notwendig ist, da gleiches schon in der HW-Konfig steht?
Danach sende ich '02 30 31 72 65 61 64 03' an das Gerät und müsste anschließend beim Empfangen '82 B9 C0 0D F6 18 04 00' zurück erhalten, jedoch bleibt der Status auf 7002 (Zwischenaufruf: Datenübertragung läuft) stehen.

Die Bits CMD_Send, CMD_Recv, CMD_Konfig und CMD_Reset steuere ich manuell über eine Variablentabelle an, bis ich die Grundfunktion habe.

Kann mir jemand sagen, was ich falsch mache?
Die Eingänge des Kommunikationsmoduls (E12.0..E19.7) werden automatisch gezogen, sobald der Port '262' als Parameter dem Receive_P2P_DB übergeben werden, oder?


Einstellungen.jpgProgramm.jpgDB.jpg
 
Zu Beginn steuere ich die Port-Konfiguration an, wobei ich mich frage, ob dies überhaupt notwendig ist, da gleiches schon in der HW-Konfig steht?
Danach sende ich '02 30 31 72 65 61 64 03' an das Gerät und müsste anschließend beim Empfangen '82 B9 C0 0D F6 18 04 00' zurück erhalten, jedoch bleibt der Status auf 7002 (Zwischenaufruf: Datenübertragung läuft) stehen.

Die Portkonfiguration kannst du dir eigentlich sparen wenn du es in der HW-Konfig einträgst.
Wenn es dann läuft, kannst du dir Gedanken über die Bausteine PortConfig Send und Recv Config machen. Macht z.B. sinn wenn man die Config mit der Bibliothek mitliefern will.

Liest du den Bus noch irgendwie mit? Wenn nicht empfehle ich dir noch auf dem PC z.B. RealTerm mitlaufen zu lassen um zu sehen ob dein Telegramm vollständig rausgeht, und ob überhaupt was geantwortet wird.

Wie hast du die Telegramempfangserkennung konfiguriert?
 
Dann steuere ich die Portkonfiguration erstmal nicht mehr an, das reicht ja schon.
Ja, die Programmierung mache ich, wenn alles läuft schön.

Nein, ich lese den Bus nicht mit, wie soll das gehen - einfach parallel dran hängen?

Die Telegramempfangserkennung ist noch im Standard, quasi "mit beliebigem Zeichen beginnen".
 
Einfach parallel dran hängen (RS485 lässt das zu). Ich nehme dazu einen NPort. Aber es geht auch z.B. ein Exsys
Exsys USB RS485 Port
Das hilft dir den Telegrammverkehr zu diagnostizieren.
Bei RS323 ist das dann anders, da gibts nur zwei Busteilnehmer, um Telegrammverkehr mitzuschneiden brauchts Hardware.
RS323 Sniffer
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
 
Ich habe die A- und B-Leitungen getauscht und es sieht ein wenig besser aus. Also RXD und TXD blinken nun schöner als vorher und das Gerät reagiert auch darauf (LED geht nach Read aus).

Jetzt kommt das große Problem.

Wenn ich meinen Read-String an das Gerät sende, dann antwortet das Gerät darauf unmittelbar mit dem Ergebnis.
Das Ergebnis kann dann nicht mehr mit Receive_P2P_DB abgefragt werden, da es dann bereits im Datennirvana verschwunden ist.
Gibt es da einen Trick oder einen kombinierten Baustein Send/Receive?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich habe die A- und B-Leitungen getauscht und es sieht ein wenig besser aus. Also RXD und TXD blinken nun schöner als vorher und das Gerät reagiert auch darauf (LED geht nach Read aus).

Jetzt kommt das große Problem.

Wenn ich meinen Read-String an das Gerät sende, dann antwortet das Gerät darauf unmittelbar mit dem Ergebnis.
Das Ergebnis kann dann nicht mehr mit Receive_P2P_DB abgefragt werden, da es dann bereits im Datennirvana verschwunden ist.
Gibt es da einen Trick oder einen kombinierten Baustein Send/Receive?
Da ich ne Faule Sau bin. schreibe ich den Empfangsbuffer direkt in einen Speicher weg und lösche den Buffer. Dann kann ich im Programm den Speicher einfach nach legalen Telegrammen durchsuchen, diese rauspflücken und das entstandene Loch wieder schliessen.

Hier ein Beispiel. Mache das halt immer in SCL ich denke aber du erkennst was der Gedanke dahinter ist.
Code:
REGION empfangen von Daten
  #Receive("PORT"    := #Serial_PORT,
           BUFFER    := #Recv_Buffer,
           NDR       => #Fut_Tel_Koppel.Recv_Koppel.Done,
           ERROR     => #Fut_Tel_Koppel.Recv_Koppel.Error,
           STATUS    => #Fut_Tel_Koppel.Recv_Koppel.Status,
           LENGTH    => #Fut_Tel_Koppel.Recv_Koppel.Recvd_Len);

IF #Receive.ERROR THEN
    FOR #i := 20 TO 1 BY -1 DO
        #RCV_F_Status[#i] := #RCV_F_Status[#i - 1];
    END_FOR;
    #RCV_F_Status[0] := #Receive.STATUS;
END_IF;

IF #Receive.NDR THEN
    "FC_Fut_FIFO_Array_fuellen"(RCVD_LEN := #Fut_Tel_Koppel.Recv_Koppel.Recvd_Len,
                                Receive := #Recv_Buffer,
                                Array := #Fut_Tel_Koppel.Recv_Koppel.Tel_Buffer);
   
    FILL_BLK(IN := b#16#0,
             COUNT := 41,
             OUT => #Recv_Buffer[0]);
    #empfangszähler += 1;
    #lastLEN := #Fut_Tel_Koppel.Recv_Koppel.Recvd_Len;
END_IF;

Code:
FUNCTION "FC_Fut_FIFO_Array_fuellen" : Void
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
   VAR_INPUT
      RCVD_LEN : UDInt;   // Menge an Bytes die vorne eingefüllt werden soll
      Receive : Array[*] of Byte;   // Daten die eingefüllt werden sollen. Es wird von Byte 0 angefangen und dann anzahl bei LEN genommen
   END_VAR

   VAR_IN_OUT
      "Array" : Array[*] of Byte;
   END_VAR

   VAR_TEMP
      untereGrenze : UDInt;
      obereGrenze : UDInt;
      Laenge : UDInt;
      index : Int;
   END_VAR


BEGIN
    #untereGrenze := DINT_TO_UDINT(LOWER_BOUND(ARR := #Array, DIM := 1));
    #obereGrenze := DINT_TO_UDINT(UPPER_BOUND(ARR := #Array, DIM := 1));
    #Laenge := #obereGrenze - #untereGrenze;
   
    // gefüllten Bereich um eingetroffene Länge nach oben schieben
    // um platz für neue Daten zu machen
    MOVE_BLK(IN:=#Array[#RCVD_LEN],
             COUNT:=#Laenge - #RCVD_LEN,
             OUT=>#Array[0]);
   
    // Neue Daten unten einfüllen.
    MOVE_BLK(IN:=#Receive[0],
             COUNT:=#RCVD_LEN,
             OUT=>#Array[#obereGrenze - #RCVD_LEN]);
   
   
END_FUNCTION

Ich mache das so weil je nach Empfangsgerät bekommt man im buffer manchmal ganze Telegramme oder das zeug halt auch nur Bytesweise. im Speicherarray habe ich dann aber dann trotzdem die ganzen Daten hintereinander, also auch komplette Telegramme und kann diese dann verarbeiten und löschen.
Du könntest auch zwei Arrays füllen, eines das du zur verarbeitung nimmtst und die Daten dann löscht wenn verarbeitet. und das andere um den Stream online zu beobachten.
 
@vollmi, du nutzt doch soweit ich mich erinnere auch die Open Controller.

Vielleicht ist das für dich relevant:
https://www.sps-forum.de/threads/sy...i-status-beobachten.110950/page-4#post-871043
Im Bezug auf folgendes:
Danke dir. Zum glück konnte ich mich von den OpenControllern trennen. Die Dinger haben nur Probleme gemacht und das Vertrauen nachhaltig zerstört.
Das
Code:
#empfangszähler += 1;
hat für die Funktion glücklicherweise keine Relevanz. Ich hau die Zähler in Verzweigungen zum Testen rein um zu schauen ob und wie oft eine Verzweigung/FOR/While/etc. durchlaufen wird
 
Also das Problem jetzt ist, dass der Status des "Receive_P2P_DB" auf 7002 hängen bleibt. Hier muss ich noch eine Lösung finden.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Das Antwort-Telegramm wird mit CR LF beendet, aber das habe ich nirgendwo eingestellt.
Ich vermute, dass da das Problem liegt.
Ich vermute, dass ich einfach im untersten Feld, siehe Bild, bei der Telegrammendesequenz bei 1. A und bei 2. D eintrage. Leider muss ich noch warten, bis ich wieder an die Anlage komme.

Alternativ würde ich die Zeitüberschreitung nutzen.
Ja und ansonsten muss ich den Stream nochmal mitloggen.

Unbenannt.jpg
 
Alternativ würde ich die Zeitüberschreitung nutzen.
Ja und ansonsten muss ich den Stream nochmal mitloggen.

Ich persönlich würde auf jeden Gall die Zeichenverzugszeit nutzen. Du kannst die Endsequenz nutzen, allerdings hast du das Ende dann nicht im Buffer. Ich persönlich nutze auch dann die Zeichenverzugszeit und werte das Ende dann in der Telegrammauswertung aus.
 
Kann man denn den Status '7002' irgendwie wieder resetten?
HW-Konfig laden, Gerät ab-/anklemmen, Neustart und AEG haben nicht geholfen...
 
Zurück
Oben