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

Results 1 to 9 of 9

Thread: Twincat ADS-Notifications im Thread

  1. #1
    Join Date
    23.07.2003
    Posts
    248
    Danke
    29
    Erhielt 16 Danke für 13 Beiträge

    Default


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Hi ...

    hat jemand schon mal mit ADS in einem separaten Thread gearbeitet ? Ich starte einen Backgroundworker (oder Thread, kommt aufs gleiche raus) und geb ihm ein paar Events (AmsRouterStateChanged, AdsStateChanged, ADSIGRP_SYM_VERSION)...

    Diese Events werden aber NIE gestartet, egal was mein Ams-Router macht ... wenn ich das ganze ganz normal in einem mainform_load aufrufe funktioniert es Problemlos.

    Hat das jemand schon mal gemacht ? Ach ja C#, bevor ichs vergess...

    Die ganze Zeit hab ich in einem Timer gearbeitet, bringt natuerlich leichte Nachteile mit sich ...

    danke
    michael
    Reply With Quote Reply With Quote Twincat ADS-Notifications im Thread  

  2. #2
    Join Date
    24.04.2008
    Location
    Lübeck
    Posts
    338
    Danke
    11
    Erhielt 68 Danke für 65 Beiträge

    Default

    Events werden dort abgearbeitet, wo sie aufgerufen werden!

    Also werden die Events immer in dem Thread gefeuert und die angehängten Methoden in dem Thread abgearbeitet, in dem der ADS Client erzeugt wurde.

    Ich würd das spontan so machen, dass ich für jeden Event eine Methode habe, in der vom ThreadPool dann ein Thread genommen wird um darauf zu reagieren:

    Code:
    protected virtual void OnNotification (AdsNotificationEventArgs e)
    {
        ThreadPool.QuequeUserWorkItem(NotificationCallback, e);
    }
    
    public void NotificationCallback (object state)
    {
        AdsNotificationEventArgs args = (AdsNotificationEventArgs)state;
        
        // Do something...
    }
    Keine Garantie auf Richtigkeit, aber sollte schon grob passen und erklären was ich meine.

  3. #3
    nekron is offline Erfahrener Benutzer
    Themenstarter
    Join Date
    23.07.2003
    Posts
    248
    Danke
    29
    Erhielt 16 Danke für 13 Beiträge

    Default

    Moin moin Neals,

    also irgendwie bin ich anscheinend doch zu unbewandert in dem ganzen um das zu verstehen ...

    Kannst du mir eventuell mit einem konkreteren Beispiel dienen ?

    danke
    michael

  4. #4
    Join Date
    24.04.2008
    Location
    Lübeck
    Posts
    338
    Danke
    11
    Erhielt 68 Danke für 65 Beiträge

    Default

    Moin hört sich gut an, bin auch Norddeutscher

    Hab das Beispiel 8 aus dem InfoSys mal erweitert...

    Hier das Beispiel: http://infosys.beckhoff.com/content/...S_Sample08.exe

    Hier meine Erweiterung:

    Code:
            void AmsRouterNotificationCallback(object sender, AmsRouterNotificationEventArgs e)
            {
                // Thread aus dem ThreadPool beauftragen
                ThreadPool.QueueUserWorkItem(RouterNotificationCallback, e);
            }
    
            // Diese Funktion wird vom Thread ausgeführt
            private void RouterNotificationCallback(object e)
            {
                // Daten umwandeln
                AmsRouterNotificationEventArgs args = (AmsRouterNotificationEventArgs) e;
    
                if(args.State == AmsRouterState.Stop || args.State == AmsRouterState.Removed)
                {
                    // Verbindung abbrechen und versuchen neu aufzubauen oder so...
                }
    
                // Aus einem Thread auf Form zugreifen
                BeginInvoke((MethodInvoker) delegate
                    {
                         _routerLabelValue.Text = args.State.ToString();
                    });
            }

  5. Folgender Benutzer sagt Danke zu Neals für den nützlichen Beitrag:

    nekron (01.12.2008)

  6. #5
    nekron is offline Erfahrener Benutzer
    Themenstarter
    Join Date
    23.07.2003
    Posts
    248
    Danke
    29
    Erhielt 16 Danke für 13 Beiträge

    Default

    Moin moin Neals,

    bin zwar kein Norddeutscher, verbringe aber recht viel Zeit dort oben

    Ups - da haben wir mächtig aneinander vorbeigeredet ....

    Mein Problem ist ein ganz anderes ... Ich starte einen Thread, der eine Verbindung zum Twincat öffnet, dann ein paar Events um einen Verbindungsabbruch zu erkennen... Diese werden aber im Gegensatz zum Starten aus dem Haupt-Thread ( -> Applikation) nie aufgerufen ...

    Code:
    
    publicvoid _worker()
    {
    TcAdsClient _tcClient = newTcAdsClient();
    AdsStream dataStream = newAdsStream(30);
    while (true)
    {
    try
    {
    if (!_tcClient.IsConnected)
    {
    _tcClient.Connect(801);
    _tcClient.AddDeviceNotification(0xF008, 0x0, dataStream, AdsTransMode.OnChange, 500, 500, 0);
    _tcClient.AdsNotification += newAdsNotificationEventHandler(_tcClient_AdsNotification);
    _tcClient.AdsStateChanged += newAdsStateChangedEventHandler(_tcClient_AdsStateChanged);
    _tcClient.AmsRouterNotification += newAmsRouterNotificationEventHandler(_tcClient_AmsRouterNotification);
    }
    System.Threading.Thread.Sleep(100);
    }
    catch (AdsErrorException ex)
    {
    // ...
    }
    }
    }
    
    Das ganze jetzt ohne Retry-Time usw ... auf jeden Fall werden die Notifications nicht aufgerufen ...

    Hast Du dazu eine Idee ??

    danke
    michael

  7. #6
    Join Date
    24.04.2008
    Location
    Lübeck
    Posts
    338
    Danke
    11
    Erhielt 68 Danke für 65 Beiträge

    Default

    Wenn deine Funktion worker in einem Thread laufen würde, währe sie ja durchgehend dabei, neu zu connecten und den Events immer wieder die gleiche Funktion zuzuweisen. Das heißt die währe dann 10 - 20 mal oder so auf dem Event und wenn das Event gefeuert wird, wird die Funktion 10 mal ausgeführt.

    Ich würde sagen die Funktionen in der Schleiße sind fehl am Platze...

    Habs mal so gemacht:

    Code:
        public partial class Form1 : Form
        {
            private TcAdsClient tcClient;
            private AdsStream adsStream;
            private BinaryReader binRead;
            private int notificationHandle;
            Thread adsThread;
    
    
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                
                try
                {
                    adsThread = new Thread(AdsThread);
                    adsThread.Start();
                }
                catch (AdsErrorException ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
    
            private void AdsThread()
            {
                tcClient = new TcAdsClient();
    
                /* connect the client to the local PLC */
                tcClient.Connect(801);
    
                adsStream = new AdsStream(2);                /* stream storing the ADS state of the PLC */
                binRead = new BinaryReader(adsStream);    /* reader to read the state data */
    
                /* register callback to react on state changes of the local AMS router */
                tcClient.AmsRouterNotification +=
                                        AmsRouterNotificationCallback;
    
    
                notificationHandle = tcClient.AddDeviceNotification(
                                            (int)AdsReservedIndexGroups.DeviceData,    /* index group of the device state*/
                                            (int)AdsReservedIndexOffsets.DeviceDataAdsState, /*index offsset of the device state */
                                            adsStream,    /* stream to store the state */
                                            AdsTransMode.OnChange,    /* transfer mode: transmit ste on change */
                                            0,    /* transmit changes immediately */
                                            0,
                                            null);
    
                /* register callback to react on state changes of the local PLC */
                tcClient.AdsNotification += OnAdsNotification;
    
                while (tcClient.IsConnected)
                {
                    Application.DoEvents();
                    Thread.Sleep(50);
                }
            }
    
            /* callback function called on state changes of the PLC */
            void OnAdsNotification(object sender, AdsNotificationEventArgs e)
            {
                if (e.NotificationHandle == notificationHandle)
                {
                    AdsState plcState = (AdsState)binRead.ReadInt16(); /* state was written to the stream */
                    BeginInvoke((MethodInvoker) delegate
                                                    {
                                                        _plcLabelValue.Text = plcState.ToString();
                                                    });
                }
            }
    
            /* callback function called on state changes of the local AMS router */
            void AmsRouterNotificationCallback(object sender, AmsRouterNotificationEventArgs e)
            {
                BeginInvoke((MethodInvoker) delegate
                                                {
                                                    _routerLabelValue.Text = e.State.ToString();
                                                });
            }
    
            private void _exitButton_Click(object sender, EventArgs e)
            {
                Close();
            }
    
            private void Form1_FormClosing(object sender, FormClosingEventArgs e)
            {
                try
                {
                    adsThread.Abort();
                    tcClient.DeleteDeviceNotification(notificationHandle);
                    tcClient.Dispose();
                }
                catch (AdsErrorException ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }

  8. #7
    Join Date
    09.03.2010
    Posts
    1
    Danke
    0
    Erhielt 0 Danke für 0 Beiträge

    Default

    No German writing here sorry,

    I had the same problem with the onnotification. The problem resides in the property TcAdsClient.Synchronize. This one should be set to false for the notification to triggered correctly.

    Although the last sample program works great, it doesn't answer completely to the originally posted question.

  9. #8
    Join Date
    24.04.2008
    Location
    Lübeck
    Posts
    338
    Danke
    11
    Erhielt 68 Danke für 65 Beiträge

    Default

    My posted code was "my" best practice.

    If you set the property Synchronize to true, the client tries to fire all events in the main-thread.

    Which question is not answered yet?

  10. #9
    Join Date
    03.02.2009
    Posts
    7
    Danke
    0
    Erhielt 0 Danke für 0 Beiträge

    Default


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Nochmal hallo in die kompetente Runde,

    vielleicht kann ich diesen älteren Thread mit meinem Multi-Threading Problem nochmal etwas aufwärmen...
    Ich habe genau das gleiche Problem wie oben geschildert und habe alle Vorschläge durchprobiert.
    Mein Hauptunterschied ist allerdings das ich ein WPF XAML Frontend entwickle und da sieht das alles mit den Nachrichtenbearbeitungsschleifen etwas anders aus.

    Als funktionierende Alternative "polle" ich derzeit im Bulk-Verfahren. Aber die Round-Trip Zeiten sind gähnend langsam. Gefühlte 300 ms (für nur 7 bool Variablen - die wie gesagt alle in einem Rutsch übertragen werden).

    Wer hat hier einen Tipp für mich?

Similar Threads

  1. TwinCAT ADS / Projekte via ADS laden
    By cayen in forum CODESYS und IEC61131
    Replies: 5
    Last Post: 30.05.2017, 10:08
  2. Replies: 9
    Last Post: 28.11.2014, 10:59
  3. Verwendung von ADS Notifications mit BC9000
    By Swampler in forum CODESYS und IEC61131
    Replies: 1
    Last Post: 21.11.2011, 12:39
  4. TwinCat ADS
    By Bigchaqy in forum CODESYS und IEC61131
    Replies: 9
    Last Post: 08.10.2011, 23:46
  5. Twincat ads
    By Simo in forum CODESYS und IEC61131
    Replies: 6
    Last Post: 23.03.2009, 17:49

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •