# Allgemein Toolbox Library Kuehner.



## Burkhard (22 September 2015)

Hallo Leute,

geht es nur mir so oder ist es auch bei anderen der Fall. Ich finde diese Bibliothek und das Download-Package total unuebersichtlich. Man sieht den Wald vor lauter Baeumen nicht.

Und was soll dieser merkwuerdige Configurations-Editor. Der versteckt die Configuration vor mir. Ich will aber nicht manuell konfigurieren, sondern aus dem Programm heraus!

Wie kann ich denn ISO over TCP einstellen?



```
myConn.Configuration.CpuIP = strDevice.stIPAddress
            myConn.Configuration.CpuRack = 0
            myConn.Configuration.CpuSlot = 2
            myConn.Configuration.Port = 102
            myConn.Configuration.TimeoutIPConnect = 5000000
            myConn.Configuration.PLCConnectionType =
            myConn.Connect()
```

Bei Libnodave war alles schoen einfach und uebersichtlich. Nun habe ich mich entschieden mal diese Toolbox-Lib auszuprobieren, da ich mit Libnodave und Multi-Threading Probleme habe. Aber irgendwie ist das sehr unuebersichtlich gestaltet. 

Wo sehe ich denn mal ein Beispiel wie man die Connection richtig konfiguriert?


----------



## Hans54216 (22 September 2015)

Ich würde sagen über:


```
myConn.Configuration.ConnectionType = (int)LibNodaveConnectionTypes.ISO_over_TCP;



public enum LibNodaveConnectionTypes
    {
        // ReSharper disable InconsistentNaming
        MPI_über_Serial_Adapter = 1,
        MPI_über_Serial_Adapter_Andrews_Version_without_STX = 2,
        MPI_über_Serial_Adapter_Step_7_Version = 3,
        MPI_über_Serial_Adapter_Adrews_Version_with_STX = 4,
        PPI_über_Serial_Adapter = 10,
        AS_511 = 20,
        Use_Step7_DLL = 50,
        ISO_over_TCP = 122,
        ISO_over_TCP_CP_243 = 123,
        Netlink_lite = 223,
        Netlink_lite_PPI = 224,
        Netlink_Pro = 230,
        // ReSharper restore InconsistentNaming
    }
```


----------



## Burkhard (22 September 2015)

Kann man den Enum-Type nicht direkt vorschlagen lassen wie bei diesem DataGridView? Unter *DotNetSiemensPLCToolBoxLibrary.DataTypes* findet man naemlich nichts aber statt dessen dann unter Communication. Und unter den vielen Beispielen ist alles was ich gefunden habe mit dem manuellen Konfigurator konfiguriert...

Die Wrapper-Funktionen sind schon sehr gut, und die Handhabbarkeit ist viel besser als bei Libnodave. Und auch Multithreading-faehig ist die Toolbox, das war bei der libnodave.net nicht der Fall.

Trotz der Unuebersichtlichkeit der Beispiele, gibt es von mir einen Daumen hoch fuer diese Bibliothek. Das zusammenstellen der Tagliste und das Lesen in eine Rutsch ist einfach genial!!


----------



## Jochen Kühner (22 September 2015)

Burkhard schrieb:


> Anhang anzeigen 30110
> 
> Kann man den Enum-Type nicht direkt vorschlagen lassen wie bei diesem DataGridView? Unter *DotNetSiemensPLCToolBoxLibrary.DataTypes* findet man naemlich nichts aber statt dessen dann unter Communication. Und unter den vielen Beispielen ist alles was ich gefunden habe mit dem manuellen Konfigurator konfiguriert...
> 
> ...




Jaaaaaaaa..... die Bibliothek ist halt im laufe der Jahre gewachsen. Als ich damit angefangen habe, war das auch so ziemlich mein erster Code in CSharp! Und die zeit um das in eine schönere Struktur zu packen hab ich im Moment einfach nicht! Aber du hast recht, das gehört in einen Enum! Mein hauptsächliches denken war damals, das man einfach den eingebauten Config Dialog nimmt, so muss nicht jeder selber einen bauen...

Vlt finde Ich gegen Ende des Jahres mal Zeit dies zu verbessern...

Doku gibt's leider gar keine, komm ich einfach nicht dazu, dafür helf ich gern bei Fragen aus!

Problem ist im Moment auch, mach fast gar nichts mehr mit S7, so mach Ich da nicht wirklich viel!


----------



## Burkhard (23 September 2015)

Hallo Jochen! Schwamm drueber. Nach der obligatorischen Einstiegsfrage und zwei Tagen Beschaeftigungszeit mit der Beispiel-Solution, hab ich jetzt den Dreh Raus... 

Und das SPS-Forum ist wirklch genial... Deutschland - Land der Ideen, sage ich da nur!! An was arbeitest du den gerade?

Sowas haben die Chinesen nicht!

Hat jemand die Lib schon mal mit LabView eingesetzt?


----------



## Burkhard (23 September 2015)

Hallo Jochen,

wieviele Daten kann ich mit der TagList lesen? Ich bekomme die Fehlermeldung "Index was outside the bounds of the array"


```
myConn.ReadValues(lstPlcTag)
```

Gibt es da eine Beschraenkung?

Das ist meine Tag Liste:


DB500.DBW2INT1INTDB500.DBW4INT2INTDB500.DBW6INT3INTDB500.DBW8INT4INTDB500.DBW10INT5INTDB500.DBW12INT6INTDB500.DBW14INT7INTDB500.DBW16INT8INTDB500.DBW18STRING1STRINGDB500.DBW274STRING2STRINGDB500.DBW530STRING3STRINGDB500.DBW786STRING4STRINGDB500.DBW1042DWORD1DWORDDB500.DBW1046DWORD2DWORDDB500.DBW1050DWORD3DWORDDB500.DBW1054DWORD4DWORDDB500.DBW1058REAL1REALDB500.DBW1062REAL2REALDB500.DBW1066REAL3REALDB500.DBW1070REAL4REAL


----------



## Burkhard (23 September 2015)

Ich habe mal die Strings rausgenommen, da diese ja sehr gross sind (ein String 255 Byte) und eine PDU ja schon 240 Byte umfasst. Nun geht es.

Daher meine Frage: Wie kann ich mit einer Tag-Liste eine grosse Anzahl von Tags lesen. So gross ist die Anzahl ja eigentlich gar nicht. Aber eben ueber tausend Byte pro SPS. Insgesamt habe ich 14 SPSen und fuer jede SPS einen eigenen Lese-Thread. 

Vier Strings a 255 byte + 4DWORD und 4 REAL und 8 INT = 1074 Byte, die ich mit einmal lesen will. Ist das moeglich? Warum geht es bei mir nicht?


----------



## Jochen Kühner (23 September 2015)

Normalerweise sollte mein Code die tags so anordnen und aufteilen das die gelesen werden. Auf mehrere PDU's muß es natürlich aufgeteilt werden, aber das sollte trotzdem funktionieren. Ist auf jeden Fall ein Bug!!! Ich schaus mir an!


----------



## Burkhard (23 September 2015)

Hallo lieber Jochen. Das waere toll, wenn der Code so funktionieren wuerde wie von dir angesprochen und die Aufteilung in libnodave Read-Requests und PDU's intern vornehmen wuerde. Ich habe noch einen Test gemacht und einen String gelesen (255 Byte), das geht. Wenn ich dann noch einen weiteren String in die Tag-Liste setze, kommt wieder die Meldung, Index is outside the Bounds of an array.


----------



## Jochen Kühner (23 September 2015)

Kann das Problem nicht nachvollziehen...

Folgender Code läuft bei mir:


```
[COLOR=blue]var[/COLOR] tags = [COLOR=blue]new[/COLOR][]
            {
                [COLOR=blue]new[/COLOR] [COLOR=#2b91af]PLCTag[/COLOR]() { DataBlockNumber = 5550, ByteAddress = 2, TagDataType = [COLOR=#2b91af]TagDataType[/COLOR].Int },
                [COLOR=blue]new[/COLOR] [COLOR=#2b91af]PLCTag[/COLOR]() { DataBlockNumber = 5550, ByteAddress = 4, TagDataType = [COLOR=#2b91af]TagDataType[/COLOR].Int },
                [COLOR=blue]new[/COLOR] [COLOR=#2b91af]PLCTag[/COLOR]() { DataBlockNumber = 5550, ByteAddress = 6, TagDataType = [COLOR=#2b91af]TagDataType[/COLOR].Int },
                [COLOR=blue]new[/COLOR] [COLOR=#2b91af]PLCTag[/COLOR]() { DataBlockNumber = 5550, ByteAddress = 8, TagDataType = [COLOR=#2b91af]TagDataType[/COLOR].Int },
                [COLOR=blue]new[/COLOR] [COLOR=#2b91af]PLCTag[/COLOR]() { DataBlockNumber = 5550, ByteAddress = 10, TagDataType = [COLOR=#2b91af]TagDataType[/COLOR].Int },
                [COLOR=blue]new[/COLOR] [COLOR=#2b91af]PLCTag[/COLOR]() { DataBlockNumber = 5550, ByteAddress = 12, TagDataType = [COLOR=#2b91af]TagDataType[/COLOR].Int },
                [COLOR=blue]new[/COLOR] [COLOR=#2b91af]PLCTag[/COLOR]() { DataBlockNumber = 5550, ByteAddress = 14, TagDataType = [COLOR=#2b91af]TagDataType[/COLOR].Int },
                [COLOR=blue]new[/COLOR] [COLOR=#2b91af]PLCTag[/COLOR]() { DataBlockNumber = 5550, ByteAddress = 16, TagDataType = [COLOR=#2b91af]TagDataType[/COLOR].Int },
                [COLOR=blue]new[/COLOR] [COLOR=#2b91af]PLCTag[/COLOR]() { DataBlockNumber = 5550, ByteAddress = 18, TagDataType = [COLOR=#2b91af]TagDataType[/COLOR].String, ArraySize = 255 },
                [COLOR=blue]new[/COLOR] [COLOR=#2b91af]PLCTag[/COLOR]() { DataBlockNumber = 5550, ByteAddress = 274, TagDataType = [COLOR=#2b91af]TagDataType[/COLOR].String, ArraySize = 255 },
                [COLOR=blue]new[/COLOR] [COLOR=#2b91af]PLCTag[/COLOR]() { DataBlockNumber = 5550, ByteAddress = 530, TagDataType = [COLOR=#2b91af]TagDataType[/COLOR].String, ArraySize = 255 },                
                [COLOR=blue]new[/COLOR] [COLOR=#2b91af]PLCTag[/COLOR]() { DataBlockNumber = 5550, ByteAddress = 768, TagDataType = [COLOR=#2b91af]TagDataType[/COLOR].String, ArraySize = 255 },
                [COLOR=blue]new[/COLOR] [COLOR=#2b91af]PLCTag[/COLOR]() { DataBlockNumber = 5550, ByteAddress = 1042, TagDataType = [COLOR=#2b91af]TagDataType[/COLOR].Dword },
                [COLOR=blue]new[/COLOR] [COLOR=#2b91af]PLCTag[/COLOR]() { DataBlockNumber = 5550, ByteAddress = 1046, TagDataType = [COLOR=#2b91af]TagDataType[/COLOR].Dword },
                [COLOR=blue]new[/COLOR] [COLOR=#2b91af]PLCTag[/COLOR]() { DataBlockNumber = 5550, ByteAddress = 1050, TagDataType = [COLOR=#2b91af]TagDataType[/COLOR].Dword },
                [COLOR=blue]new[/COLOR] [COLOR=#2b91af]PLCTag[/COLOR]() { DataBlockNumber = 5550, ByteAddress = 1054, TagDataType = [COLOR=#2b91af]TagDataType[/COLOR].Dword },
                [COLOR=blue]new[/COLOR] [COLOR=#2b91af]PLCTag[/COLOR]() { DataBlockNumber = 5550, ByteAddress = 1058, TagDataType = [COLOR=#2b91af]TagDataType[/COLOR].Float },
                [COLOR=blue]new[/COLOR] [COLOR=#2b91af]PLCTag[/COLOR]() { DataBlockNumber = 5550, ByteAddress = 1062, TagDataType = [COLOR=#2b91af]TagDataType[/COLOR].Float },
                [COLOR=blue]new[/COLOR] [COLOR=#2b91af]PLCTag[/COLOR]() { DataBlockNumber = 5550, ByteAddress = 1066, TagDataType = [COLOR=#2b91af]TagDataType[/COLOR].Float },
                [COLOR=blue]new[/COLOR] [COLOR=#2b91af]PLCTag[/COLOR]() { DataBlockNumber = 5550, ByteAddress = 1070, TagDataType = [COLOR=#2b91af]TagDataType[/COLOR].Float },
            };
 
 
 
            myConn = [COLOR=blue]new[/COLOR] [COLOR=#2b91af]PLCConnection[/COLOR]([COLOR=#a31515]"SimpleCSharpDemonstrationConnection"[/COLOR]);
            myConn.Connect();
 
            myConn.ReadValues(tags);
```


----------



## Jochen Kühner (23 September 2015)

Burkhard schrieb:


> Hallo lieber Jochen. Das waere toll, wenn der Code so funktionieren wuerde wie von dir angesprochen und die Aufteilung in libnodave Read-Requests und PDU's intern vornehmen wuerde. Ich habe noch einen Test gemacht und einen String gelesen (255 Byte), das geht. Wenn ich dann noch einen weiteren String in die Tag-Liste setze, kommt wieder die Meldung, Index is outside the Bounds of an array.
> 
> Anhang anzeigen 30117



Kannst du denn mal den Stacktrace zeigen?


----------



## Jochen Kühner (23 September 2015)

Hab auch mal das Parallele lesen probiert. Bei mir scheint das genau so schnell zu sein wie wenn ich nur 1 mal lese, d.h. es geht parallel...


```
myConn = [COLOR=blue]new[/COLOR] [COLOR=#2b91af]PLCConnection[/COLOR]([COLOR=#a31515]"SimpleCSharpDemonstrationConnection"[/COLOR]);
           [COLOR=blue]var[/COLOR] myConn2 = [COLOR=blue]new[/COLOR] [COLOR=#2b91af]PLCConnection[/COLOR]([COLOR=#a31515]"SimpleCSharpDemonstrationConnection"[/COLOR]);
           [COLOR=blue]var[/COLOR] myConn3 = [COLOR=blue]new[/COLOR] [COLOR=#2b91af]PLCConnection[/COLOR]([COLOR=#a31515]"SimpleCSharpDemonstrationConnection"[/COLOR]);
           [COLOR=blue]var[/COLOR] myConn4 = [COLOR=blue]new[/COLOR] [COLOR=#2b91af]PLCConnection[/COLOR]([COLOR=#a31515]"SimpleCSharpDemonstrationConnection"[/COLOR]);
           myConn.Connect();
           myConn2.Connect();
           myConn3.Connect();
           myConn4.Connect();
 
           [COLOR=blue]var[/COLOR] tags1 = tags.Select(x => [COLOR=blue]new[/COLOR] [COLOR=#2b91af]PLCTag[/COLOR](x)).ToList();
           [COLOR=blue]var[/COLOR] tags2 = tags.Select(x => [COLOR=blue]new[/COLOR] [COLOR=#2b91af]PLCTag[/COLOR](x)).ToList();
           [COLOR=blue]var[/COLOR] tags3 = tags.Select(x => [COLOR=blue]new[/COLOR] [COLOR=#2b91af]PLCTag[/COLOR](x)).ToList();
           [COLOR=blue]var[/COLOR] tags4 = tags.Select(x => [COLOR=blue]new[/COLOR] [COLOR=#2b91af]PLCTag[/COLOR](x)).ToList();
 
           [COLOR=#2b91af]Stopwatch[/COLOR] w = [COLOR=blue]new[/COLOR] [COLOR=#2b91af]Stopwatch[/COLOR]();
           w.Start();
           [COLOR=blue]var[/COLOR] tsk = [COLOR=#2b91af]Task[/COLOR].Factory.StartNew(() => { myConn.ReadValues(tags1); });
           [COLOR=blue]var[/COLOR] tsk2 = [COLOR=#2b91af]Task[/COLOR].Factory.StartNew(() => { myConn2.ReadValues(tags2); });
           [COLOR=blue]var[/COLOR] tsk3 = [COLOR=#2b91af]Task[/COLOR].Factory.StartNew(() => { myConn3.ReadValues(tags3); });
           [COLOR=blue]var[/COLOR] tsk4 = [COLOR=#2b91af]Task[/COLOR].Factory.StartNew(() => { myConn4.ReadValues(tags4); });
           [COLOR=#2b91af]Task[/COLOR].WhenAll(tsk, tsk2, tsk3, tsk4).Wait();
           w.Stop();
```


----------



## Burkhard (23 September 2015)

Die Array-Size beim STRING-Datentyp, muss ich die extra setzen oder ist das der Standard-Wert? Ich setze es jetzt mal explizit und schau mal ob es dann geht?

Das war es! Wenn man den Wert von 255 fuer die Array-Size explizit setzt, geht es. Ich dachte es reicht, wenn ich Datentyp STRING auswaehle, da dieser in der S7 SPS standardmaessig 255 Byte gross ist.

OK, damit ist die Frage beantwortet. Danke lieber Jochen!!


----------

