Registrieren auf Merker Flag Änderung in AGLink

lorgarn

Level-1
Beiträge
15
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,
nachdem man mir letzte Woche so großartige Hilfestellung in diesem Forum geben konnte, kann ich mittlerweile bereits mit einer realen SPS sprechen. Ich kann die Datenblöcke mit AGLink auslesen und neu beschreiben und habe auch Zugriff auf die Merkerbits, mit denen die SPS mir mitteilt, daß ein bestimmter Zustand erreicht ist, oder umgekehrt ich der SPS mitteile, daß es etwas zu tun gibt.

Meine Frage dazu ist, ob es da 'Best Practices' gibt, wie man auf die Änderung eines Merkerflags programmatisch lauscht. Ließt man das Feld zyklisch in einem Tread aus bis es sich geändert hat oder kann man einen 'EventListener' auf diese Änderung registrieren? Ich arbeite im Moment mit C# und bin grundsätzlich mit dem dort benutzen Event Mechanismus durch Delegates vertraut. Ich habe auch gesehen, daß es bereits Events in der AGLink Bibliothek gibt, diese sind aber leider nicht im AGLink Api Guide dokumentiert. In den Beispielen werden sie benutzt aber ich verstehe das im Moment so, daß damit nur eine asynkrone Kommunikation geschaffen wird und nicht auf eine Bestimmte Änderung gewartet wird.

An anderer Stelle hier im Forum habe ich gelesen, daß man bei erwarteten Änderungen besser nicht die Events benutzen sollte, sondern nur bei unerwarteten (Paperstau, Station nicht mehr erreichbar, etc.)

Ich würde gerne Meinungen bzw. Beispiel dazu hören.

Mit freundlichem Gruß
Lorgarn
 
Also ich frage immer alles nur zyklisch ab, aber ein besserer Weg in manchen Situationen wäre schon nett. Ich könnte mir da nur eine offene TCP-Verbindung vorstellen, die meldet, dass sich das Bit geändert hat. Müsste halt leider auch auf der SPS programmiert werden.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Normalerweise liest man Zyklisch ein! Es gibt zwar auch die möglichkeit das die Sps Bits pusht, glaube sogar das dies auf geänderte beschränkt werden kann, jedoch können dies nicht alle Cpus und auch nur für wenige Bytes
 
Hallo zusammen,
erteinmal Danke für die Antworten, auch wenn sie mir im Moment nicht ganz klar sind.

Also ich frage immer alles nur zyklisch ab, aber ein besserer Weg in manchen Situationen wäre schon nett. Ich könnte mir da nur eine offene TCP-Verbindung vorstellen, die meldet, dass sich das Bit geändert hat. Müsste halt leider auch auf der SPS programmiert werden.
Ich hatte angenommen daß wir so eine Verbindung mit der AGLink Bibliothek hergestellt haben. Wieso muß dazu was auf der SPS programmiert werden?

Normalerweise liest man Zyklisch ein! Es gibt zwar auch die möglichkeit das die Sps Bits pusht, glaube sogar das dies auf geänderte beschränkt werden kann, jedoch können dies nicht alle Cpus und auch nur für wenige Bytes
Was meinst Du damit, daß die SPS Bits Pusht? Wie die SPS ihre Flags setzt darauf hab ich keinen Einfluß. Mich interessiert ein praktisches Anwenderbeispiel, diese Änderungen auf C# Seite auszulesen.

Gruß
Lorgarn
 
Hallo,
ich habe jetzt nicht so genau verstanden, wo du hinwillst. Ich vermute aber, dass du die Variablen und deren Animation im Script trennen willst.
Hierzu würde ich mir ein ValueChanged-Event generieren, ggf. sogar mit eigenen EventArgs, die mir den Status (z.B.) mitteilen.
Das geht natürlich nur, wenn du dir den jeweils "letzten Zustand" der Variablen in deiner zyklischen Einleseroutine "merkst" ...

Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,
ich habe jetzt nicht so genau verstanden, wo du hinwillst.
Ok ich beschreibe es mal konkreter. Die SPS stellt per RFID fest, daß ein Bauteil auf einer Station steht. Dieses muß ich in meinem C# Programm mitbekommen (so wie ich es bisher verstehe darüber, daß sich ein Merker-Flag geändert hat). Ich lese nun zu diesem Zeitpunkt einen Datenbereich aus der SPS aus, mache Einträge auf einer Datenbank und sage danach der SPS bescheid (auch wieder über eine MerkerFlag), daß die Operation abgeschlossen ist und das Bauteil auf die nächste Station fahren kann.
Ich kann das selbstverständlich selber in einem delegate Event in einem eigenen Thread prüfen, indem ich halbsekündlich das entsprechende Flag lese und das Event feuere, wenn sich der Wert ändert. Meine Frage ist einfach, ob das üblich ist das so zu machen, oder ob es da aus Eurer Erfahrung andere, bessere Herangehensweisen ergeben haben.

Gruß
Lorgarn
 
Naja ...
Wenn du die Dinge voneinander trennen möchtest dann wäre das der Ansatz.
Du hast einmal eine Routine, die die gewünschten / benötigten Variablen aus der SPS herausliest (wenn es komfortabel funktioniert dann könnte man es Item-Server nennen).
Willst du die Funktions-Logik der Variablen nicht dort machen, wo du die Variable ausliesst, dann wäre ein Event m.E. der richtige Ansatz.
So, wie du es jetzt zuletzt aber beschrieben hast wäre der Teil der Funktion ja eine unmittelbare Reaktion auf das Einlesen.
Was gefällt dir denn selbst noch am Ehesten ?

Gruß
Larry
 
Hallo,
es geht nicht unbedingt darum was ich lieber habe ^^.
Ich habe einen WCF Service, der einzelne grafische Anwendungen auf Industrie PCs an den einzelnen Stationen der Fertigungsstraße mit Informationen versorgt. Der Service hat weiterhin eine Anbindung an eine Datenbank und über die AGLink DLL an die SPS. Es kann praktisch zu jeder Zeit passieren, daß eine Station auf der Fertigungstraße meldet, daß ein Bauteil angekommen ist. Die Funktionen von AGLink hab ich in eine einzelne Klasse gekapselt, damit ich später komplexere Abfragen einfach per Funktion darauf abbilden kann. Dazu habe ich mir jetzt eine Threadklasse gebaut:
Code:
internal class FlagThread
    {
        //int conNr;
        int startBit;
        int offset;
        Byte[] expected;
        AGWrapper parent;

        public delegate void flagChanged();
        public event flagChanged changed;

        FlagThread(AGWrapper p, int start, int end, Byte[] exp) {
            parent = p;
            startBit = start;
            offset = end;
            expected = exp;
        }

        public void testForChange()
        {
            while (parent.readFlagBytes(startBit , offset) != expected  ) {
                System.Threading.Thread.Sleep(500);
            }
            changed();
        }
    }

Von diesen Objekten kann ich nun für jede Station eines erstellen und auf das Event warten, z.B.:

Code:
 testi() {
            Console.WriteLine("ThreadTest");
            Byte[] res = new Byte[2];  //muß eigentlich noch gefüllt werden
            FlagThread station1 = new FlagThread(agobjekt, 14, 2, res);
            station1.changed += new FlagThread.flagChanged(eventIsDone);
            Thread myThread = new Thread(station1.testForChange);
            myThread.Start();
        }

        static void eventIsDone()
        {
            //Hier lesen aus Datenblock
            //Schreiben in Datenbank
            //whatever...
        }
    }
Meine Frage ist nur, ob ich das Rad hier gerade neu erfinde. Kann mir nicht so recht vorstellen, daß ich der erste bin, der sowas versucht.

Gruß
Lorgarn
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hm schade, hätte gedacht da gibt es mehr Erfahrungswerte. Ich kann morgen meine Testsuit mit der SPS reden lassen, dann werde ich sehen wie gut das funktioniert.
Gibt es wenigstens irgendwo eine Dokumentation der Events in AGLink? Der API Guide listet leider nur Funktionen auf...

Gruß
Lorgarn
 
Hi Lorgarn,
Wenn du AGLink installiert hast, hast du die Dokumentation als PDF unter "Start->Programme->DELTALOGIC->ACCON-AGLink->Doku->Referenz.NET.pdf". Da gibt es eine Auflistung aller verfügbarer Ereignisse und die gesamte Dokumentation der Funktionen die vom .NET-Bereich angeboten werden.

Mfg,
Voddy
 
Hallo,
in dem Dokument hatte ich bereits einen Mechanismus gefunden nämlich NCK_StartCyclicRead. Ich vermute, daß ich das dann asynkron wie in dem einfachen asynkronen Beispiel was im Lieferumfang enthalten ist benutzen muß und mir dann ein passendes Event heraussuchen muß. Außer den Namen der Events gibt es nämlich nicht so recht Beschreibungen was die tun.
Mein oben beschriebene Lösung hat den 'Realtest' heute morgen überstanden. Ich werde mir daher diese CyclicRead Funktion bis Montag mal anschauen und mir dann überlegen, mit welcher Methode ich weiter vorgehe.

Gruß
Lorgarn
 
Zuviel Werbung?
-> Hier kostenlos registrieren
NCK_StartCyclicRead ist wie der Name schon sagt für NCKs (Sinumerik CNC) gedacht - diese haben einen "Überwachungssupport" im Protokoll drinn - deswegen gibt es dafür einen Funktion in AGLink - mit einer SPS (Simatic) hat das nichts zu tun

Deine Lösung sieht schon ganz gut aus - wobei ich nicht jeden Thread einen einzelnen Read machen lassen wuerde - eher mit ReadMix mehrere Merker zusammenfassen und dann per Timer abfragen und die Eventverteilung am Ende des Timers machen - aber auch nur dann
wenn wir hier nicht von ein paar wenigen Merken reden

der API Guide ist auch eine gute Orientierung
 
Zuletzt bearbeitet:
Die NCK kann das, einige SPSen können das ein bischen und dann auch nur bei Daten. Ich selbst würde an Deiner Stelle zyklisch lesen und die Auswertung machen. Dies geht überall. Ansonsten würde ich mir mal speziell die OnReadMixCompleted- bzw. OnReadMixExCompleted-Events sowie das gesamte .net-Handbuch genauer ansehen.
 
Zurück
Oben