TwinCat 3: Emergency Message

klausbre

Level-1
Beiträge
54
Reaktionspunkte
17
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo und guten Abend,

ich schreibe aktuell einen Baustein zur Anbindung von Yaskawa-Sigma7-Servos an eine Beckhoff-Steuerung. Die Kommunikation läuft über EtherCat.
Das klappt auch wirklich hübsch inzwischen, allerdings macht mir das Error-Handling Kopfzerbrechen. Dabei geht es mir um die im Regler anfallenden
Fehlermeldungen, die im Prinzip per SDO aus einem Objekt gelesen werden können.

1) in dem Vorgängerbaustein unter CANopen hatte ich einen Zugriff auf die von der Steuerung empfangenen Daten des Emergency Telegramms.
Hier findet sich u. a. der Fehlercode des Regler wieder. In der Beckhoff-Hilfe wird auch öfters von diesem gesprochen und die empfangenen Daten
landen auch im Output-Bereich von Twincat, aber ich finde einfach nicht, wie ich diese Daten von meinem SPS-Programm aus abholen kann.
Gibt es da eine Möglichkeit.

2) das zweite Problem ist ein wenig merkwürdig und es ist mir nicht ganz klar, ob die Steuerung oder der Servo dies erzeugt: mit dem Auftreten
eines Fehler springt der Regler aus dem Zustand Operational heraus und tauscht keine PDOs mehr aus. Man kann nun in der Steuerung einen
automatischen Neuverbindungsversuch anhaken ... aber so richtig hübsch ist das nicht. Dies führt im Regler zu einem neuen Fehler
(einem Kommunikationsfehler), der den ursprünglichen überschreibt. Kann man das Verhalten irgendwie einstellen?

Vielen Dank
K. Kilper
 
Hallo allerseits,

Frage 2 hat sich inzwischen geklärt. Dies ist ein Bug in der Reglerfirmware, der herstellerseitig gelöst werden wird.

Nach wie vor würde mich aber interessieren, wie man den Inhalt des Emergency-Telegramms unter Twincat herankommt.

Viele Grüße
Klaus Kilper
 
@Paulchen: Dein Link führt zum CANOpen Master.
Was Klausbre allerdings fragt ist die Emergency-Nachricht vom EtherCAT-Device. Diese sind standardisiert, ich habe sie auch ab- und an schon gesehen aber mir sie noch nie logisch in ein PLC-Programm (o.ä.) integriert.

@Klausbre: Die CANOpen Emergency Lösung ist wichtig damit eine Info tatsächlich auf dem Bus übermittelt werden. Bei EtherCAT sind aber alle Prozesstelegramme zyklisch sodass du immer eindeutig weisst ob der Slave betriebsbereit ist (WcState = 1 und State = OP).

Guga
 
Hallo,

meinst du diesen Telegrammaufbau, Guga?
http://infosys.beckhoff.com/content/1031/cx805x_hw/2037671691.html?id=24222615214316414213

Die Emergency-Nachricht sieht dann so aus:
Struktur der Emergency-Nachricht
Das Emergency-Objekt ist stets 8 Byte lang; es enthält zunächst den 2-Byte Error Code, dann das 1-Byte Error Register und schließlich den 5 Byte großen Additional Code. Dieser teilt sich in ein 2-Byte Bitfeld und ein 3-Byte Parameterfeld auf:
11-bit Identifier
8 Byte Nutzdaten
0x80 (128[SUB]dez[/SUB]) + Node-ID
EC0
EC1
EReg
Bitfeld0: Comm
Bitfeld1: DevErr
EMCY Trigger
Info0
Info1
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hi Paulchen,

die Emergency-Objekte werden von den EtherCAT-Slaves geworfen. Das passiert klassischerweise wenn die Konfig nicht stimmt. Der Mechanismus ist von CAN abgeleitet. Wie gesagt macht es bei CAN sehr viel Sinn um sicherzustellen das die Info auch im Master ankommt. Im EtherCAT bin ich mir hier nicht sicher das es relevant ist.

Wenn der EtherCAT-Master den Slave nicht zum laufen bringt sehe ich die Ursache en Detail. Wenn der Slave noch antwortet (PreOp oder höher) dann ist im allgemeinen der Fehler auch irgendwo in einem CoE-Objekt im Slave hinterlegt. Wenn der Slave nicht kommuniziert... ist eh alles hinfällig.

Da aber einige EtherCAT-Implementierungen eine Portierung von einem CANopen Device zu grunde liegt haben einige Hersteller die Emergency-Telegramme im Slave. Dein Link zielt wieder auf CAN... hat also nichts mit EtherCAT zu tun.

Guga


emergency.jpg
 
Hi Guga,
danke für den Hinweis. Habe es nicht richtig gelesen und dachte, der Servo läuft als CAN-Slave.
Direkt im Ethercat sollte es doch noch einfacher sein!?
Wenn das Gerät es zulässt, müsste doch ein Zugriff über CoE / ADS möglich sein.
Gibt es keine Beschreibung der Daten auf dem Gerät?
Gruß Paulchen
 
Ich weiß der Thread ist alt, aber ich stehe aktuell vor einem sehr ähnlichen Problem.

Verstehe ich das richtig so, das man unter EtherCAT die Emergency Nachrichten nicht benötigt weil die Fehler auch an andere Stelle im Slave abrufbar sind und einfach zyklisch gepollt werden können?
Unter Codesys gibt es die Möglichkeit die letzte Emergency Msg auszulesen (IoDrvEtherCATLib.ETC_CO_Emergency : struct), unter TwinCat fehlt mir diese Möglichkeit jedoch...


Mein Aufbau soll gleichermaßen mit Codesys 3.5 und Beckhoff Tc3.1 Steuerungen laufen und die gleichen Funktionalitäten bieten. Die Programmarchitektur wird daher bis auf herstellerspez. Lib. Bausteine gleich sein.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Unterstützt dein Regler ein Standard Protokoll wie das CiA402? also mit controlWord und statusWord?
Falls ja kannst du doch im Statuswort das Fehlerbit pollen, das sollte ja zyklisch kommen und dann wenn es kommt dieses Diagnosedatum rauflesen.
Normalerweise ist das einfach ein Parameter mit Index und Subindex den liest du mit dem Baustein FB_ECCoESdoRead (https://infosys.beckhoff.com/content/1031/tcplclib_tc2_ethercat/56996235.html) ein.

Falls kein Standardprotokoll hinterlegt ist, kannst du sicher irgendein Fehler/Warnungs Bit in das zyklische Abbild geben und dann pollst du eben dieses.

Wir mussten uns eigentlich für jeden CoE-fähigen Controller deren spezifisches ErrorHandling einbauen. Am schönsten war bis jetzt immer noch das von der ETG standardisierte Format, das ist so ähnlich aufgebaut wie oben erklärt -> ein Datum aus ein paar Byte (kein Standard-Datentyp). Den liest man in ein Array of Byte ein und mit einem Union kannst du dann gemütlich aus der parallel liegenden Struktur auf die Daten zugreifen.

Sg
 
Wir mussten uns eigentlich für jeden CoE-fähigen Controller deren spezifisches ErrorHandling einbauen. Am schönsten war bis jetzt immer noch das von der ETG standardisierte Format, das ist so ähnlich aufgebaut wie oben erklärt -> ein Datum aus ein paar Byte (kein Standard-Datentyp). Den liest man in ein Array of Byte ein und mit einem Union kannst du dann gemütlich aus der parallel liegenden Struktur auf die Daten zugreifen.

Sg

Der Teil mit dem spezifischen ErrorHandling beruhigt mich schon mal. PL möchte nämlich eine universelle Lösung - die Eierlegende Wollmichsau des Diagnosehandlings sozusagen...
Ich hatte gehofft ich könnte über das Standard Protokoll gehen und die Emergencies direkt abfangen. Der von dir vorgeschlagene Weg über Mapping SDO<->PDO war von mir auch schon als Alternative angedacht, scheint als ob mir erstmal nichts anderes übrig bleibt.

Der Teil mit dem Union erschließt sich mir allerdings noch nicht ganz, hatte vor die Daten stur in ein Byte Array zu speichern, über die Auswertung hatte ich mir bisher noch keine Gedanken gemacht :oops:
 
Najo, Mapping ist es ja eigentlich keines.
Du hast im Statuswort meist (bei Cia402 und bei SoE ziemlich ähnlich) ein ErrorBit. Dieses Statuswort kommt ja zyklisch im PDO daher.
Das kannst du nun zyklisch pollen und wenn das auf TRUE geht startest du einfach einen Leseauftrag auf dieses Fehlermeldungsobjekt (asynchron) -> reagieren solltest du freilich schon sofort nachdem es auf TRUE geht, das lesen geht ja dann nebenher.

Das mit der Union ist eigentlich recht einfach:

Du legst ein Union an z.B.:
Code:
TYPE myUnion :
UNION
  diagCode : WORD;
  diagStruct : MyDiagStruct;
END_UNION
END_TYPE

dann brauchst du noch die Struktur:

Code:
TYPE MyDiagStruct :
STRUCT
  diagByte1 : BYTE;
  diagByte2 : BYTE;
END_STRUCT
END_TYPE

Du kannst dann in das Word (oder auch eben in das Byte Array) die Daten asynchron rauflesen und sie dann gemütlich per Struktur abgreifen.

Code:
myUnionVar : myUnion;
dummyByte : BYTE;

myUnionVar.diagCode := 156;

dummyByte := myUnionVar.diagByte1;

Ich hoffe das ist so verständlich

Sg
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Naja laut Hersteller Handbuch ist es genau genommen wohl schon ein Mapping. Das StatusBIT welches angibt ob eine neue Diagnose Message vorhanden ist, liegt nicht auf PDOs wenn man es nicht explizit aktiviert. Danach taucht z.b. im TC3 Tree ein weiterer Input auf mit dem Namen bzw. Pfad "Diag History^New Message available". Das werde ich wie vorgeschlagen zyklisch pollen.

Vielen Dank für deine ausführliche Antwort!
Allerdings erschließt sich mir der Vorteil gegenüber einer Art Ringpuffer - für sagen wir mal 20 Messages á 23 Bytes - nicht ganz. Hätte die Nachrichten einfach in ein Array geschrieben und wenn bei 20 angekommen, wieder von vorn begonnen. Evtl. Vorher noch die Daten an einen Syslog-Server geschickt oder so etwas in der Art.
Einen schön kurzen, aussagekräftigen Diagnosecode erhalte ich nämlich leider nicht zurück. Es sieht sogar so aus, das es ein Bit gibt, das angibt wie die Fehlernummern zu interpretieren sind, nach DS402 bzw. 401 oder herstellerspezifisch und dementsprechend Nummern mehrfach vorkommen können.
 
Also wie gesagt wir haben bisher immer das Statuswort abgefragt und dort ein Bit gepollt. Wie auch immer du das löst, dieses "New Message available" ist wahrscheinlich eine eigene Variable im Controller und musst separat mappen, Das Statusbit bekommst du sowieso immer im Statuswort mit. Der Vorgang bei uns war der folgende, ich denke der wird bei eurem Controller ähnlich sein:
  • StatusWort Bit geht auf TRUE
  • Baustein startet mit Lesen vom Parameter (Neuester Meldungs Index)
  • Baustein liest diese Meldung in ein messageArray : ARRAY [0..18] OF BYTE; welches in einem Union parallel zu einer Struktur liegt die den selben Aufbau hat wie die Meldung. (Bei dir wäre das Array jetzt von 0..22 und die Struktur wäre halt so aufgebaut wie die Meldung aufgebaut ist => Beispiel beim ETG Standard Diag Format:
    DiagCode : Unsigned 32Bit
    Meldungstyp : Unsigned 16Bit
    TextID : Unsigned 16Bit
    Zeitstempel in [ns] : Unsigned 64Bit
    FlagParam 1 : Unsigned 16Bit
    Parameter 1 : Unsigned 8Bit
  • Diese Werte stehen jetzt binär in dem Array, jetzt müsstest du die Werte umständlich rausklötzeln.
  • Wenn die Struktur in deinem Union, die neben dem Array liegt aber jetzt genau so aufgebaut ist wie das oben beschriebene Meldungsformat, kannst du einfach gemütlich per Struktur drauf zugreifen
  • Anschließend ziehe ich als PLC den Index nach im Buffer des Controllers nach

Also eigentlich ist der Buffer ja eh schon im Regler aufgebaut, der Regler schreibt eine Nachricht rein, du liest sie aus und ziehst den Lesezeiger nach.
Vielleicht verwendet euer Regler ja den gleichen Standard: Objekt für neuesten meldungsindex : 0x2006:02, Objekt für Lesezeiger (heißt hier "Neueste Quittiermeldung"): 0x2006:03

Bei unserem Regler gibt es noch einen Parameter der beim Start der PLC ausgelesen wird, wo steht wie groß der Buffer im Regler ist (Maximale Meldungen 0x2006:01)
 
Alles klar, das heißt ich spare mir das umständliche maskieren/schieben um die Nachricht nachher auszuwerten.
Nochmals vielen Dank für die ausführliche Erläuterung!

Mit dem Buffer hast du natürlich recht, einfach den Index der neuesten Meldung auszulesen ist natürlich eine wesentlich elegantere Lösung!

Werde zur Umsetzung vermtl. frühestens nächste Woche kommen, aber bin schon sehr gespannt. Jetzt habe ich jedenfalls eine ganz gute Vorstellung wie ich es anzugehen habe! :)
 
Zurück
Oben