How we work with C#

C# Programmierbeispiel

sysWORXX CTR-700 in C#

 

Allgemeine Informationen


Diese Application Note beschreibt ausführlich die Programmierung des sysWORXX CTR-700 in C# (ausgesprochen als „C Sharp“). Sie erweitert damit die bereits veröffentlichten Application Notes für Java und Node-RED.

C# ist eine typsichere, objektorientierte Programmiersprache, deren Ursprung in der Familie der C-Sprachen liegt. Sie weist eine enge Verwandtschaft zu C, C++ sowie Java auf und ist somit für Programmierer, die bereits Erfahrung mit diesen Sprachen haben, leicht anwendbar. Das wichtigste Designziel der Sprache C# war und ist ihre Plattformunabhängigkeit. Die erste Version dieser Sprache wurde 2001 veröffentlicht.

Von der Historie her ist C# eng mit dem .NET-Framework verknüpft und dadurch auch auf Windows-Plattformen am weitesten verbreitet. Durch Projekte wie Mono oder auch .NET Core von Microsoft können in C# geschriebene Applikationen aber mittlerweile auch gleichwertig auf anderen Betriebssystemen, wie zum Beispiel Linux, ausgeführt werden. Zusätzlich hat Microsoft angekündigt, dass die nächste Version des .NET Frameworks (.NET 5) .NET Core und Mono beinhalten und somit gleichzeitig eine noch größere Anzahl an Zielplattformen unterstützen wird.

Das .NET Framework bietet umfangreiche Klassenbibliotheken, Programmierschnittstellen und Dienstprogramme für die Anwendungsentwicklung. Ebenso sind viele komfortable Tools frei verfügbar, welche eine einfachere Benutzung ermöglichen und die nahtlose Verbindung mit anderen Schnittstellen erlauben, wie beispielsweise Anbindungen zu SQL-Servern, IIS, Office und vielen weiteren. Zusätzlich wird eine Laufzeitumgebung für die Ausführung dieser Anwendungen bereitgestellt.

Die wohl bekannteste Entwicklungsumgebung für die C#-Programmierung ist Visual
Studio von Microsoft. Diese wird sowohl in einer kostenpflichtigen Version, als auch in einer kostenfreien Community-Versionen angeboten. Die Community-Version darf laut den Lizenzbedingungen von Microsoft für nichtkommerzielle Projekte verwendet werden.

Darüber hinaus gibt es noch weitere und von Microsoft weitgehend unabhängige Entwicklungsumgebungen, wie zum Beispiel Eclipse, MonoDevelop, JetBrains Rider und viele weitere. Da C# mit dem .NET Framework ein sehr umfangreiches Funktionspaket beinhaltet, kann
es für die unterschiedlichsten Anwendungen verwendet werden. C# wird beispielsweise für die Erstellung von Windows-Anwendungen und -services, aber auch für Webanwendungen, Konsolenprogramme und sogar für Videospiele genutzt.

Insbesondere im IoT-Umfeld hat C# in den letzten Jahren große Verbreitung gefunden. So existieren mittlerweile zahlreiche, oftmals quelloffene Softwarepakete für die Aufbereitung von Daten sowie Kommunikations-Stacks zur Anbindung von Edge-Controllern an übergeordnete Cloud-Systeme. Mit der im Folgenden vorgestellten Laufzeitumgebung lassen sich diese Softwarepakte auch auf dem sysWORXX CTR-700 nutzen.

 

How we work with C#

Allgemeine Informationen

Als Betriebssystem für den Edge-Controller sysWORXX CTR-700 wird eine auf Debian basierende Linux-Distribution verwendet. Geeignete Laufzeitumgebungen für C#-Programme stellen Open-Source Projekte wie Mono oder .NET Core breit. Diese ermöglichen die Ausführung von in C# programmierten Anwendungen auch auf Embedded Devices. Im Fall des CTR-700 wird Mono verwendet. Für das CTR-700 stellt der Hersteller eine entsprechende Klassenbibliothek bereit, mit der sich die verschiedenen Hardwareinterfaces und IOs in eine C#-Anwendungen einbinden und ansprechen lassen. So ist es möglich, mit C# nicht nur eine generische Datenverarbeitung durchzuführen, sondern auch direkt auf die Hardware des Gerätes zuzugreifen. Im Weiteren wird durch eine Demonstration die Erstellung und Inbetriebnahme einer C#-Applikation für das sysWORXX CTR-700 veranschaulicht.

 

Eventbasierte Steuerung der Anwendung
 

Das nachfolgende Demoprogramm zeigt eine C#-Anwendung, die einen analogen Eingang des sysWORXX CTR-700 liest und den gemessenen Wert auf der Konsole ausgibt. Zusätzlich ist es möglich, über vier Knöpfe, welche an die digitalen Eingänge angeschlossen sind, eventbasierend das Verhalten des Programms zu verändern. Das gesamte Programm kann über den am Ende des Artikels angegebenen Link heruntergeladen und nachvollzogen werden.

 

Voraussetzungen

Für dieses Beispiel wurden die Community Version von Visual Studio 2019 und das .NET Framework Version 4.6.1 verwendet. Die Nutzung alternativer Entwicklungsumgebungen ist ebenso möglich, gegebenenfalls können aber einzelne Schritte in der Abarbeitung leicht abweichen.
In Visual Studio sind über den NuGet-Paketmanager zusätzlich die folgende Extensions
zu installieren:
 

• Für die Verwendung von Mono-Funktionalitäten, muss die Extension „Mono.Posix” installiert werden. Diese ist hier für den verwendeten SIGINT-Interrupt erforderlich.

• Bei älteren Versionen von Visual Studio ist es möglich, dass die Klassenbibliothek des CTR-700 sich nicht übersetzen lässt. In diesem Fall muss die Extension „Microsoft.Net.Compilers” installiert werden. Optional besteht die Möglichkeit einen Mono-Remote-Debugger zu installieren.


Dadurch ist es möglich, sich über eine Remote-Verbindung mit dem CTR-700 zu verbinden und anschließend das Programm, während es auf dem Gerät ausgeführt wird, zu debuggen. Diese Funktion wird in der beschriebenen Funktionalität nur von Visual Studio unterstützt. Dafür werden Addons wie beispielsweise der „MonoRemote-Debugger “ oder „SMonoDebugger“ benötigt. Beide bieten einen leicht unterschiedlichen Funktionsumfang, stellen im Kern aber dieselbe Funktionalität bereit. Aufgrund der etwas einfacheren Handhabung wird für dieses Beispiel „VSMonoDebugger“ verwendet. Die dazugehörige Installationsanleitung kann auf der entsprechenden Marketplace Seite von Visual Studio nachgelesen werden, zu finden unter folgendem Link:
 
https://marketplace.visualstudio.com/items?itemName=GordianDotNet.VSMonoDebugger0d62

 

Zusätzlich wird die vom Hersteller bereitgestellte Klassenbibliothek für den Zugriff auf die IOs des CTR-700 benötigt. Diese kann aus dem Demo-Projekt oder der virtuellen Maschine für das CTR-700 (siehe Download- Link SYS TEC electronic Website) entnommen werden. Die Klassenbibliothek muss anschließend in dem C#-Projekt hinzugefügt werden. In Visual Studio erfolgt dies über „Drag and Drop“ oder per Rechtsklick auf das Projekt in der Projektmappe und „Hinzufügen > Vorhandenes Element“.

 

Neben dem sysWORXX CTR-700 und einer Verbindung zu einem Windows-PC, werden zusätzlich noch vier Taster benötig. Diese müssen an die digitalen Eingänge 0 bis 3 angeschlossen werden. Über diese Taster ist später das Verhalten des analogen Eingangs steuerbar. Ebenso wird ein Quelle zur Erzeugung der analogen Werte benötigt. Dafür kann beispielsweise ein Potentiometer, Sensor, oder auch eine Spannungsquelle wie Batterien oder ein Labornetzteil verwendet werden. Dieses ist an den analogen Eingang 0 anzuschließen. Die folgende Abbildung zeigt den schematischen Aufbau der Anwendung:

Programmablauf
 

Der Ablauf und die Funktionsweise des Hauptprogramms sind in der Datei „Program. cs “ zu finden. Beim Start des Programms werden zunächst alle benötigten Variablen angelegt und Initialisierungen vorgenommen. Für die Verwendung des CTR-700 Objektes muss zunächst eine Instanz der Treiberklasse erzeugt werden. Ebenso werden weitere Hilfsvariablen angelegt, beispielsweise für den Zustand des analogen Eingangs (Spannungs- oder Strommessung) und der damit verbundenen Umrechnung (Digit und gemessene Einheiten), sowie das Zeitintervall der Messung. Anschließend wird die eigentliche Main-Schleife (MainLoop) aufgerufen.

Die MainLoop initialisiert als erstes Interrupt-Events für die digitalen Eingänge 0 bis 3 und den SIGINT-Interrupt für das Beenden des Programms (Tastenkombination „Strg + C“). Ebenso wird der dazugehörige Interrupt-Handler für die DIs registriert. Anschließend tritt das Programm eine while-Schleife ein, die – typisch für Embedded Geräte – so lange ausgeführt wird, bis entweder der Run-Schalter in die Position „STOP“ geschaltet oder der  SIGINT-Interrupt ausgelöst wird. Solang die while-Schleife ausgeführt wird, erfolgt eine zyklische Abfrage des analogen Eingangs AI0. Standardmäßig wird die anliegende Spannung jede Sekunde gemessen und auf der Konsole ausgegeben.

 

Die Ausgabe auf der Konsole erfordert die zwei Hilfsvariablen „digit“ und „sMeassure“. Sie dienen dazu, den gemessenen Analogwert umzurechnen und die dazu passende physikalische Einheit anzugeben. Der Wert eines Digits des AD-Wandlers entspricht 355.23
 

μV für die Spannungsmessung bzw. 819.87
nA für die Strommessung.
 

Ein separater Event-Handler bearbeitet die Eingaben der digitalen Eingänge über eine Switch-Case-Anweisung. Die folgende Tabelle zeigt, welcher Eingang, welche Eigenschaft des Programms verändert:
 

Tabelle 1: Steuerung ADC

toggle fullscreen

Digitaler Eingang

Auswirkung auf ADC

DI0

Schaltet auf Strommessung

DI1

Schaltet auf Spannungsmessung (Standardeinstellung bei Start)

DI2

Verringert die Zykluszeit des Programms um 100ms,

aber nicht unter 100ms

DI3

Verlängert die Zykluszeit des Programms um 100ms

Verwendung der Klassenfunktion für das sysWORXX CTR-700
 

Damit der oben beschriebene Programmablauf durchgeführt und die Hardware des CTR-700 verwendet werden kann, muss eine entsprechende Instanz des CTR-700-I/O-Treibers erstellt werden. Eine zusätzliche Initialisierung ist nicht nötigt.


var ctr700 = new Ctr700();
 

Danach wird sie wie jede andere Klasse in C# verwendet. So lässt sich beispielsweise die Ausgabe auf einen digitalen Ausgang realisieren:
 

ctr700.SetDigitalOutput(0, true);

 

Diese Methode setzt den digitalen Ausgang 0 auf true (high = an). Auf ähnliche Weise können auch digitale und analoge Eingänge ausgelesen und verwendet werden. Eine umfangreichere Dokumentation ist in der Klassenbibliothek selbst nachzulesen. Folgende Programmausschnitte zeigen die Hauptschleife, in der sich das Programm befindet und die Verwendung der eventbasierten Veränderung des Ausleseverhaltens:

 

MainLoop:

private static void MainLoop(Ctr700 ctr700)

        {

            UnixSignal sigint = new UnixSignal(Signum.SIGINT);

 

Hier findet die Initialisierung des SIGINT-Interrupts statt.
 


            for (byte i = 0; i<4; i++)

            {

                ctr700.SetDigitalInputEvents(i, Ctr700InterruptTrigger.RisingEdge);

            }

            ctr700.DigitalInputChanged += Ctr700_DigitalInputChanged;

 

Diese for-Schleife schaltet die Eventsteuerung der DI’s auf die steigende Flanke. Beim Verlassen der Schleife werden diese wieder freigegeben.

 

while (ctr700.RunSwitch == true & !sigint.WaitOne(0))

            {                        

                Ctr700_SetAdc(ctr700, AdcMode);

                           Console.WriteLine("Measured Analog Input: " +
                           Math.Round(((ctr700.GetAnalogInput(bAnalogChannel) * digit ) /
                           1000000), 4) + " " + sMeassure);              

                System.Threading.Thread.Sleep(DelayThread);                

            }

            Console.WriteLine("Shutting Down.");
 

Die while-Schleife bildet das eigentliche Hauptprogramm. Sie wird solange ausgeführt, wie der Run-Switch auf „ON“ steht und kein SIGINT-Interrupt ausgelöst wird.

 

            for (byte i = 0; i < 4; i++)
            {
            ctr700.SetDigitalInputEvents(i, Ctr700InterruptTrigger.None);
            }
            ctr700.DigitalInputChanged -= Ctr700_DigitalInputChanged;
        }

 

Wird die Hauptschleife verlassen, werden alle DI-Events wieder deaktiviert. Dies läuft analog zur Initialisierung weiter oben.

Eventhandler für die DIs:
private static void Ctr700_DigitalInputChanged(object sender,

DigitalInputChangedEventArgs args)

        {

            Console.WriteLine($"Digital input {args.Channel} is now

     {(args.State ? "on" : "off")}");

           

            switch(args.Channel)

            {
            case 0:

                    Console.WriteLine("Set Analog Input to current measurement.");
                    AdcMode = Ctr700AdcMode.Current;
                    break;

 

                case 1:

                    Console.WriteLine("Set Analog Input to voltage measurement.");
                    AdcMode = Ctr700AdcMode.Voltage;
                    break;

 

                case 2:

                    DelayThread = (DelayThread == 100) ?  100 : DelayThread - 100;
                    Console.WriteLine("Speed-up the measurement interval by 100 ms.
                                  Measurement is now at " + DelayThread + " ms");
                    break;
 

                case 3:

                    DelayThread += 100;
                    Console.WriteLine("Slow-down the measurement interval by 100 ms.
                                  Measurement is now at " + DelayThread + " ms");
                    break;

 

                default:

                    DelayThread = 1000;
                    AdcMode = Ctr700AdcMode.Current;
                    break;

            }

        }

 

Die eventbasierte Steuerung besteht im aus einer Switch-Anweisung, die je nach verwendetem digitalem Eingang die Funktionsweise des Programms verändert.

 

Übertragung, Start und Debuggen der Applikation
 

Um das Programm auf dem CTR-700 auszuführen, muss dieses zunächst kompiliert und anschließend auf das Gerät übertragen werden. In Visual Studio geschieht dies über die Funktion „Erstellen à Projektmappe erstellen“.

Dadurch wird eine Exe-Datei, je nach Einstellung im Ordner „bin/Debug“ oder „bin/Release“ erzeugt, welche anschließend auf das CTR-700 übertragen werden muss. Innerhalb von Visual Studio übernimmt diese Aufgabe das Remote Plugin transparent im Hintergrund. Das erzeugte Executeable kann aber auch manuell mit einem SFTP-Tool wie beispielsweise WinSCP auf das CTR-700 geladen werden.
 

Um die Applikation zu starten, muss auf die Linux-Konsole des CTR-700 zugegriffen werden. Möglich ist dies entweder über SSH, die Service-Schnittstelle (μUSB), oder, wie weiter unten beschrieben, das Mono-Debugger-Plugin. Nach der Anmeldung ist es notwendig, in das Verzeichnis zu wechseln, in dem sich die Exe-Datei befindet. Die Applikation wird dann mit dem folgenden Kommando gestartet werden:
 

mono DemoApplication.exe
 

Optional besteht die Möglichkeit, die Exe-Datei auch ohne den speziellen Mono-Aufruf zu starten. Dafür muss diese jedoch die Rechte zur Ausführung erhalten. Dies geschieht über die folgenden Kommandos:

 

chmod +x DemoApplication.exe

        ./DemoApplication.exe

 

Zusätzlich kann das Programm auch über „VSMonoDebugger“ übertragen und anschließend debuggt werden. Visual Studio baut über diese Erweiterung eine SSH-Verbindung auf, um so das Programm zu übertragen und zu starten. Zunächst muss aber die notwendige SSH-Konfiguration vorgenommen werden. Dies erfolgt über den Menüpunkt „Erweiterungen à Mono à Settings“. Die folgende Abbildung zeigt die Konfigurationsmaske. Die verwendete IP-Adresse und Login-Daten sind entsprechend der vorhandenen Gegebenheiten anzupassen.

 

Die Übertragung und Debug-Session wird anschließend über das Menü „Erweiterungen à Mono à Deploy and Debug (SSH)“ ausgeführt. Im Ausgabefenster von Visual Studio werden dann die auftretenden Konsolenausgaben angezeigt. Ebenso ist es möglich, das Programm Schritt für Schritt zu debuggen.

Sobald das Programm gestartet ist, wird jede Sekunde die anliegende Spannung am analogen Eingang ausgelesen. Über die digitalen Eingänge (siehe Tabelle weiter oben) kann der Messmodus und auch das Messintervall umgeschaltet werden. Jeder Veränderung wird auf der Konsole ausgegeben.

 

Abschließende Hinweise

Das vorliegende Beispiel veranschaulicht, wie einfach das sysWORXX CTR-700 mit C# und .NET verwendet wird. Jeder C#-Entwickler kann auf dieser Basis eigene Applikationen entwickeln, welche direkt mit den Schnittstellen des Gerätes interagieren.

Statt dieser einfachen Anwendung, die nur Strom- und Spannung einliest, könnten über den analogen Eingang auch Sensoren angeschlossen werden, um beispielweise Umgebungsdaten zu erhalten und auszuwerten.

Für den Einstieg und die generelle Verwendung des CTR-700 bieten wir auf unserer Produkt-Website eine Linux-VM zum Download an. Diese umfasst eine vorkonfigurierte Xubuntu-Installation. Ebenso beinhaltet diese die Klassenbibliothek, welche für die Softwareentwicklung mit C# benötigt wird. Dort ist auch weiteres Informationsmaterial, wie das Gerätehandbuch, SD-Karten-Image (Betriebssystem, usw.) zu finden, aber auch weiterführende Dokumentation zum sysWORXX CTR-700.