Beispiel Maschine mit Microsoft Visual C#

Microsoft Visual Studio 2005 ist eine Entwicklungsumgebung zur Erstellung um C#-Projekten. Anhand des Maschine Beispiels werden Sie das Einbinden der TwinCAT ADS .NET Komponente mit der Programmiersprache C# (ausgeschrieben: CSharp) kennenlernen.

Erforderliche Software:

- Microsoft .NET Framework Version 2.0, mehr dazu hier
- Microsoft Visual Studio 2005
- TwinCAT 2.10

Bevor Sie das C#-Programm starten können, muss TwinCAT und das SPS-Programm aktiv sein. Ist auf Ihrem Rechner nicht Microsoft Visual Studio 2005 installiert, so müssen Sie das Microsoft .NET Framework Version 2.0 installieren. Dadurch werden die benötigten DLL's auf Ihrem System eingerichtet.

Die ersten Schritte...

Schritt für Schritt lernen Sie die Entwicklung eines C#-Programm und das Einbinden der TwinCAT ADS .NET Komponente anhand eines Beispiels kennen.

1. Neues Projekt erstellen:

Starten Sie das Visual Studio 2005. Erstellen Sie ein neues Projekt, indem Sie im Menü -> File -> New -> Project klicken. Im Dialogfeld 'New Project' können Sie ein neues Projekt auf der Basis verschiedener Vorlagen erstellen. Hier wählen Sie unter 'Project Types' die Programmiersprache Visual C# und unter den Vorlagen 'Windows Application'. Geben Sie Ihrem Projekt ein neuen Namen, in diesem Fall bitte den Namen 'Machine' eingeben. Wählen sie dann den Verzeichnispfad unter 'Location' in dem Sie ihr Arbeitsprojekt erstellen wollen.

Beispiel Maschine mit Microsoft Visual C# 1:

2. Bedienungsoberfläche erstellen

Hierzu wird zuerst eine Oberfläche in dem Design Modus der Form 'frmMachine' mit Hilfe der Toolbox erstellt. Die Einstellungen der verschiedenen Controls (wie z.B. 10 Labels, 2 Radiobuttons, 1 Progressbar, 1 PictureBox , GroupBox...) können Sie im Properties Window des Visual Studio einsehen und einstellen.

// Gruppenfelder (GroupBox)
grpDevice.Text = "";
grpCount.Text = "";
grpSpeed.Text = "Speed";

// Bezeichnungsfelder (Label)
lblMachine.Text = "Machine";
lblDeviceDown.Text = "Device Down";
lblDeviceUP.Text = "Device Up";
lblCount.Text = "0";
lblCountLabel.Text = "Count:";
lblSteps.Text = "Steps:";
lbl100Procent.Text = "100%";
lbl0Procent.Text = "0%";

// Das sind die Pfeile DeviceDown und DeviceUp mit einer anderen Schriftart und Schiftgröße (Label) 
DeviceDown.Text = "ê";
DeviceDown.Font = new System.Drawing.Font("Wingdings", 20.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(2)));
DeviceUp.Text = "é";
DeviceUp.Font = new System.Drawing.Font("Wingdings", 20.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(2)));

// ProgressBar
prgSteps.Name = "prgSteps";

// Optionsfelder (RadioButton)
optSpeedSlow.Text = "slow";
optSpeedFast.Text = "fast";
Beispiel Maschine mit Microsoft Visual C# 2:

Im oberen linken Bereich sehen Sie die beiden Ausgänge, die auch auf die Busklemmen ausgegeben werden. Unten links ist die Variable abgebildet, welche die Werkstücke zählt. Rechts können Sie mit dem Feld 'Speed' die Taktgeschwindigkeit des Motors verändern. Die Anzeige 'Steps' entspricht der Anzahl der Takte, die auf den Ausgang 1 ausgegeben werden.

3. Referenz hinzufügen

Hier muss zuerst eine Referenz namens TwinCAT.Ads.dll hinzugefügt werden. Die TwinCAT ADS .NET Komponente wird über das Menü -> Project -> Add Reference eingebunden. Um zu überprüfen ob tatsächlich die Referenz eingebunden wurde, können Sie sich im Solution Explorer (STRG + W + S) vergewissern.


Beispiel Maschine mit Microsoft Visual C# 3:

4. Quelltext bearbeiten

Nach dem Erstellen der Oberfläche und das Einbinden der TwinCAT ADS Komponente kann zum C# Quelltext gewechselt werden. In die oberste Zeilen des Quelltextes werden die benötigten Namespaces 'System.IO' und 'TwinCAT.Ads' eingefügt.

using System.IO;
using TwinCAT.Ads;


Als nächstes sind die Deklarationen innerhalb der Klasse frmMachine dran.

privateTcAdsClient tcClient;
privateAdsStream dataStream;
privateBinaryReader binReader;
private int hEngine;
private int hDeviceUp;
private int hDeviceDown;
private int hSteps;
private int hCount;
private int hSwitchNotify;
private int hSwitchWrite;


Die Methode 'frmMachine_Load' wird beim Aufruf der Windows Application gestartet. Diese Methode verbindet man, indem das Event 'Load' der Form mit der Methode im Properities Fenster verknüpft wird. In ihr werden Instanzen verschiedener Klassen erzeugt und eine Verbindung mit Laufzeitsystem 1 der Komponente TwinCAT.Ads über Port 801 hergestellt.

//-----------------------------------------------------//Wird als erstes beim Starten des Programms aufgerufen//-----------------------------------------------------private void frmMachine_Load(object sender, EventArgs e)
{
    try
    {
     // Eine neue Instanz der Klasse AdsStream erzeugen
     dataStream = newAdsStream(7);

     // Eine neue Instanz der Klasse BinaryReader erzeugen
     binReader = newBinaryReader(dataStream);

     // Eine neue Instanz der Klasse TcAdsClient erzeugen
     tcClient = newTcAdsClient();
     
     // Verbinden mit lokaler SPS - Laufzeit 1 - Port 801 
     tcClient.Connect(801);
    }
    catch
    {
     MessageBox.Show("Fehler beim Laden");
    }    

    //...


SPS Variablen verbinden:

In dem frmMachine_Load-Ereignis der Form wird mit der Methode TcAdsClient.AddDeviceNotification()eine Verbindung zu jeder Variablen in der SPS erzeugt. Das Handle dieser Verbindung wird in einem Array gespeichert. Der Parameter TransMode spezifiziert die Art des Datenaustausches. In diesem Fall wird mit AdsTransMode.OnChange festgelegt, dass die SPS-Variable nur übermittelt wird falls sich der Wert in der SPS geändert hat(siehe AdsTransMode ). Der Parameter cycleTime bestimmt, wie oft die PLC checken soll, ob sich die entsprechende Variable geändert hat. Dann werden die Variablen mit einer Methode 'tcClient_OnNotification' (die noch geschrieben werden muss) verbunden, die bei einer Änderung einer Variablen aufgerufen wird.

try
    {
    // Initialisieren der Überwachung der SPS-Variablen
    hEngine = tcClient.AddDeviceNotification(".engine", dataStream, 0, 1, AdsTransMode.OnChange, 10, 0, null);
    hDeviceUp = tcClient.AddDeviceNotification(".deviceUp", dataStream, 1, 1, AdsTransMode.OnChange, 10, 0, null);
    hDeviceDown = tcClient.AddDeviceNotification(".deviceDown", dataStream, 2, 1, AdsTransMode.OnChange, 10, 0, null);
    hSteps = tcClient.AddDeviceNotification(".steps", dataStream, 3, 1, AdsTransMode.OnChange, 10, 0, null);
    hCount = tcClient.AddDeviceNotification(".count", dataStream, 4, 2, AdsTransMode.OnChange, 10, 0, null);
    hSwitchNotify = tcClient.AddDeviceNotification(".switch", dataStream, 6, 1,  AdsTransMode.OnChange, 10, 0, null);

    // Holen des Handles von "switch" - wird für das Schreiben des Wertes benötigt
    hSwitchWrite = tcClient.CreateVariableHandle(".switch");

    // Erstellen eines Events für Änderungen an den SPS-Variablen-Werten 
    tcClient.AdsNotification += newAdsNotificationEventHandler(tcClient_OnNotification);
    }
    catch (Exception ex)
    {
    MessageBox.Show(ex.Message);
    }
}

Definition:

Zum Verbinden der Variablen wurde die Methode 'AddDeviceNotification()' verwendet.

public int AddDeviceNotification(string variableName, AdsStream dataStream, int  offset, int length, AdsTransMode transMode, int cycleTime, int maxDelay, object userData);

Zum Verbinden der Variable 'hSwitchWrite' wurde die Methode 'CreateVariableHandle' verwendet.

int TcAdsClient.CreateVariableHandle(string variableName);

Methode schreiben:

Oben wurde bereits auf eine Methode verwiesen, die noch gar nicht existiert. Daher wird diese Methode, die 'tcClient_OnNotification' genannt wurde, als nächstes geschrieben. Diese Methode wird aufgerufen, wenn sich eine der SPS-Variable geändert hat.

//------------------------------------------------//wird bei Änderung einer SPS-Variablen aufgerufen//------------------------------------------------private void tcClient_OnNotification(object sender, AdsNotificationEventArgs e)
{
    try
    {
    // Setzen der Position von e.DataStream auf die des aktuellen benötigten Wertes
    e.DataStream.Position = e.Offset;

    // Ermittlung welche Variable sich geändert hatif(e.NotificationHandle == hDeviceUp)
    {
        //Die Farben der Grafiken entsprechened der Variablen anpassenif (binReader.ReadBoolean() == true)
        {
        DeviceUp_LED.ForeColor = Color.Red;
        }
        else
        {
        DeviceUp_LED.ForeColor = Color.White;
        }
    }
    else if(e.NotificationHandle == hDeviceDown)
    {
        if (binReader.ReadBoolean() == true)
        {
        DeviceDown_LED.ForeColor = Color.Red;
        }
        else
        {
        DeviceDown_LED.ForeColor = Color.White;
        }
    }
    else if(e.NotificationHandle == hSteps)
    {
        // Einstellen der ProgressBar auf den aktuellen Schritt
        prgSteps.Value = binReader.ReadByte();
    }
    else if(e.NotificationHandle == hCount)
    {
        // Anzeigen des "count"-Werts
        lblCount.Text = binReader.ReadUInt16().ToString();
    }
    else if(e.NotificationHandle == hSwitchNotify)
    {
        // Markieren des korrekten RadioButtonsif (binReader.ReadBoolean() == true)
        {
        optSpeedFast.Checked = true;
        }
        else
        {
        optSpeedSlow.Checked = true;
        }
    }
    }
    catch (Exception ex)
    {
    MessageBox.Show(ex.Message);
    }
}

Es fehlen noch zwei Methoden, mit denen die Maschine schnell oder langsam gestellt wird. In Ihnen wird ein virtueller Schalter umgelegt, hier wird ein Wert in die SPS-Variable switch geschrieben.

//------------------------------------------------------//wird aufgerufen, wenn das Feld 'slow' markiert wird//------------------------------------------------------private void optSpeedFast_Click(object sender, EventArgs e)
{
    try
    {
    tcClient.WriteAny(hSwitchWrite, true);
    }
    catch (Exception ex)
    {
    MessageBox.Show(ex.Message);
    }
}

//------------------------------------------------------//wird aufgerufen, wenn das Feld 'fast' markiert wird//------------------------------------------------------private void optSpeedSlow_Click(object sender, EventArgs e)
{
    try
    {
    tcClient.WriteAny(hSwitchWrite, false);
    }
    catch (Exception ex)
    {
    MessageBox.Show(ex.Message);
    }
}

Zu guter Letzt muss noch dafür gesorgt werden, dass die Methoden 'optSpeedFast_Click' und 'optSpeedSlow_Click' auch beim richtigen Ereignis aufgerufen werden. Dazu in die Design Ansicht wechseln, den Radiobutton 'optSpeedFast' markieren, im Properities Window bei Events auf 'Click' klicken und dann die Methode 'optSpeedFast_Click' wählen. Und das Gleiche muss auch noch mit dem RadioButton 'optSpeedSlow' mit der Methode 'optSpeedSlow_Click' gemacht werden.

Notifications und Handles löschen:

In dem frmMachine_FormClosing-Ereignis der Form werden die Verbindungen wieder mit der Methode DeleteDeviceNotification()freigegeben.

//------------------------------------------//wird beim Beenden des Programms aufgerufen//------------------------------------------private void frmMachine_FormClosing(object sender, FormClosingEventArgs e)
{
    try
    {
    // Löschen der Notifications und Handles
    tcClient.DeleteDeviceNotification(hEngine);
    tcClient.DeleteDeviceNotification(hDeviceUp);
    tcClient.DeleteDeviceNotification(hDeviceDown);
    tcClient.DeleteDeviceNotification(hSteps);
    tcClient.DeleteDeviceNotification(hCount);
    tcClient.DeleteDeviceNotification(hSwitchNotify);

    tcClient.DeleteVariableHandle(hSwitchWrite);
    }
    catch (Exception ex)
    {
    MessageBox.Show(ex.Message);
    }
    tcClient.Dispose();
}


Das SPS ProgrammMachine_Final.prosollte auf dem Laufzeitsystem 1 starten und das erstellte C#-ProgrammMachine.exekann getestet werden.

Download C# Programm Beispiel:

CSharp Beispiel