# Schnelle Datenübertragung, Datenspeicherung und Datenvisualisierung



## Burkhard (2 Oktober 2015)

Hallo Freunde der Hochsprachenprogrammierung.

Ich habe mit der DotNetSiemensPLCToolBoxLibrary eine Applikation entwickelt, mit der ich Daten aus der Siemens S7-SPS lesen, die aktuellen Werte anzeigen und in Dateien abspeichern kann.

Ich moechte nun waehrend die Erfassung laeuft, die die Werte in einem DataGridView anzeigen. Ich stelle mir das so vor, dass sich das GridView dann kontinuierlich mit Zeilen fuellt. 

In einem Background-Thread werden die Werte von der S7 gelesen und in eine DataTable geschrieben. Alle 30 Millisekunden faellt eine neue Zeile in der DataTable an. Sehr schnell habe ich an die 100.000 Zeilen in der Tabelle.

Im GUI-Thread habe ich ein DataGridView mit Binding-Source an diese DataTable verbunden. 

Im Debugger laeuft das ganze irgendwie. Aber wenn ich die Exe ohne Debugger starte, dann friert das Programm manchmal ein. Ich habe ein wenig experimentiert und eine Exe erzeugt die ohne Einfrieren laeuft, aber wenn ich dann weitere Aenderungen am Programm durchfuehre, habe ich wieder Probleme. 

Ich bin auf der Suche nach einem grundsaetzlichen Hinweis, wie man bei solchen Problemstellungen vorgeht, denn ich glaube ich habe hier ein grundsaetzliches Architektur-Problem in der Herangehensweise.

Wie werde grosse Datenmengen, die in einem Background-Thread anfallen am besten gespeichert. Ist die DataTable hier das richtige Instrument? Wie Zeige ich diese Daten dann am besten im UI-Thread an?


----------



## dolo280 (2 Oktober 2015)

Hallo Burkhard,

was spricht den Deine Konsole (Vermutlich Visual Studio?) beim Ausführen des Programms im Debugging Modus? (Irgendwelche Exceptions?) Ist der "Invoke" zwischen den Threads sauber gelöst?

Bevor Du das Programm als Stand-Alone Exe betreibst erstelle es mal als "Release"! - Führst Du das Programm auf der gleichen Maschine aus wie beim Debuggen? Sind alle Verweise als Lokale Kopie gesetzt?

Für einfaches Abspeichern gibt es evtl. schönere Lösungen als ein DataSet. Grundsätzlich sollte es aber funktionieren.

Gruß aus der Pfalz


----------



## Larry Laffer (2 Oktober 2015)

Hallo,
ich würde das gar nicht über einen DataTable und Binding lösen - wobei ich gestehen muss, dass ich einen DGV in diesem Zusammenhang und in dieser Form noch nie verwendet habe.
Hast du mal versucht, jeden neuen Datensatz als neue Row hinzuzufügen ?
Hast du in deinem Thread am Ende ein Thread.Sleep(0) oder größer damit die Applikation selbst auch noch die Chance hat, ihre Events durchzubekommen ?

Was mich hier allerdings auch noch interessieren würde :
Wie bekommst du zuverlässig alle 30 ms auf diese Weise Daten von der SPS ? Das kann ich mir irgendwie so gar nicht vorstellen. Es könnte von da her also auch genauso sein, dass dir dein Programm deswegen einfriert.

Gruß
Larry


----------



## Jochen Kühner (2 Oktober 2015)

Ich glaube auf jeden Fall nicht das es flüssig laufen wird wenn man einer DGV alle 30ms eine Zeile hinzufügt! Vlt. gehts mit WPF einem DataGrid und einer Observable Collection wenn die Ui Virtualisierung aktiv ist! Aber auch nur Vlt! Ich glaubs irgenwie nicht! du kannst doch die daten auch puffern und nur alle z.B. 500ms als block hinzufügen?


----------



## Burkhard (2 Oktober 2015)

Hallo,

also das Lesen der Daten alle 30ms funktioniert, das habe ich ja bereits in einem anderen Thread gezeigt, lieber LarryLaffer. Auch das Schreiben der Daten in die Datei funktioniert verzögerungsfrei, mit Schwankungen zwischen 20 und 35 ms.

Ich habe mich entschieden die 4 Threads die die Daten aus der SPS lesen nicht zu syncronisieren. Sonst wuerde ja der langsamste Thread immer den Takt vorgeben. Die Schreiben ganz unabhaengig von einernder ihre Daten in eine Erebnis-Tabelle. Das klappt soweit auch ganz gut.

Morgen werde ich nach mal Zeitmessungen machen um zu kontrollieren ob auch das Schreiben der Daten in die DataTable genau so verzögerungsfrei funktioniert wie das Schreiben in die Datei. Ich baue alle 30ms eine Row mit einem Zeitstempel zusammen und füge dann die Row der Datetable hinzu. Nach 10 Minuten Aufzeichnungszeit kontrolliere ich den Jitter der Zeitstempel. 

Beim Datenbinden an das DataGridview gibt es immer mal wieder Schwankungen um die 200ms.  Ich habe nachgedacht und finde sowieso, dass diese riesige Datenmenge in einem DGV sowieso niemand anschauen kann und will. 

Wichtiger ist die grafische Darstellung der Daten in Charts, denn ein Bild sagt mehr als tausend Worte, bzw. Zahlen. Darum ist der nächste Schritt die Bindung der Datatable an ein Chart.

Hat einer von euch Erfahrungen mit Echtzeit-Charts, wenn Daten alle 30ms anfallen? Ich habe früher mit dem Scope-View-Analyzer von Beckhoff gearbeitet und die arbeiten da auch mit Puffern, das sieht man daran wie sich die Diagramme aufbauen. Auch mit dem Autem PLC-Analyzer habe ich gerarbeitet und da sieht man, dass die grafische Darstellung auf das allernötigste reduziert wurde um genug Performance für die Erfassung und Speicherung der Daten zu haben.

Gibt es da vielleicht eine OpenSource Library für die Echtzeitdarstellung von Messwerten?


----------



## Burkhard (2 Oktober 2015)

Larry Laffer schrieb:


> Hast du in deinem Thread am Ende ein Thread.Sleep(0) oder größer damit die Applikation selbst auch noch die Chance hat, ihre Events durchzubekommen ?



Ja, ich habe einen Thread.Sleep(20) in meinem Haupt-SPS-Thread drin. Der UI-Thread ruft pro SPS den SPS-Thread auf, dieser wiederum ruft pro Connection einen Connection-Thread auf.



Larry Laffer schrieb:


> Wie bekommst du zuverlässig alle 30 ms auf diese Weise Daten von der SPS ? Das kann ich mir irgendwie so gar nicht vorstellen.



Doch frag ma den Jochen, mit der Toolboxlibrary geht das. Die Zykluszeit der Erfassung schwankt zwischen 20ms und 35 ms. Dabei nutzt man soviele Connections zur S7 wie eben frei sind und liest über jede Connection pro Lesezyklus eine PDU.


----------



## Burkhard (3 Oktober 2015)

dolo280 schrieb:


> Hallo Burkhard,
> 
> was spricht den Deine Konsole (Vermutlich Visual Studio?) beim Ausführen des Programms im Debugging Modus? (Irgendwelche Exceptions?) Ist der "Invoke" zwischen den Threads sauber gelöst?



IM Debugging-Mode gibt es keine Exzeptions. Die Delegates für die Cross-Thread Operations  beim Zugriff auf Controls des UI-Threads sind auch alle OK. Für eine Cross-Thread-Operation beim Schreiben in ein Data-Set brauche ich kein Delegate/Invoke, da reicht ein SycLock m.E. aus.



dolo280 schrieb:


> Bevor Du das Programm als Stand-Alone Exe betreibst erstelle es mal als "Release"! - Führst Du das Programm auf der gleichen Maschine aus wie beim Debuggen? Sind alle Verweise als Lokale Kopie gesetzt?



Ja, als Release habe ich es jetzt auch kompiliert und ich teste es auf der gleichen Maschine. Alle Referenzen sind ins Release Verzeichnis kopiert. Es ist wirklich bei der Multi-Thread-Programmierung so, dass es da Merkwürdigkeiten gibt, die auch der Debugger nicht erkennt. 

Wenn einer von euch mal Zeit hat, kann er sich ja mein Projekt mal runterladen und anschauen. Probiert mal bitte die Sub "ShowDataGridView2(...)" aus der in frmMain untersten Sub "ToolStripButtonUpdate_Clicked" in die darueberliegende Sub "EventOperation2FinishedRaised" zu kopieren, so dass sie direkt unter "ShowDataGridview1(...)" steht.

Dann wieder einen Build machen. Im Debugger läuft es, aber die Standalone-Exe friert ein, sobald der Datenaustausch mit der S7 startet und das Event kommt. Ich kapier nicht wieso es laueft wenn ich das Event manuell über den Button zeitversetzt steuere.


----------



## LowLevelMahn (3 Oktober 2015)

> Ja, als Release habe ich es jetzt auch kompiliert und ich teste es auf der gleichen Maschine. Alle Referenzen sind ins Release Verzeichnis kopiert. Es ist wirklich bei der Multi-Thread-Programmierung so, dass es da Merkwürdigkeiten gibt, die auch der Debugger nicht erkennt.



Ja absolut - deine Applikation hat im Debug-Modus/und auch innerhalb/ausserhalb der IDE ein anderes Zeitverhalten 
damit bekommst du z.B. mehr/weniger Events durch oder Fehler in deiner Synchronisation werden damit verborgen/kasschiert

so eine Frage, deine Einfrierproblem und dein Datenweg über einen DataTable+Bindings lassen mich irgendwie an der Stabilität deiner 30ms-Aussagen zweifeln 
hab schon genug Mit-Threads-ist-es-schneller-Beispiele gesehen die schneller aber instabiler liefen - nach Korrektur der Synchronisation waren diese wieder auf erwartetem Niveau unterwegs

Ein Benchmark der nicht stundenlang mit hoher Wiederholrate, gemittelt und ohne IO wie Console,GUI,Dateiausgabe ausserhalb der IDE gefahren wurden ist bedeutungslos - weil es einfach zu viel Rauschanteil in der Messung gibt

ein nackter C/C++ Test mit AGLink(in meinen Messungen bisher immer am schnellsten) + eine Liste deiner Variablen/und wie du sie auf n Verbindungen splittest (nicht der Algorithmus sonder nur welche Variablen in welcher Reihenfolge auf welche Verbindung) würde da eine gute Testgrundlage bieten


----------



## Jochen Kühner (3 Oktober 2015)

Für Charts würd Ich dir z.B. unter WPF das von mir gepflegte WPF Toolkit empfehlen (https://github.com/dotnetprojects/WpfToolkit) oder http://oxyplot.org/


----------



## Burkhard (4 Oktober 2015)

Da muss ich ja WPF lernen. Damit habe ich noch nie gearbeitet. Ich habe heute einfach mal das Chart-Control von Microsoft ausprobiert. Was fuer Vorteile hat den das Chart-Control aus deinem WPF-Toolkit gegenueber den Standard-Chart von MS?


----------



## Larry Laffer (4 Oktober 2015)

Ganz grundsätzlich finde ich den Vorschlag von Jochen (Beitrag #4) ganz gut.
Warum  nicht die eingehenden Werte in einer List (z.B.) speichern und diese  quasi als FiFo benutzen um deren Inhalte dann wieder in deinen DGV oder  auch in den Chart (asynchron oder wie Zeit ist) zu übertragen.
Der  Chart hat übrigens vom Grundverhalten m.E. das gleiche Problem - er ist  ein grafisches Control das sich in dem wie auch immer gewünschten  Intervall neuzeichnen (Invalidate) muss.
Du solltest berücksichtigen, dass auch dass so seine Zeit braucht. 

Ich  habe gelesen, dass deine Anwendung funktioniert. Ich habe aber auch  gelesen, dass deine Anwendung immer mal wieder einfriert. Beachte bitte,  dass das Überfrachten mit Events (auch Invalidate oder Refresh ist so  etwas) genau dazu führen kann. Außerdem gibt es da (ich weiß zu wenig  über dein Projekt) auch noch den geliebten GC (Garbage Collector) ...

Gruß
Larry


----------



## Burkhard (5 Oktober 2015)

Leider ist vb.net keine Deterministische und Zyklus-Orientierte Programmiersprache, wo das Speicherabbild am Anfang eines Zyklus gelesen und am Ende eines Zyklus geschrieben wird und jeder Zyklus garantiert nur die eingestellte Zeit von z.B. 1 bis 10 ms benoetigt, so wie zB. TwinCat.

Waere LabView vielleicht die bessere Wahl zum Lesen, Verarbeiten, Anzeigen und Speichern sehr grosser Datenmengen?


----------



## Larry Laffer (5 Oktober 2015)

Tja ...
nach meiner Meinung macht es LabView (in der Frequenz) auch mit dem gleichen Trick. Du hast da ja eine Mess-Hardware dran (z.B. NI) und die überträgt ihre Messwerte dann auch blockweise (z.B. über Ethernet) an den PC mit der Software.

TwinCat kann dir auch nicht sicher garantieren, dass deine Task-Zykluszeit immer unter dem einstellten Wert bleibt. Das hängt immer von deinem in dem Task laufenden Programm ab. Wenn du es mit der Zykluszeit allerdings übertreibst dann hättest du da (aber genauso auch bei Siemens) einen Watchdog, der dir das "unter die Nase reibt".

So, wie ich das sehe, ist die Frage bei dir nicht die Realisierbarkeit ("ob") der Aufgabe sondern mehr das "wie". Ich würde an der Stelle mal ein bißchen "feilen" ...

Gruß
Larry


----------



## Burkhard (6 Oktober 2015)

TwinCat lauft in echter harter RealTime, das heisst, es ist egal was das Betriebssystem macht, der Prozessor arbeitet den TwinCat Task immer mit der gleichen Zykluszeit (mit minimalem Jitter) ab und du hast einen Realtime-Slider mit dem du den Performance Anteil des Prozessors zwischen TwinCat und Windows kontrollieren kannst und auch einen Balken siehst wie die momentane Echtzeitauslastung ist, und natuerlich wie du bereits erwaehnt hast, gewarnt wirst, falls die Performance nicht reicht. 

TwinCat kann in der NC eine ziemlich grosse Anzahl von Servo-Achsen (10) gleichzeitig berechnen und hat fuer die PLC eine Zykluszeit bis minimal 1 ms. Bei einem ausreichend schnellen PC, kann dann auch ein ziemlich umgangreiches PLC Projekt mit dieser Zykluszeit abgearbeitet werden und wenn der User am Windows rumfummelt hat das keine Auswirkungen auf die Zykluszeit. Das ist ja das gute an der SoftSPS mit RTOS oder RTX.

Aber sei es drum, bei PC Applikationen unter Normal-Windows hat man diese Vorteile eben nicht. Ich habe mal ein paar Versuche mit meinem Programm unternommen und tatsaechlich festgestellt, dass das Updaten des Charts in meinem SPS-Thread Zykluszeitschwankungen verursacht, die umso groesser werden, je groesser die Datenmenge ist, die an den Chart gebunden wird. Die Basis-Datenerfassungsrate liegt bei mir um die 30ms. Immer wenn ich den Update-Button betaetige, dann gibt es einen Nadel-Peak der am Anfang um die 200ms und gegen Ende meiner Erfassung um die 1000ms liegt.

Mein Plan ist nun, die Update-Funktion so zu programmieren, dass das Chart nicht immer wieder geloescht und von Null aufgebaut wird, sondern dass immer nur neue Punkte hinzugefuegt werden. Wenn das Updaten dann jede Sekunde einmal erfolgt, dann sollte es eine Verbesserung geben, die auch deutlich sichtbar sein sollte.


----------



## Larry Laffer (6 Oktober 2015)

Burkhard schrieb:


> Mein Plan ist nun, die Update-Funktion so zu programmieren, dass das Chart nicht immer wieder geloescht und von Null aufgebaut wird, sondern dass immer nur neue Punkte hinzugefuegt werden. Wenn das Updaten dann jede Sekunde einmal erfolgt, dann sollte es eine Verbesserung geben, die auch deutlich sichtbar sein sollte.



Das wäre dann im Prinzip die vorgeschlagene FIFO-Geschichte (die so in dieser Form m.E. auch mit einem DGV funktionieren würde).

Es könnte natürlich auch noch gehen, wenn du einen OnTheFly-Chart brauchst (also ein Chart der z.B.) jeweils nur die letzten 1000 Messwerte darstellt), dass du dir einen eigenen Chart selbst erstellst. Das Graphics-Object stellt ja das dafür Benötigte im Großen und Ganzen zur Verfügung. Was man nur schauen (also ausprobieren) müßte wäre welche Datenablage hier die besten Ergebnisse bringt (Array, List/Collection).

Gruß
Larry

Nachsatz:
Auf jeden Fall : deine Untersuchungen hierzu sind wirklich gut und sehr aufschlußreich ...  :s12:


----------



## Burkhard (7 Oktober 2015)

Die Update-funktion fuer das Chart-Control ist nun differentiell, das heisst, es werden immer nur die Punkte hinzugefuegt die seit dem letzten Update hinzugekommen sind.

Dadurch hat sich das Zeitverhalten wesentlich verbessert. Bei druecken des Update-Buttons gibt es nur noch Zykluszeit-Aenderungen von 250ms statt 1000ms. Das bedeutet eine Verbesserung um 400 Prozent!

Grundsaetzlich muss man leider sagen, dass sich die Programmiersprache vb.net nicht fuer harte Echtzeitanwendungen eignet. Echtzeit bedeutet in dem Fall nicht "besonders schnell" sondern "deterministisch", das heisst, man kann Erwarten dass ein Thread innerhalb garantierter Intervalle aufgerufen wird und sein Abarbeitungs-Intervall nicht in Abhaengigkeit von der Auslastung anderer Threads in Mitleidenschaft gezogen wird, wie das bei mir eben der Fall ist.

Fuer die Anforderung "Harte Echtzeit" gibt es Echtzeitbetriebssysteme (RTOS) und fuer Windows gibt es IntervalZero RTX, oder Kithara, welche aber nur fuer Visual Studio C++ (Kithara, RTX) oder Delphi (Kithara) zur Verfuegung stehen und zudem kostenpflichtig sind.

http://www.intervalzero.com/german/

http://www.kithara.de/en/products/realtime-suite

Dieser Artikel befasst sich ebenso mit dem Thema "Realtime" und Visual Studio:

http://www.folding-hyperspace.com/real-time-programming-tips/tip-11-is-net-suitable-for.html

Hat jemand von euch Erfahrungen mit diesen Software-Paketen und kann sagen, wie die Anwendungsfreundlichkeit ist?


----------



## Burkhard (7 Oktober 2015)

Wenn ich die Update-Funktion nicht sporadisch mit dem Button, sondern aller 500ms aktiviere, und dann aller 2000ms ein Axis-Re-Calculation+Redraw des Charts mache sieht die Sache so aus...

Wenn ich dann die Priority des Process auf RealTime stelle bekomme ich nochmal eine Verbesserung, wie man am Vergleich beider Aufzeichnungen sehen kann.


```
[SIZE=1]Dim myProcess As System.Diagnostics.Process = System.Diagnostics.Process.GetCurrentProcess()
myProcess.PriorityClass = System.Diagnostics.ProcessPriorityClass.RealTime
[/SIZE]
```

Es ist offenbar so, dass die differentielle Uebertragung der Punkte in die Curve-List des Charts zwar einiges an Geschwindigkeits-Vorteil bringt, aber das Redraw des Charts muss ja dennoch die gesamte Kurve zeichnen und die wird ja immer groesser! Man sieht in der zweiten Messung, dass, wenn ich das Fenster minimiere, nur die Punkteliste aktualisiert wird, aber kein Redraw stattfindet und dann die Zykluszeit wieder korrekt bei 30s liegt, bis ich das Fenster wird maximiere.


Wie bereits gesagt koennte ein FILA (First-in-Last-Out) Buffer, der immer nur z.B. 10.000 Punke darstellt schon was bringen. Ich koennte den Chart so konfigurieren, dass die Zeit-Achse mit jedem Update entsprechend skaliert wird, so dass man immer nur 5 Minuten sieht, und man nach dem Ende der Messung, quasi Offline, mit Zoom-to-Default, wieder alle Messwerte sehen kann.


----------



## LowLevelMahn (7 Oktober 2015)

> Grundsaetzlich muss man leider sagen, dass sich die Programmiersprache vb.net nicht fuer harte Echtzeitanwendungen eignet. Echtzeit bedeutet in dem Fall nicht "besonders schnell" sondern "deterministisch", das heisst, man kann Erwarten dass ein Thread innerhalb garantierter Intervalle aufgerufen wird und sein Abarbeitungs-Intervall nicht in Abhaengigkeit von der Auslastung anderer Threads in Mitleidenschaft gezogen wird, wie das bei mir eben der Fall ist.



du schreibst es so als wäre das eine neue Erkenntnis - die ganzen .Net-Sprachen sind nicht Hart-Echtzeit- und kaum Soft-Echtzeitfähig (zu wenig statisch, viel zu viel dynamic/Heap fuer jeden Pups, häufig laufender asychroner GC)
genau so wie z.B. WPF wegen seinem Design sehr dynamisch/adaptiv ist - aber dafür auch Ressourcen frisst als gäbe es kein Morgen


----------



## Burkhard (7 Oktober 2015)

Ich konnte durch die Abschaltung des Rechen- und Grafik-Intensiven Progress-Bar, der waehrend der Aufzeichnungen aus dem Background-Thread aktualisiert wurde, die Performance meiner Applikation enorm steigern. Ich habe 16 Minuten Werte aus der SPS gelesen und diese mit sehr zuverlaessiger Zykluszeit von 30ms im Chart darstellen koennen. Am Ende waren es 50.000 Messwerte.

Zur Echtzeitfaehigkeit von vb.net. Die mangelnde Hard-Readltime-Faehigkeit ist mir bisher nur aus Artikeln und Buechern bekannt. Ich habe bisher immer die Soft-Realtime-Faehigkeiten genutzt und wollte dies nun alles mal in ein paar Experimenten fuer mich selber bestaetigen.

Mit TwinCat 2 habe ich selber auch schon sehr viel Erfahrung gesammelt und kenne daher die Faehigkeiten die ein echtes Hard-Realtime-System bieten kann.

Hat einer von Erfahrung mit C++ und RTX?


----------



## LowLevelMahn (7 Oktober 2015)

> Die mangelnde Hard-Readltime-Faehigkeit ist mir bisher nur aus Artikeln und Buechern bekannt.



.Net UND dein darunter liegendes Windows sind hier das Problem



> Ich habe bisher immer die Soft-Realtime-Faehigkeiten genutzt



so wie du das schreibst klingt es so als wäre Hard oder Soft-Realtime so einen Art Option zum einschalten
nur so als Frage: Dir ist klar das Harte Echtzeit nur ein Zeitverhalten garantiert nicht das es besonders schnell ist
- deswegen bin ich mir nicht ganz sicher warum du hier überhaupt Hart/Soft-Echtzeit ansprichst, deine (GUI)Komponenten/Implementierungen
sind doch einfach nur zu langsam eine höhere Datenrate zu stemmen - oder? Was hat das mit Hart/Soft-Echtzeit zu tun?



> Hat einer von Erfahrung mit C++ und RTX?



ich arbeite bei sowas mit C/C++ - damit kann man einfach viel gezielter (weil man gezwungen ist) die Heap-Bewegung usw. kontrollieren - wenn es denn wichtig ist 
einen Geschwindigkeitsvergleichen zwischen .Net und C++ resultierendem Code ist zu Anwendungsspezifisch deswegen kann man dazu kaum oder nur schlechtes sagen

die RTX ist eine Soft-SPS und "könnte" dir kürzere Abtastraten als 30ms bringen - oder meinst du RTX mit C++ programmieren?

fuer den Test der GUI-Performanz kannst du ja auch mal Testweise ein anderes Toolkit benutzten das auf Ausgabegeschwidigkeit getrimmt ist
z.B. https://visualstudiogallery.msdn.microsoft.com/d09aa844-247a-4aa6-b591-cca32f1b8b3f (http://arction.com/) als Trial mit mit GPU/Direct2D Backend - oder andere dieser Art


----------



## Burkhard (7 Oktober 2015)

LowLevelMahn schrieb:


> So wie du das schreibst, klingt es so, als wäre Hard- oder Soft-Realtime so einen Art Option zum einschalten. Nur so als Frage: Dir ist klar das Harte Echtzeit nur ein Zeitverhalten garantiert nicht das es besonders schnell ist.



Zum Thema 'Wie ich etwas schreibe' bzw. was du da heraus liest, darf mich mich selber aus Posting Nr.16 zitieren.



			
				Burkhard schrieb:
			
		

> Grundsaetzlich muss man leider sagen, dass sich die Programmiersprache vb.net nicht fuer harte Echtzeitanwendungen eignet. *Echtzeit bedeutet in dem Fall nicht "besonders schnell" sondern "deterministisch", das heisst, man kann Erwarten dass ein Thread innerhalb garantierter Intervalle aufgerufen wird* und sein Abarbeitungs-Intervall nicht in Abhaengigkeit von der Auslastung anderer Threads in Mitleidenschaft gezogen wird, wie das bei mir (meiner vb.net Applikation) eben der Fall ist.



Windows ist in gewissen Grenzen ein Soft-Realtime-System und mit meiner Applikation wollte ich diese Grenzen einfach mal austesten um zu sehen wie gut oder schlecht diese Soft-Realtime so ist.  So viel zum Thema, warum ich hier von Hard- und Soft-Realtime spreche. 

Nun noch meinen Senf zum Thema: 'Windows ist das  Problem'. Offensichtlich gibt es Systeme wie TwinCat und IntervalZero RTX die Windows in ein hartes RTOS verwandeln. Mit TwinCat kenne ich mich aus. Das installiert man auf dem PC und hat dann den System-Service in der Task-Leiste. Dann kann man anfangen nach IEC1131 sein Programm zu schreiben und mittels des ADS-OCX Daten mit mit einer vb.net Applikation auszutauschen. 



LowLevelMahn schrieb:


> Ich arbeite bei sowas mit C/C++ - damit kann man einfach viel gezielter (weil man gezwungen ist) die Heap-Bewegung usw. kontrollieren - wenn es denn wichtig ist
> einen Geschwindigkeitsvergleichen zwischen .Net und C++ resultierendem Code ist zu Anwendungsspezifisch deswegen kann man dazu kaum oder nur schlechtes sagen. Die RTX ist eine Soft-SPS und "könnte" dir kürzere Abtastraten als 30ms bringen - oder meinst du RTX mit C++ programmieren?



Ich meinte das IntervalZero RTX, siehe hier:

https://de.wikipedia.org/wiki/RTX:_Real_Time_eXtensions_für_Windows

Da heisst es: 

RTX wird von Embedded-Geräteherstellern verwendet, die Windows als handelsübliches Betriebssystem nutzen, jedoch den Bedarf an einem Echtzeit-Betriebssystem (RTOS) haben. Durch den Software-Einsatz kann auf zusätzliche Echtzeit-Hardware verzichtet werden.Die Anwendungsentwicklung für RTX64/RTX erfolgt mit Microsoft Visual Studio in C/C++ mit Windows-artigen APIs. RTX64/RTX ausführbare Dateien tragen die Namenserweiterungen «.rtss» und DLLs verwenden «.rtdll».


----------



## LowLevelMahn (7 Oktober 2015)

> Zum Thema 'Wie ich etwas schreibe' bzw. was du da heraus liest, darf mich mich selber aus Posting Nr.16 zitieren.



ich habe mich einfach durch dein "Ich habe bisher immer die Soft-Realtime-Faehigkeiten genutzt" iritieren lassen



> Nun noch meinen Senf zum Thema: 'Windows ist das Problem'. Offensichtlich gibt es Systeme wie TwinCat und IntervalZero RTX die Windows in ein hartes RTOS verwandeln.



deren gibt es viele INTime, CeWin (nicht WinCE), und und und - die erlaube harte Echtzeit in einem abgekoppelten Subsystem unter Windows und meist
auch die Kommunikation mit dem Host-Windows

mir ist aber aus deinen Post nicht ganz klar was du erreichen willst

du hast eine NC, eine S7 mit der du mit Libnodave kommuniziert und auch TwinCAT zum daddeln rumliegen, du
hast auch davon gesprochen die Visualisierung in LabView zu machen falls es dafür besser geeignet ist

1. am Anfang ging es nur um die Kommunikation - multiple Threads per SPS, auf n Verbindungen als Thread usw.
mit der du jetzt eine Raten im GUI von 30-40ms erreichst

2. jetzt hast du x Verbesserungen im GUI-Code gemacht und deine Applikation läuft immer schneller/besser

3. dann ging es plötzlich um Harte- und Softe Echtzeit per Windows-Extension - was hat das mit deiner Applikation zu tun?
denkst du deine TCP/IP-Kommunikation oder GUI werden damit schneller?

deine Chart-Komponenten und GUI frisst viel Zeit - wie du ja schon bemerkt hast - deswegen mein Tip auch mal eine andere
Chart-Komponenten zu testen die noch schneller ist - oder sogar für hohe Geschwindigkeit entwickelt wurde

deine Applikation läuft nicht in der Echtzeiterweiterung und selbst wenn
würde dein GUI dadurch auch nicht schneller - eher langsamer

und wenn es dir um Mini-Details und Zeitverhalten geht musst du das ganze eher
auf C/C++ Basis machen, nur Konsole ohne Ausgabe, alles in fix allokierte und Zeiterfassung nutzen die nicht schon per se 10-20ms ungenau ist
damit du 100% frei von Einflüssen bist

was hast du also vor? - das ist es was mich an deinen Postings verwirrt


----------



## Burkhard (8 Oktober 2015)

LowLevelMahn schrieb:


> was hast du also vor? - das ist es was mich an deinen Postings verwirrt



Na ich hab doch geschrieben, ich will ein Programm schreiben mit dem ich Daten aus mehreren PLCs lesen kann und gleichzeitig mein Wissen über Multi-Threading erweitern und die Grenzen der Soft-realtime von Windows und vb.net austesten. 

Gleichzeitig bin ich auf der Suche nach Verbesserung der Realtime-Faehigkeiten. Denn unter vb.net bin ich da sicher an der Grenze des machbaren. 

Wenn ich da mehr C++ programmieren muss, auch gut. Ich habe bereits Erfahrungen mit C++. Beispielsweise habe ich das Lesen und Schreiben mit ReadRequests mit libnodave mit einem kleinen C++ Programm realisiert. Aber ich vermute, das Programmieren von Threads ist unter C++ nicht so einfach wie mit dem .net-Framework. Auch kann ich unter C++ nicht die Toolbox-library von Jochen verwenden.


----------



## LowLevelMahn (8 Oktober 2015)

> Na ich hab doch geschrieben, ich will ein Programm schreiben mit dem ich Daten aus mehreren PLCs lesen kann und gleichzeitig




Das habe ich schon verstanden - nur deine letzten Ausflüge Richtung Echtzeit-Erweiterung passen nicht ins Bild - oder du hast eben immer noch nicht
gesagt was du mit der Erweiterung machen willst/dir erhoffst? Und weil ich nicht verstehe was dir das in deine jetzigen Situation bringen soll wirkt dein
Echtzeitfachwissen ein wenig Wikipedia-basiert 




> mein Wissen über Multi-Threading erweitern und die Grenzen der Soft-realtime von Windows und vb.net austesten.




denkst du das du mit den 30ms per TCP/IP und den paar Threads schon an die Grenze von Windows/VB.Net gehst? - das fehlt aber schon noch was
die SPS ist hier die stark beschränkende Einheit - und moeglicherweise dein Chart wenn schneller Datenkommmen - und da kannst du nur noch mit direkter SPS<->PC TCP/IP-Kommunikation (also mit SPS Programmierung) mehr erreichen
Das hat aber alles absolut nichts mit der Echtzeitfähigkeiten von deinem Betriebssystem noch VB.Net zu tun - oder was denkst du?


Erstmal: Profiler - wo sind deine Bottlenecks


ANTS von Redgate (als Demo) http://www.red-gate.com/de/products/dotnet-development/ants-performance-profiler/


1. Strategie - Belastungstest deiner Infrastruktur (mit Profiler)


Erweiter dein Sytem um eine "künstliche" SPS(libnodave Klasse) die sehr sehr viel schneller Daten liefert als die echte SPS und schau welche Raten du da erreichst
Falls du die libnodave Aufrufe in einer Klasse gekapselt hast diese durch einen libnodave-Fake ersetzbar machen (mit gleichem Interface)
du solltest damit so nah wie moeglich an der SPS bleiben damit deine künstliche SPS auch durch deine normale Infrastruktur Daten liefert - keine Abkürzungen
damit kannst du im Profiler viel deutlicher feststellen wie Performant deine Verarbeitung ist UND  Synchronisationsprobleme-Probleme besser/häufiger Aufdecken -> langsam=fast immer sicher, sau-schnell=böse

erstmal deine GUI komplett für das Profiling abkoppel (mach es am besten abkoppelbar) - und keine Ausgabe (auch nicht Konsole - die ist noch langsamer wegen den Consolen-Puffern)

2. Strategie - eine schnellere SPS die ueber libnodave funktioniert


Installier (als Demo) dir die Soft-SPS von Deltalogic damit kannst du unbegrenzt Read/Write per libnodave machen
http://www.deltalogic.de/automatisierungstechnik/software/accontrol-s7-win32.html
nur eben schneller als mit der echten SPS


3. Strategie - auch mal eine andere Kommunikationlibrary - siehe AGLink (http://www.deltalogic.de/automatisierungstechnik/software/accon-aglink.html) - auch mit VB.Net, einfach nur als vergleich
Vergleichen ist immer gut um ein Gefühl für die Komponenten (GUI, SPS-Kommunikation, Infrastruktur) zu bekommen


(4. Strategie) ein anderes Chart-Tool


also


```
SPS (echte S7, Accontrol) --------> Kommunikations-Object ( per Libnodave, als Simulation (=brutal schnell), AGLink) ----> deine Infrastruktur (Liste, Puffer, etc) ----> GUI/Chart (z.B. [URL]http://arction.com[/URL])
```

fuer die Verbindungsabstraktion wuerde ich zur Vereinfachung folgendes machen


```
class DBVar
   DB-Nr, Offset, Value

interface Verbindung
  Verbindung(IP, Rack, Slot)
  Read(DBVar)
  Read(DBVar[])

  konrekte Klassen mit den spezifischen Konstruktor und Read-Methoden
  class LibnodaveVerbindung: Verbindung
  class AGLinkVerbindung: Verbindung
  class SimulationVerbindung: Verbindung (liefert einfach fixe Werte - kein Random weil das auch Zeit kostet)
```

wenn du dann die Verbindungsklasse als generischen-Parameter in deinen Test gibts kannst du leich hin und her wechseln
- und dein ganzer Code mit Thread pro SPS, Thread pro Verbindung usw bleibt voellig unveraendert (das/soll muss auch so sein)

und du musst damit es Sinnvoll ist die Strategie 1 (Profiling, Messen) und dann Strategie 2 fahren



> Gleichzeitig bin ich auf der Suche nach Verbesserung der Realtime-Faehigkeiten.
> Denn unter vb.net bin ich da sicher an der Grenze des machbaren.




Wenn du auf der TCP/IP-Seite nichts mehr reissen kannst (und die Kommunikation dort ist ja nicht wirklich Umfrangreich)
kannst du nur doch an deinem Programm arbeiten - da wäre Strategie 1-4 schon mal der richtige Weg




> Wenn ich da mehr C++ programmieren muss, auch gut.




erstmal dein VB.Net Programm ordentlich Benchmarken (die künstliche Tests mit einer simulierten SPS)


das Wissen laesst sich genau so auf C++ anwenden - nur eben kleiner/statische


----------



## Burkhard (9 Oktober 2015)

Hallo LowLevelMahn, vielen Dank fuer die hilfreichen Hinweise. Ich will gerne soviel wie moeglich lernen.

Das Arction-Chart ist ja schweineteuer!! Wow!!


----------



## LowLevelMahn (9 Oktober 2015)

> du hast eben immer noch nicht
> gesagt was du mit der Erweiterung machen willst/dir erhoffst



und?



> denkst du das du mit den 30ms per TCP/IP und den paar Threads schon an die Grenze von Windows/VB.Net gehst?



und?



> Hallo LowLevelMahn, vielen Dank fuer die hilfreichen Hinweise



keine Hinweise - Arbeitsanweisungen 



> Ich will gerne soviel wie moeglich lernen.



du meinst implementieren - lernen ist immer dabei



> Das Arction-Chart ist ja schweineteuer!! Wow!!



deine Arbeitszeit/Versuche/Fehler kosten sehr schnell mehr


----------



## LowLevelMahn (19 Oktober 2015)

Im letzten Post von mir waren noch Fragen enthalten siehe "?"

und bist du schon weiter gekommen?


----------

