# Visual Studio zugriff über TwinCat3 (C# / ADSdll)



## Fränki (2 Mai 2016)

Hallo Leute,

ich habe hier einen Beckhoff EK1100 im Einsatz.
Ich versuche eine einfach Form von lesen und schreiben von SPS variablen zu erstellen.
Ich orientiere mich an diesem Bsp: http://infosys.beckhoff.de/index.ph...31/tcadscomlib/html/tcadscomlib_intro.htm&id=

PLC CODE:

```
PROGRAM MAIN VAR    
 int1:INT := 30000;
 str1:STRING := 'this is a test string';
END_VAR
```

C#

```
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

using TwinCAT.Ads;


namespace Read_Write
{
    public partial class Form1 : Form
    {
        internal System.Windows.Forms.TextBox tText;
        internal System.Windows.Forms.TextBox tint1;

        private int hText;
        private int hint1;

        private TcAdsClient adsClient;



        public Form1()
        {
            InitializeComponent();
        }


        private void Form1_Load(object sender, EventArgs e)
        {
            adsClient = new TcAdsClient();
            try
            {
                adsClient.Connect(851);

                //PLC Variablen
                hText = adsClient.CreateVariableHandle("MAIN.str1");
                hint1 = adsClient.CreateVariableHandle("MAIN.int1");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            adsClient.Dispose();
        }

        //READ Button
        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                tText.Text = adsClient.ReadAny(hText, typeof(String), new int[] { 80 }).ToString();
                tint1.Text = adsClient.ReadAny(hint1, typeof(int)).ToString();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

        }

        private void Write_Click(object sender, EventArgs e)
        {
            try
            {
                adsClient.WriteAny(hint1, int.Parse(tint1.Text));
                adsClient.WriteAny(hText, tText.Text, new int[] { 80 });
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
    }
}
```




Nun bekomme ich beim drücken auf "Read oder Write folgdenden Fehler




Habt ihr eine Idee?

VG


----------



## MasterOhh (2 Mai 2016)

Hast du das Form im Designer zusammengeklickt?

Du verweist auf tText und tint1. Diese beiden Textboxen werden bei dir aber nirgends initialisiert. Auf dem Bild mit deinem Form ist auch nur eine Textbox zu sehen und keine 2.

In den Beispielen von Beckhoff gibt es keine gesonderte Designer.cs. Die InitializeComponent Methode ist direkt im cs File für die Form. 

Am einfachsten fügst du im Designer noch eine 2te Textbox hinzu. Die erste nennst du dann halt tText und die 2te tint1. 

Im Deklarationsteil von Form1.cs löschst du dann die Deklarationen von tText und tint1. Die sollten jetzt im Designer File enthalten sein.


----------



## Fränki (3 Mai 2016)

Das war die Lösung. Danke!


----------



## Damba (7 September 2016)

Hall Leute,
Ich möchte auch die SPS variablen in visual studio  lesen und schreiben. Ich habe das gleiche Programm verwendet und sieht jetzt so aus. 

```
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading.Tasks;
using TwinCAT.Ads;


namespace ReadWriteADS
{
    public partial class Form1 : Form
    {
        

        private int hText;
        private int hint1;

        private TcAdsClient adsClient;


        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            adsClient = new TcAdsClient();
            try
            {
                adsClient.Connect(851);

                //PLC Variablen
                hText = adsClient.CreateVariableHandle("MAIN.str1");
                hint1 = adsClient.CreateVariableHandle("MAIN.int1");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            adsClient.Dispose();
        }

        //READ Button
       

        private void button1_Click_1(object sender, EventArgs e)
        {

            try
            {
                textBox1.Text = adsClient.ReadAny(hText, typeof(String), new int[] { 80 }).ToString();
                textBox2.Text = adsClient.ReadAny(hint1, typeof(int)).ToString();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

        }

        private void button2_Click(object sender, EventArgs e)
        {
            try
            {
                adsClient.WriteAny(hint1, int.Parse(textBox2.Text));
                adsClient.WriteAny(hText, textBox1.Text, new int[] { 80 });
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
    }
}
```

Im solution Explorer hab ich so konfiguriert:



aber ich bekomme diesen Fehler:



Ich weiss nicht was ich ändern muss. Hat Jemand eine Idee?


----------



## Hack (7 September 2016)

Hast du die zwei Variablen auch im SPS Programm angelegt?


----------



## Damba (7 September 2016)

ja. das habe ich so gemacht. 

```
PROGRAM MAIN VAR    
 int1:INT := 30000;
 str1:STRING := 'this is a test string';
END_VAR
```


----------



## Pippen (7 September 2016)

Arbeitest Du auch mit TwinCAT3?


----------



## Damba (7 September 2016)

Ja Genau! Jetzt habe ich das SPS Projekt kompiliert. Aber das von c# jibt mir wieder andere Fehler wie folgt:


----------



## Damba (7 September 2016)

Das läuft jezt. Danke!


----------



## Damba (9 September 2016)

Jetzt möchte ich die Daten aus dem Windows application zum Bechhoff TcCOM Objects schicken. ist das möglich?


----------



## Pippen (12 September 2016)

So wie Du die Daten lesen kannst, kannst Du sie auch in die SPS schreiben.


----------



## Damba (13 September 2016)

ich kann bis jetzt nur die Daten von Twincat in Windows Application einlesen. aber wenn ich daten zu Twincat schicken möchte bekomme ich ein Error: Parameter ist ungültig


----------



## MasterOhh (13 September 2016)

Wäre schon hilfreich, wenn du uns zeigst (code-schnipsel) wie du versuchst die Daten an die SPS zu übertragen. In der ADS.dll gibt es ja einige verschiedene Methoden die das bewerkstelligen.


----------



## Pippen (13 September 2016)

Im Beckhoff Information System ist es jedenfalls ziemlich schön beschrieben meine ich.


----------



## Damba (14 September 2016)

Hier ist der SPS Code:

```
PROGRAM MAIN
VAR
    int1:INT ;
    str1:STRING ;
END_VAR


int1:= 30000;
str1:= 'this is a test string';
```


C# Code:

```
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading.Tasks;
using TwinCAT.Ads;


namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        private int hText;
        private int hint1;

        private TcAdsClient adsClient;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            adsClient = new TcAdsClient();
            try
            {
                adsClient.Connect(851);

                //PLC Variablen
                hText = adsClient.CreateVariableHandle("MAIN.str1");
                hint1 = adsClient.CreateVariableHandle("MAIN.int1");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            adsClient.Dispose();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                textBox1.Text = adsClient.ReadAny(hText, typeof(String), new int[] { 80 }).ToString();
                textBox2.Text = adsClient.ReadAny(hint1, typeof(int)).ToString();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            try
            {
                adsClient.WriteAny(hint1, int.Parse(textBox2.Text));
                adsClient.WriteAny(hText, textBox1.Text, new int[] { 80 });
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }




    }
}
```

beim drücken von button1_Click bekomme ich die Daten aus dem Twincat wie folgt:



Beim drücken von button2_Click bekomme ich diesen Fehler:


Ich dwollte damit daten in Texbox schreiben und beim drücken von Button dann in Twincat senden.


----------



## Pippen (14 September 2016)

Ich denke beim String geht's schief. Hast Du mal versucht nur den int Wert zu schreiben?


----------



## Damba (14 September 2016)

Ja. ich hab in beide Buttons die Zeile mit Texbox2 auskommentiert. das gibt den gleichen Fehler!


----------



## MasterOhh (14 September 2016)

Das Schreiben von Strings ist im Infosys eigentlich sehr gut beschrieben.
Guckst du Link


----------



## Damba (14 September 2016)

Vielen Dank für die Antwort. Allerdings habe ich das gleiche Problem. ich glaube ich muss noch einige Einstellungen in Twincat machen. aber ich weiss nicht was fehl. Mit Integer ist auch genauso


----------



## Pippen (14 September 2016)

Hat es evtl. etwas mit dem Alignment zu tun?
Setze mal folgende Zeile über die Definition der Variablen im SPS Programm:


```
{attribute 'pack_mode' := '1'}
PROGRAM MAIN
VAR
    int1:INT ;
    str1:STRING ;
END_VAR


int1:= 30000;
str1:= 'this is a test string';
```

So wird ein 1-Byte Alignment der Variablen erzwingt.


----------



## Damba (14 September 2016)

Danke! Jetzt läuft es zu Hälfte. Und zwar ich kann String data zum Twincat schicken. Der Integer geht leider noch nicht.


----------



## Damba (15 September 2016)

Jetzt hat es geklappt. Ich musste beim Integer Typ ein entsprechende .Net Typ wie zum Beispiel "int16" geben. Vielen Dank!


----------



## KGU (20 September 2016)

Klar, die SPS ist auch ein TcCom Modul. Du brauchst einfach die Port Nummer des TcCOm-Modules und die Symbole für dieses müssen vorhanden sein. Dann ist das ähnlich wie du es oben bereits getan hast.


----------



## Damba (21 September 2016)

Wo finde ich die Portnummer? Ich habe eine Globale Variable erstellt und habe die Eingang und Ausgang des TcCOM object auf die globale Variable verlinkt. jetzt kann ich die Parameter in SPS lesen aber nicht in Windows Application.


----------



## KGU (21 September 2016)

Bei TcCom-Modulen nimmst du die Port-Nummer des Tasks der dieses treibt. und wie gesagt, nicht vergessen CS (create Symbols) anzuhacken.


----------



## Damba (21 September 2016)

Und wo soll ich die  Portnummer angeben? In C# Programm dann?


----------



## Damba (21 September 2016)

Jetztfunktioniert es, wenn ich die Daten von TcCOM einlese. Zum reischreiben geht immer noch nicht. Es zeigt kein Fehler aber die Daten kommen einfach nicht an. Ich glaube es liegt an die Global Variablen. Wie kann ich nur mit dem MAIN arbeiten?


----------



## Damba (22 September 2016)

Endlich funktioniert alles wie ich möchte. Danke euch noch mal!


----------

