none
Anfängerfrage - Windows Forms Methode Funktioniert, läuft aber als eigenständige Klasse nicht RRS feed

  • Frage

  • Hallo, ich will eine Verbindung zu einem Laufzeitsystem aufbauen. Das funktioniert wenn ich die Klasse Form1.CS nutze.

    Wenn ich das ganze nun in einer neuen Klasse schreibe und dann in Program.cs aufrufe, dann klappt das nicht.

    Meine Klasse ist public. die Daten für die Laufzeitumgebung sind konstant und es wird nur eine Variable beschrieben.

    Wie muss ich das nun in Program.cs schreiben? die Klasse heists ADS

    Ich bin leider noch totaler anfänger und komme aus der SPS programmierung...

    Mittwoch, 27. April 2011 15:17

Antworten

  • Hallo G.,
    erstmal wird Dein "new ADS()" erst nach dem Schliessen der Hauptform aufgerufen, was wahrscheinlich nicht so sein soll.
    Ergo kann man das besser nach InitializeComponent in die HauptForm (bei Dir Form1) stellen.
    Der Aufruf selber sollte gar nicht gross verändert werden, sondern normal eher so belassen werden:
     static class Program
     {
     /// <summary>Der Haupteinstiegspunkt für die Anwendung.</summary>
     [STAThread]
     static void Main()
     {
      Application.EnableVisualStyles();
      Application.SetCompatibleTextRenderingDefault(false);
      Application.Run(new Form1());
     }
     }
    
    ______
    In der Form1 dann zum Beispiel:
     public partial class Form1 : Form
     {
     public Form1()
     {
      InitializeComponent();
      // using Boom_2704;
      ADS ads = new ADS();
      // ggf. jetzt noch die Open_ADS Methode public machen:
      //  public void Open_ADS()
      // um sie dann hier mit:
      //  ads.Open_ADS();
      // aufrufen zu können.
     }
     }
    
     
    Allgemeine Hinweise und Beispiel-Downloads auch:
    [TwinCAT Quick Start - Beispiel Maschine mit Microsoft Visual C#]
    http://infosys.beckhoff.com/content/1031/tcquickstart/html/tcquickstart_samplecsharp.htm

    ciao Frank
    Mittwoch, 27. April 2011 15:53

Alle Antworten

  • Post Code!

    Deiner Klasse fehlt wahrscheinlich die Referenz auf eine Instanz, die im Formular bekannt ist.


    Thorsten Dörfler
    Microsoft MVP Visual Basic
    vb-faq.de
    Mittwoch, 27. April 2011 15:33
    Beantworter
  • using System;
    using System.Linq;
    using System.Collections.Generic;
    using System.Text;
    using System.IO;
    using TwinCAT.Ads;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Windows.Forms;
    
    namespace Boom_2704
    {
      public class ADS
      {
    
        private TcAdsClient tcClient;
        private bool si;
    
        private void open_ADS()
        {
    
        // -----------------------------------------------------
        // Wird als erstes beim Starten des Programms aufgerufen
        // -----------------------------------------------------
    
          try
          {
            // Eine neue Instanz der Klasse TcAdsClient erzeugen
            tcClient = new TcAdsClient();
            tcClient.Connect(801); // Verbinden mit lokaler SPS - Laufzeit 1 - Port 801
          }
          catch
          {
             MessageBox.Show("Fehler beim Laden");
          }
    
          // ---------------------------------------------------- 
          // -------------------- READ PLC DATA ----------------- 
          // ---------------------------------------------------- 
    
          bool Drives = (bool)tcClient.ReadSymbol(".Drives_ON", typeof(bool), si);
    
          tcClient.WriteSymbol(".Drives_Order", true, si);
    
    
          // ---------------------------------------------------
    
          if (Drives == true)
            tcClient.WriteSymbol(".PROGRAM_ACTIVE", true, si);
          else
            tcClient.WriteSymbol(".PROGRAM_ACTIVE", false, si);
    
          // ---------------------------------------------------
        }
     
      }
    }
    _____________________________________________
    using System;
    using System.Linq;
    using System.Collections.Generic;
    using System.Windows.Forms;
    using System.IO;
    using TwinCAT.Ads;
    
    namespace Boom_2704
    {
      static class Program
      {
        /// <summary>
        /// Der Haupteinstiegspunkt für die Anwendung.
        /// </summary>
        [MTAThread]
    
        static void Main()
        {
          Application.Run(new Form1());
          ADS ADS_1 = new ADS(); // Klasse
        }
      }
    }
      
     _____________________________________________
    
    
    
    
    
    
    
    
    
    
    
            
    
    Mittwoch, 27. April 2011 15:35
  • Hallo G.,
    erstmal wird Dein "new ADS()" erst nach dem Schliessen der Hauptform aufgerufen, was wahrscheinlich nicht so sein soll.
    Ergo kann man das besser nach InitializeComponent in die HauptForm (bei Dir Form1) stellen.
    Der Aufruf selber sollte gar nicht gross verändert werden, sondern normal eher so belassen werden:
     static class Program
     {
     /// <summary>Der Haupteinstiegspunkt für die Anwendung.</summary>
     [STAThread]
     static void Main()
     {
      Application.EnableVisualStyles();
      Application.SetCompatibleTextRenderingDefault(false);
      Application.Run(new Form1());
     }
     }
    
    ______
    In der Form1 dann zum Beispiel:
     public partial class Form1 : Form
     {
     public Form1()
     {
      InitializeComponent();
      // using Boom_2704;
      ADS ads = new ADS();
      // ggf. jetzt noch die Open_ADS Methode public machen:
      //  public void Open_ADS()
      // um sie dann hier mit:
      //  ads.Open_ADS();
      // aufrufen zu können.
     }
     }
    
     
    Allgemeine Hinweise und Beispiel-Downloads auch:
    [TwinCAT Quick Start - Beispiel Maschine mit Microsoft Visual C#]
    http://infosys.beckhoff.com/content/1031/tcquickstart/html/tcquickstart_samplecsharp.htm

    ciao Frank
    Mittwoch, 27. April 2011 15:53
  • Danke, das war wirklich sehr hilfreich. Hast du noch einen Tip wie ich die Laufzeitumgebung zyklisch aktualisieren kann?
    Mittwoch, 27. April 2011 16:18
  • Hallo G.,

    • Danke, das war wirklich sehr hilfreich.

    gern, das konnte ich tun, weil Du den Code (und Hintergründe) auf Thorstens Anfrage gepostet hattest.

       

    • Hast du noch einen Tip wie ich die Laufzeitumgebung zyklisch aktualisieren kann?

    es könnte bei dieser Frage mehreres gemeint sein. Normal solltest Du hier in den meisten Fällen über Änderungs-Ereignisse und deren Handler-Methoden unter .NET arbeiten - und das geht auch mit der TwinCat-Library 

    Mit der Methode TcAdsClient.AddDeviceNotification() kann man eine Verbindung zu jeder Variablen in der SPS erzeugen.
    Man kann mit AdsTransMode.OnChange festgelegen, dass die SPS-Variable nur übermittelt wird falls sich der Wert in der SPS geändert hat (siehe AdsTransMode ). Der Parameter cycleTime bestimmt dann, wie oft die PLC checken soll, ob sich die entsprechende Varaiable geändert hat. [-> TcAdsClient.AdsNotification Event] abonnieren und in dessen Handler (z.B. tcClient_OnNotification) ggf. Aktualisierungen durchführen.

      // Erstellen eines Events für Änderungen an den SPS-Variablen-Werten 
      tcClient.AdsNotification += new AdsNotificationEventHandler(tcClient_OnNotification);
    
    

    siehe zum Beispiel [hier] und weitere Themen im linken Menü-Frame der Webseite.

     


    ciao Frank
    Mittwoch, 27. April 2011 17:47
  • ja das kenne ich. es gibt aber auch das Beispiel Merker synchron aus der SPS lesen.

    Hier wird aber nur der Wert über die Konsole ausgegeben und mit tcClient.ReadAny( INDEXGROUP, INDEXOFFSET, TYPE)

     

    ist das symbolisch mit Windows Forms nicht möglich?

    Donnerstag, 28. April 2011 07:35