Auf Aktualisierung von Feldbusvariablen reagieren?

enginear

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

ich bin neu in diesem Forum und werde hier wohl zukünftig öfters mal unterwegs sein ;)

Ich habe folgende Frage: Gibt es die Möglichkeit in Codesys (3.5.16.3) automatisiert zu erkennen, wenn ein neues Datenframe über den Feldbus reingekommen ist?

In meinem konkreten Fall geht es darum einen Versuch aufzubauen bei dem die EthernetIP-Kommunikation zwischen zwei geräten getestet werden soll. Dafür sende ich Daten vom Master (Scanner) zum Slave (Adapter) und dieser sendet diese wieder zurück. Immer wenn mein Master die Daten zurück erhält würde ich gerne auf dieses Event reagieren, um dann zu kontrollieren ob die erhaltenen Daten denen der ursprünglich losgeschickten entsprechen.

Ich vermute, dass sich soetwas mit einem Event-Handler lösen lässt. Mir ist aber noch unklar wie genau ich feststellen kann, dass meine Feldbuseingangsvariablen aktualisiert worden sind.

Grundsätzlich muss es die Möglichkeit doch geben, da das Interrupt/Notification welches bei einkommenden Daten ausgelöst wird, sich ja durch ein Flag oder ähnliches bemerkbar macht.

Eine weitere Frage wäre, ob das senden und empfangen von Daten über den Feldbus parallel zu der Main-Task ablaufen kann, oder verhält es sich eher concurrent? Ersteres dürfte doch nur gehen, wenn man einen Mehrkernprozessor hat.


Vielen Dank und viele Grüße

euer neues Mitglied enginear
 
Um zu erkennen ob die gerade empfangenen Daten ungleich der zuletzt gesendeten Daten sind gibt es nur die Möglichkeit, dass du dir den Datensatz beim Senden in einen anderen Speicherbereich (DB) kopierst. Kommen nun Daten an/zurück so mußt du per Schleifendurchlauf den alten und den neuen Datensatz vergleichen. Bei einem Unterschied lößt du dann deine Aktion / dein Ereignis aus ...
Anders würde es aber auch in einer Hochsprache (z.B.) nicht funktionieren ...

Der Sende- und der Empfangsvorgang laufen asynchron zum Zyklus. Du mußt hier also schon eine Art Ablauf (oder Statemachine) umsetzen ... Denk aber daran : eine SPS bearbeitet ihr Programm grundsätzlich zyklisch ...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
@Larry Laffer :

Was genau meinst du mit (DB)?

Ich hätte dafür einfach ein Pointerarray mit den entsprechenden Datentypen angelegt und direkt mit den Adressen der Feldbusvariablen z.B. ADR(%QB100) bis ADR(%QB163) (insgesamt 64 Byte, die pro Buszyklus übertragen werden) initialisiert. Anschließend kann ich den dereferenzierten Wert der Pointer über eine Schleife in ein weiteres Array zwischenspeichern. Nach dem ankommen neuer Daten kann dann der Vergleich zwischen ankommenden Variablen und denen, im zwischengespeicherten Array durchgeführt werden. Das temporäre Array ist nötig, da ich die zu sendenden Daten verändere. Oder kann man das ganze besser lösen?

Nur wie kann ich die Daten nach dem Senden (dazu muss ich erst einmal wissen, wann gesendet wird) zwischenspeichern?

Ich dachte man könnte (wie bei Mikrocontrollern) über Interrupts, die z.B. bei einem Pin-Change ausgelöst werden auf ein solches Ereignis reagieren.

Meinst du, dass Sende- und Empfangsvorgang zum Maintask-Zyklus asynchron laufen? Bis jetzt habe ich den Eindruck, dass diese concurrent (also fühlt sich für den User oft wie parallel an, ist genau genommen aber sequenziell) ablaufen. Das kommunizieren über den Bus macht doch wahrscheinlich ein separater Controller, oder?
 
DB = Datenbaustein - kann aber sein, dass das bei CodeSys anders heißt ...

Du mußt die Daten auf alle Fälle, alleine schon für den Vergleich, irgendwo zwischenspeichern. Bei temporären Array mußt du allerdings aufpassen - ist dieses nicht ausgerechnet im Main deklariert dann verliert es, wenn es als TEMP deklariert ist, von Zyklus zu Zyklus seine Daten.
Das Beste wäre schon, wenn du dir einen Funktionsbaustein erstellst und dein Array im STAT-Bereich deklarierst ...

Das Zwischenspeichern nach dem Senden machst du dann genauso wie du es mit den Eingangsdaten schon so schön beschrieben hast.
Denk dran - du hast einen Ablauf und den setzt du am Sinnvollsten in einer Statemachine (Schrittkette oder wie immer du das nennen möchtest) um ...

Was ist deine Programmier-"Sprache" ? ST ?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ein Datenbaustein scheint eine Datenstruktur/Container in der klassischen Softwaretechnik zu sein. Da kann ich ja das Array verwenden.

Ich wusste gar nicht, dass es soetwas wie temporäre Arrays gibt (wieder was gelernt (y) ). Ich meinte damit eigentlich ein ganz normales Array, dass immer seinen Wert behält, sofern er nicht überschrieben wird oder die Steuerung abgeschaltet wird. Ich hoffe das ist auch der Fall, wenn ich es zwischen im Kopfbereich zwischen VAR und END_VAR initialisiere, da dieser Teil doch nur einmal zum Programmstart ausgeführt wird.
Ich habe es nur als temporär bezeichnet, weil die Daten, die ich darin abspeichere nur zum Zwischenspeichern für den Vergleich dienen.

Was ich noch nicht verstanden habe ist, wie ich festellen kann, dass die Daten vom Bus gesendet worden sind? Also meinst du, dass man im Code das Senden über den Feldbus explizit triggert? Deswegen weiß ich auch nicht, wie ich das in einer State Machine umsetzen soll. Bis jetzt kenne ich das nur so, dass man die Feldbustask zyklisch laufen lässt und die läuft dann im Hintergrund oder concurrent zur Maintask oder so ähnlich?

Meine Programmiersprache ist ST.
 
... Gibt es die Möglichkeit in Codesys (3.5.16.3) automatisiert zu erkennen, wenn ein neues Datenframe über den Feldbus reingekommen ist? ...
Wenn es nur dir darum geht, eine Aktualisierung der Empfangsdaten zu erkennen, dann musst du nicht den kompletten Bereich vergleichen. Es genügt, einen Watchdog mit zu schicken und auf Veränderung zu überwachen. Das sollte man auf solchen Schnittstellen nach Möglichkeit so wie so immer tun. Ein Watchdog ist im einfachsten Fall ein Togglebit, welches bei jedem Senden den Zustand wechselt. Es kann aber auch ein Zahlenwert sein, der bei jedem Senden um "1" erhöht wird, oder ein Zeitstempel etc.

Wie sieht es mit der Datenkonsistenz aus? Muss diese auch händisch gewährleistet werden?
 
Immer wenn mein Master die Daten zurück erhält würde ich gerne auf dieses Event reagieren, um dann zu kontrollieren ob die erhaltenen Daten denen der ursprünglich losgeschickten entsprechen.
@Onkel Dagobert : ich habe das so verstanden, dass sich irgendwo in den Daten etwas ändert (oder auch nicht) - in dem Fall nützt ein Togglebit nichts ...

@enginear : Wenn du den Sende-Baustein aufrufst dann gibt der auf alle Fälle ein DONE zurück wenn er gearbeitet hat. Ich würde nicht immer wieder (in jedem Zyklus) triggern - so kannst du nichts nachvollziehen. Beschäftige dich mal mit Schrittketten. In deinem Fall :
Schritt 0 : warten auf Freigabe für Ablauf (hier kannst du dann das Ganze auch abbrechen)
Schritt 1 : Daten einlesen und speichern
Schritt 2 : mit letzten Daten vergleichen und ggf. ein Event auslösen
Schritt 3 : neue Daten senden
Schritt 4 : gesendete Daten abspeichern
dann wieder zurück zu Schritt 0
 
Daran habe ich jetzt gar nicht gedacht - so tief steckt man nun schon in dem SEND - RECEIVE drin.

Okay - dann also Nachsatz : in dem Fall würden die Daten ja gesendet wenn du sie auf die Ausgangsworte geschrieben hast. In dem Fall kann man also von unmittelbar sprechen und nicht mehr azyklisch und das DONE würde entfallen ...
 
@Onkel Dagobert : ich habe das so verstanden, dass sich irgendwo in den Daten etwas ändert (oder auch nicht) - in dem Fall nützt ein Togglebit nichts ...

Die Frage war aber:
.. Ich habe folgende Frage: Gibt es die Möglichkeit in Codesys (3.5.16.3) automatisiert zu erkennen, wenn ein neues Datenframe über den Feldbus reingekommen ist? ..

Dass er anschließend die Daten auf Veränderungen überprüfen möchte, war nur eine Begründung seines Vorhabens.
... um dann zu kontrollieren ob die erhaltenen Daten denen der ursprünglich losgeschickten entsprechen..
Erkennst du es jetzt? Er erwartet genau die Daten zurück, die er gesendet hat. Bei diesem Vergleich muss er den Watchdog naturlich außen vor lassen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
@Larry Laffer und @Onkel Dagobert:
Die Daten A werden von Master zu Slave geschickt. Slave schickt Daten A (unverändert) wieder zurück zu Master. Danach werden die Daten B (unverändert) von Master zu Slave geschickt und Slave schickt Daten B (unverändert) wieder zurück zu Master. Anschließend wird wieder mit Daten A begonnen. Kontrolliert werden soll ob die Verbindung einwandfrei funktioniert. Es darf also nicht zu ungewollten Bitwechseln oder zu Verbindungsabbrüchen kommen. Man könnte ein Togglebit nehmen, aber das Hochzählen wäre sicherer, da das Übersehen einer fehlerhaften Übertragung dabei weniger wahrscheinlich ist.

Ich bin allerdings davon ausgegangen, dass eine Benachrichtigung über eingehende und ausgehende Datenframes kein Problem darstellen, da dies tatsächlich ja auch irgendwo in Codesys erfasst werden muss.

@Onkel Dagobert:
Mir ist nicht klar, was du mit Datenkonsistenz und der händischen Gewährleistung meinst.

@PN/DP: Genau. Der Feldbus läuft in der Bustask. Diese ist auf zyklisch eingestellt. Ich triggere also das Senden nicht in meiner Main. Wie würde das mit EthernetIP gehen? Gibt es da vorgefertigte Bausteine für?

Hier würde ich nur gerne wissen, ob das Senden/Empfangen von Feldbusvariablen wirklich parallel abgearbeitet wird, oder immer die festen Zyklen eingehalten werden oder aber concurrent abgearbeitet?
Also wenn sowohl Main-Task, als auch Bus-Task auf 1ms Zyklus eingestellt sind, dann wäre es mit festen Zyklen ja so:
| Main-Task 1ms | Bus-Task 1ms | Main-Task 1ms | Bus-Task 1ms | Main-Task 1ms | Bus-Task 1ms | ....

Oder concurrent:
Main-Task und Bus-Task jeweils auf 1ms eingestellt
| Main-Task kann schneller abgearbeitet werden, z.B. 400us | Bus-Task startet daraufhin früher und ist ebenfalls in 300us bereits abgearbeitet | es wird gewartet bis die 1ms der Maintask um sind (also noch 300us) | und dann startet der Main-Task wieder ...

Oder parallel:
Bus-Task und Main-Task können sich gegeneseitig zeitlich gar nicht beschränken, weil sie auf verschiedenen Kernen/Controllern durchgeführt werden.


in dem Fall würden die Daten ja gesendet wenn du sie auf die Ausgangsworte geschrieben hast. In dem Fall kann man also von unmittelbar sprechen und nicht mehr azyklisch und das DONE würde entfallen ...
Ich verstehe nicht was du mit "auf die Ausgangsworte geschrieben" meinst? Ist für das Senden nicht alleine die Bus-Task verantwortlich?
Wie kann ich das Senden selbst mit einem FB triggern?
 
@Onkel Dagobert:
Mir ist nicht klar, was du mit Datenkonsistenz und der händischen Gewährleistung meinst...
Zu dem Zeitpunkt, zu dem du die Daten vergleichst, muss Block "A" komplett übertragen worden sein. Ein Empfangsbaustein wie z.Bsp. "RECEIVE" signalisiert dir das mit "DONE". In diesem einen Moment sind die zusammen gehörenden Daten von Block "A" komplett übertragen worden und du kannst sie verarbeiten. Ich kenne aber deinen Feldbus nicht. Falls deine Daten scheibchenweise ankommen, müsstest du selbst erkennen, dass der Block komplett ist. Eventuell ginge das, in dem du eine Kennung an den Anfang und die selbe Kennung an das Ende des Blockes setzt und diese beiden beim Empfang vergleichst. Diese Kennung könnte eventuell auch der Watchdog sein, dann vorzugsweise als Ganzzahl. Idealerweise quittierst du den Empfang dann wieder beim Sender, so dass er die Freigabe bekommt, den nächsten Block zu senden.
 
Als Bus verwende ich EthernetIP. Gibt es irgendwo eine gute Doku, welche FBs von Codesys standardmäßig vorhanden sind. Ein solcher Baustein mit dem ich das Senden/Empfangen selbst triggern/erfassen kann wäre sicherlich hilfreich.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Also um das noch einmal zu verdeutlichen, da da jetzt ja ein paar Fragen im Raum stehen (auch von mir) :
- Feldbusebene haben @PN/DP und auch ich (später) so verstanden, dass du über den EtherCat die Daten an die Perepherie sendest. Hier wäre dann für dein Vorhaben Konsistenz sehr wichtig.
- Konsistenz heißt, dass alle Daten eines Datenpaketes zusammengehörig übertragen werden - beim Schreiben auf die Perepherie (Ausgangsworte) kann es dir passieren, dass nicht alles im selben Zyklus geschrieben wird, In diesem Fall müßtest du dir zusätzliche Tricks einbauen. Gleiches gilt dann natürlich genauso für die Empfängerseite, wo die Daten dann über Eingangsworte herein kommen ...
- jetzt sprichst du ja von EtherNet-IP - das heißt für mich, dass du ein Datenpaket mit SEND (oder ähnlich) versendest und mit RECEIVE (oder ähnlich) eines empfängst. Bei SEND gibt es dann ein DONE-Bit, dass idR für einen Zyklus ansteht und dir mitteilt, dass dein Datenpaket, so wie es zum Zeitpunkt des Triggers gewesen ist, verschickt worden ist. Umgekehrt gibt es beim RECEIVE dann auch wieder ein Bit (es könnte NDR heißen = new Data received), dass auch wieder nur einen Zyklus aktiv ist und dir anzeigt, dass neue Daten angekommen sind.

Als Bus verwende ich EthernetIP. Gibt es irgendwo eine gute Doku, welche FBs von Codesys standardmäßig vorhanden sind. Ein solcher Baustein mit dem ich das Senden/Empfangen selbst triggern/erfassen kann wäre sicherlich hilfreich.
Codesys ist jetzt nicht so wirklich meine Welt - ich würde aber behaupten, dass es da entweder beim Hersteller oder auch in der Software selbst Hilfe zu dem Thema gibt ...
 
jetzt sprichst du ja von EtherNet-IP
Achtung: EthernetIP ist nicht Ethernet bzw. TCP/IP. EthernetIP ist das Feldbusprotokoll von Rockwell (https://de.wikipedia.org/wiki/EtherNet/IP). Im Detail kenne ich mich mit dem Feldbusprotokoll aber nicht aus. Mit dem Namen gab es aber schon häufiger Verwirrung.

Edit: Wie gesagt, ich kenne mich mit Ethernet/IP nicht aus. Aber um EtherCAT oder Profinet muss man sich in Codesys für die Grundfunktion auch nicht groß kümmern. Würde daher annehmen, dass es für Ethernet/IP ähnlich ist. Weiß es aber nicht belastbar. Hilft dir dieses Beispielprojekt (https://forge.codesys.com/prj/codesys-example/ethernet-ip-ser/home/Home/) weiter?

Gibt es in der Ethernet/IP Spezifikation integrierte Überwachungsmöglichkeiten ähnlich bspw. zum Working Counter bei EtherCAT?

Wenn du erst auf das Rücksenden der gespiegelten Daten wartest, wäre, wie bereits vorgeschlagen, wahrscheinlich ein Vergleich der Speicherbereiche kombiniert mit einer von dir vergebenen inkrementierten Telegramm-ID und einem Watchdog zur Erkennung ausbleibender Antworten ein sinnvolles Vorgehen.
 
Zuletzt bearbeitet:
Wieso habt ihr bei Feldbus direkt auf EtherCat geschlossen? Es geht jedenfalls um EthernetIP. Wie roboticBeet schon sagte steht hier IP nicht für Internet Protocol, sondern für Industrial Protocol. Es ist also ein richtiger Feldbus mit CIP (Common Industrial Protocol).

Also ich kann die Grundfunktion in Codesys einfach zusammen klicken. Der Bustask läuft dann wohl typischerweise zyklisch. Aber ich würde es gerne selbst triggern können, wann etwas gesendet wird. Ich würde vielleicht noch ausprobieren die Bustask nicht zyklisch, sondern ereignisorientiert zu starten. Dann könnte man im Main-Programm eine Boolsche Variable als Ereignis auf True setzen und anschließend wieder auf False. Damit das aber funktioniert wäte es schon wichtig zu verstehen, wie Feldbustasks abgearbeitet werden. Ist das selbst erfahrenen SPS-Programmierern nicht bekannt oder kann man das nicht genau sagen (vielleicht übersehe ich ja was), oder woran liegt das?

@roboticBeet:
Ich werde mir das Beispiel nochmal anschauen. Vielleicht beinhält das ja die benötigten Sende- und Empfangsbausteine. Vielen Dank schonmal.

Bzgl. Working Counter: Ist eine gute Frage, die ich nicht mit Sicherheit beantworten kann. Bis jetzt habe ich nichts derartiges gefunden.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wieso habt ihr bei Feldbus direkt auf EtherCat geschlossen? Es geht jedenfalls um EthernetIP. Wie roboticBeet schon sagte steht hier IP nicht für Internet Protocol, sondern für Industrial Protocol. Es ist also ein richtiger Feldbus mit CIP (Common Industrial Protocol).
Sorry - mein Fehler ... man neigt zum Verallgemeinern ... ;) :cool:

Da ich das nicht kenne, mir aber dein Problem vorstellen kann, möchte ich dich dann mal bitten konkret zu beschreiben wie du deinen Datenblock "auf die Strecke" bringst - gerne vielleicht als Code-Snippet.
In meiner Vorstellung arbeitest du hier mit Input-Bytes (IB) und Output-Bytes (QB), die du irgendwo festgelegt hast. Sollte das anders sein so würde das ja dein Code veranschaulichen ...
Sollte es so sein, so würden diese tatsächlich zyklisch geschrieben werden - jetzt ist der Bus aber nicht direkt an den Zyklus deines Programms gebunden (er kann viel schneller oder aber auch langsamer sein). In der Folge kann es dir also passieren, dass deine Daten nicht konsistent (zusammengehörig) übertragen werden. Das ist zwar immer der komplette Block, aber es kann dir halt passieren, dass sich deine letzte Zuordnung der Bytes über 2 oder 3 Übertragungen verteilt - ich weiß gerade nicht wie ich es besser erklären soll.
Wenn du dem entgehen willst dann kannst du hier nach meiner Meinung nur mit einer Counter-Variablen arbeiten (damit du auf der Gegenseite weißt, dass es ein neuerer Datensatz ist) und zusätzlich mit einer Prüfsumme, damit du erkennen kannst, dass du Konsistenz hast.
 
Also ich kann die Grundfunktion in Codesys einfach zusammen klicken. Der Bustask läuft dann wohl typischerweise zyklisch. Aber ich würde es gerne selbst triggern können, wann etwas gesendet wird. Ich würde vielleicht noch ausprobieren die Bustask nicht zyklisch, sondern ereignisorientiert zu starten. Dann könnte man im Main-Programm eine Boolsche Variable als Ereignis auf True setzen und anschließend wieder auf False. Damit das aber funktioniert wäte es schon wichtig zu verstehen, wie Feldbustasks abgearbeitet werden. Ist das selbst erfahrenen SPS-Programmierern nicht bekannt oder kann man das nicht genau sagen (vielleicht übersehe ich ja was), oder woran liegt das?
Ich denke, dass das was Du vorhast nicht gehen wird, da es auch völlig dem Konzept eines Feldbusses widerspricht. Über einen Feldbus sollen ja grundsätzlich zyklisch Daten ausgetauscht werden und das lässt sich, meine ich zumindest, auch nicht abschalten. Diese ganze Kommunikation läuft ja auch automatisiert im Hintergrund ab und muss nicht durch Bausteine gesteuert werden.
 
Ich verstehe noch nicht ganz, was die Problemstellung mit dem Feldbus zu tun hat.
Über welche Feldbusart regen wir denn überhaupt? Etwas serielles? Direkte E/A? TCPIP?

Für das Daten hin und her schicken würde ich mir einfach eine Sequenz basteln (geht das grafisch in Codesys? Ansonsten gibts bestimmt die CASE Anweisung).

Step0: Init - Warten auf Startsignal - Ablöschen aller Sende- und Empfangsbereiche.
Step1: Sendebereich für Teil A Master->Slave füllen
Step2: Absenden
Step3: Auf Antwort vom Slave warten
Step4: Datenauswertung
Step5: Sende- und Empfangsbereich ablöschen

usw...
 
Zurück
Oben