Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Lesedauer 7 Min.

Das Firmata-Protokoll für einfache Mess- und Steuerungsaufgaben

Wer kleinere Mess-, Steuerungs- und Regeltechnik-Aufgaben aus .NET heraus abwickeln möchte, kommt mit einem preiswerten und mit Firmata-Software ausgestatteten Arduino meist problemlos ans Ziel.
© EMGenie

Direkter Hardwarezugriff aus .NET-Applikationen setzt oft erheblichen Aufwand im Bereich des Prozessrechnerdesigns voraus. Mit dem Firmata-Protokoll gibt es eine an MIDI und Co. angelehnte Alternative, die einen bequemeren Zugang in die Welt des Internets der Dinge zu schaffen versucht.

Aus technischer Sicht orientiert sich Firmata an dem einst im MIDI-Standard implementierten Verfahren. Im Prinzip ist das System eine standardisierte Schnittstelle, über die ein Host Hardware-Interaktionsbefehle in Richtung eines angeschlossenen Prozessrechners schicken kann (Bild 1). Dieser führt die Befehle dann eigenständig aus und informiert über die Ergebnisse.

Das Firmata-Protokoll orientiert sich an MIDI (Bild 1)

Das Firmata-Protokoll orientiert sich an MIDI (Bild 1)

© Autor

Von Hardwareauswahl und intelligentem Systemdesign

Die in Bild 1 schematisch gezeigte Schnittstelle erlegt dem System Constraints auf – die physische Realität der Übertragung der Firmata-Kommandos sowie ihre Auswertung zeigen, dass das System nicht für Aufgaben geeignet ist, bei denen millisekundengenaue Reaktionszeiten gefordert sind.

 


Von der Protokollspezifikation

Die vollständigen Standards stehen auf https://github.com/firmata/protocol bereit. In der Theorie können Entwickler zusätzliche Funktionen in ihre Runtime implementieren. Dieses Thema würde allerdings den Rahmen des Artikels sprengen, weshalb wir es hier nur zur Inspiration anführen.


 

Im Bereich der Prozessrechnerauswahl wollen wir uns hier für einen Arduino Uno entscheiden. Das Firmata-Protokoll hat sich im Arduino-Ökosystemen so stark durchgesetzt, dass die Arduino-IDE einige Jahre lang eine einsatzbereite Implementierung der Schnittstelle als Beispiel und zur bequemen Auslieferung auf angeschlossene Systeme mitbrachte.

Spezifischerweise verwenden wir in den folgenden Schritten einen Arduino Uno R3 – die Hardwareauswahl erfolgte allerdings, dies sei ausdrücklich betont, nur aus dem Grund, weil dieser Prozessrechner in der Kiste des Autors oben lag. Außerdem ist er – wie in Bild 2 gezeigt – sehr preiswert.

Der Arduino Uno R3 ist preisgünstiger als mancher FT232-Dongle (Bild 2)

Der Arduino Uno R3 ist preisgünstiger als mancher FT232-Dongle (Bild 2)

© https://www.oemsecrets.com/compare/A000066?ccy=EUR&ctry=DE
Für unsere Experimente ausreichend: die Basis-Version von Firmata (Bild 3)

Für unsere Experimente ausreichend: die Basis-Version von Firmata (Bild 3)

© Autor

Da sich die https://github.com/firmata/arduino seit einiger Zeit vom Rest der IDE abgespaltet hat, müssen Nutzer der IDE in Version 2.0 die Bibliothek von Hand herunterladen. Hierzu wechseln wir im ersten Schritt ins Menü, um den Bibliotheksmanager auf den Bildschirm zu holen. Danach entscheiden wir uns für die in Bild 3 gezeigte Version der Bibliothek.

Nach dem Herunterladen der Bibliothek steht ein neuer Beispiel-Ordner zur Verfügung, in dem wir den Firmata-Sketch auswählen. Nach dem Öffnen ist es empfehlenswert, den Arduino mit der Workstation zu verbinden. Die Arduino-IDE fordert danach automatisiert zur Installation von Treiber und Co. auf – ein Begehr, dem im Interesse der Bequemlichkeit stattgegeben werden sollte. Die diversen Nachfragen in Bezug auf die Hardware-Installation sind in gleicher Weise abzunicken.

Im nächsten Schritt folgt die Kompilation. Wer probeweise einen modernen Arduino (Stichwort R4) anschließt, sieht sich eventuell mit einer nach dem folgenden Schema aufgebauten Fehlermeldung konfrontiert:

 

#error "This library only supports boards with an AVR, SAM, SAMD, NRF52 or STM32F4 processor."

 

In diesem Fall müssen Sie einfach eine andere Zielhardware auswählen.

Auswahl des korrekten Firmata-Pakets

Wie im Fall vieler anderer der Maker-Szene nahestehenden Technologien gilt auch bei Firmata, dass Entwickler aus verschiedenen Bibliotheken wählen dürfen. Die auf https://github.com/vvvv/VL.IO.Firmata ist insofern suboptimal, als sie sich eng in das https://vvvv.org einbindet und für eine „alleinstehende“ .NET-Applikation nicht wirklich ideal geeignet ist. Erfreulicherweise bietet Microsoft seit einiger Zeit eine hauseigene GPIO-Bibliothek an, die Teil des allgemeinen IoT-Frameworks und damit explizit auch für die Arbeit mit Firmata optimiert ist.

Unsere erste Aktion ist das Öffnen der NuGet-Konsole, wo die Pakete Iot.Device.Bindings und System.Device.Gpio in die Solution aufzunehmen sind. Der Autor experimentiert in den folgenden Schritten mit einer Applikation auf Basis der Vorlage Konsolen-App; als .NET-Version wurde die Version 9.0 des Frameworks gewählt.

Im nächsten Schritt müssen wir das von Visual Studio generierte Projektskelett anpassen. Als Erstes ist die Inklusion der folgenden Namespaces erforderlich:

 

using Iot.Device.Arduino;
using System.Device.Gpio;
using System.IO.Ports;

 

Aus Sicht der Workstation präsentiert sich ein mit Firmata-Firmware beladener Arduino wie ein per COM-Port ansprechbares Gerät. Die Bestimmung des Aufenthaltsorts erfolgt am bequemsten in der Arduino-IDE, wo der COM-Port des Boards direkt sichtbar ist (Bild 4).

Dieser Arduino sitzt auf COM 29 (Bild 4)

Dieser Arduino sitzt auf COM 29 (Bild 4)

© Autor

Mit diesem Wissen ausgestattet können wir im nächsten Schritt die Initialisierung nach folgendem Schema durchführen:

 

using var port = new SerialPort("COM29", 57600);
port.Open();
using var board = new ArduinoBoard(port.BaseStream);

 

Das einst von Windows für Raspberry Pi und Co eingeführte Programmierschema des GPIO-Controllers ist auch in der vorliegenden Bibliothek anzutreffen. Aus diesem Grund müssen wir im ersten Schritt einen Controller ins Leben rufen. Pin 13 ist in der Welt des Arduinos mit einer LED verbunden, die für die klassische Hello-World-Blinkanwendung verwendet werden kann:

 

using GpioController controller = board.CreateGpioController();
var pin = controller.OpenPin(13, PinMode.Output);
board.SetPinMode(13, SupportedMode.DigitalOutput);

 

Im nächsten Schritt nutzen wir das Pin-Objekt, um nach folgendem Schema ein langsames Blinken der LED zu befehligen:

 

while (true)
{
    pin.Write( PinValue.High);
    Thread.Sleep(1000);
    pin.Write( PinValue.Low);
    Thread.Sleep(1000);
}

 

Die Programmausführung in Visual Studio sorgt bei angeschlossenem Arduino dann für langsames periodisches Blinken der Leuchtdiode.

Hilfreich ist am Arduino Uno R3 außerdem das Vorhandensein der RX- und TX-Leuchtdioden, die bei Datenaustausch zwischen Prozessrechner und Workstation aufleuchten. Sie ermöglichen das Überwachen des Firmata-Datenflusses. Das permanente Blinken zeigt, dass jede Handlung vom Computer aus ausgelöst wird.

Kurzer Geschwindigkeitstest der Implementierung

Die weiter oben durchgeführten Überlegungen haben bestätigt, dass das Firmata-Protokoll für extrem schnell arbeitende Aufgaben absolut ungeeignet ist. Wer etwas mehr Performance aus dem Arduino Uno herauskitzeln möchte, kann im Sketch die Baudrate an der folgenden Stelle auf 115200 BPS erhöhen:

 

Firmata.begin(57600);
while (!Serial) {
    ; // wait for serial port to connect. Needed for ATmega32u4-based boards and Arduino 101
}

 

Für noch schnelleres Arbeiten wäre ein leistungsfähigerer Mikrocontroller erforderlich – im Interesse der Bequemlichkeit bleiben wir in den folgenden Schritten bei der Basis-Baudrate.

Als Nächstes entscheiden wir uns für folgenden Code, der ob des Weglassens der Aufrufe von Thread.Sleep die maximal mögliche GPIO-Performance abruft:

 

while (true)
{
    pin.Write( PinValue.High);
    //Thread.Sleep(1000);
    pin.Write( PinValue.Low);
    //Thread.Sleep(1000);
}

 

Auf einem angeschlossenen Oszilloskop präsentieren sich die Ergebnisse der Programmausführung dann wie in Bild 5 gezeigt.

Die Ausgabe der charakteristischen Wellenform beginnt (Bild 5)

Die Ausgabe der charakteristischen Wellenform beginnt (Bild 5)

© Autor

Zu beachten ist neben der vergleichsweise gemächlichen Arbeitsgeschwindigkeit auch die verwaschene Signaldarstellung. Sie weist darauf hin, dass der Firmata-Sketch bei seiner Arbeit immer wieder eine Denkpause einlegt.

Reaktion auf Eingangsereignisse als zweiter Geschwindigkeitstest

Als Nächstes wollen wir unser System mit einem Funktionsgenerator verbinden, um dadurch Rückschlüsse über die Verarbeitungs-Geschwindigkeit zu gewinnen. Im Interesse der Bequemlichkeit wollen wir dabei nicht auf Polling, sondern auf Softwareinterrupts setzen. Zu beachten ist, dass es in hauseigenen Varianten von Firmata – man spricht auch von Custom Firmata – ein alternatives Programmierschema gibt, das die Hardware-Interrupt-Engine ausnutzt.

Hier sollen allerdings die Interrupts auf Softwareebene ausreichen, weshalb wir einen weiteren Pin nach folgendem Schema deklarieren:

 

var inPin = controller.OpenPin(3, PinMode.InputPullUp);
controller.RegisterCallbackForPinValueChangedEvent(
    3,
    PinEventTypes.Rising | PinEventTypes.Falling,
    OnPinChanged
);

 

Um die Programm-Beendigung zu verhindern, platzieren wir dahinter einen Aufruf von Console.Readline:

 

Console.WriteLine("Am Arbeiten...");
Console.ReadLine();

 

Zu guter Letzt ist noch ein Eventhandler erforderlich, der beim Eintreffen von Änderungs-Ereignissen zur Ausführung gelangt. Im Fall des vorliegenden Programmbeispiels wird er sich folgendermaßen präsentieren:

 

void OnPinChanged(object sender, PinValueChangedEventArgs args)
{
    if (args.ChangeType == PinEventTypes.Rising)
    {
        pin.Write(true);
    }
    else if (args.ChangeType == PinEventTypes.Falling)
    {
        pin.Write(false);
    }
}

 

Im nächsten Schritt bietet es sich an, das System mit dem in Bild 6 gezeigten Ereignis anzuregen. Zu beachten ist, dass die Geschwindigkeit von 50 Hz mit Sicherheit alles andere als schnell ist.

Die Anregung erfolgt eher gemächlich (Bild 6)

Die Anregung erfolgt eher gemächlich (Bild 6)

© Autor
Reiz und Reaktion (Bild 7)

Reiz und Reaktion (Bild 7)

© Autor
Das System hinkt den Ereignissen hinterher (Bild 8)

Das System hinkt den Ereignissen hinterher (Bild 8)

© Autor

Im DPO-Schirmbild können wir den Kanal 1 dann als Anregung ansehen, während Kanal 2 die System-Reaktion beschreibt (Bild 7).

Verdoppeln wir die Arbeitsfrequenz dann auf 100 Hz, so sehen wir wie in Bild 8 gezeigt starke Verwischungen. Es ist also davon auszugehen, dass die Ereignisse schneller eintreffen, als unser System sie verarbeiten kann.

Fazit

Wer einfache Aufgaben der Mess-, Steuerungs- und Regeltechnik aus .NET heraus vornehmen möchte, kommt mit einem preiswerten und mit Firmata-Software ausgestatteten Arduino oft problemlos ans Ziel. Die hier durchgeführten Experimente dienen hoffentlich als Anreiz für weitere eigene Versuche – Elektronik ist und bleibt ein faszinierendes Themenfeld.

Neueste Beiträge

Software-Lifecycle 2.0 - Infinite AI Conference 2026
Die IAIC 2026 erklärte 140 Teilnehmenden, wie KI den Software-Lifecycle umkrempelt.
3 Minuten
24. Jul 2026
Figma-Praxisbeispiel digitales Fotobuch: Integration, Logik und Feinschliff - UX goes Dev, Teil 5
Der klickbare Prototyp aus dem vorangegangenen Teil dieser Serie wird in Richtung Anwendung weitergedacht: Wie lässt sich der Entwurf mit C# und XAML, etwa auf Basis der Uno Platform, technisch strukturieren?
9 Minuten
23. Jul 2026
Copiloten, Code und Community - DWX 2026
Zwischen Workshop-Laptops, Casino-Chips und KI-Diskussionen: Wie die DWX 2026 im Rosengarten 2000 Entwickler:innen vier Tage lang aus dem Alltag katapultiert hat.
7 Minuten
23. Jul 2026

Das könnte Dich auch interessieren

.NET-Anbindung für die Llama-KI - LLamaSharp
Open-Source-KI auf dem lokalen Gerät nutzen – mit handhabbarem Speicherbedarf und optionalem Zugriff auf externe Datenquellen.
8 Minuten
13. Jan 2025
Übersehen seit .NET 8: TimeProvider für testbare Zeit
Seit .NET 8 gibt es TimeProvider als offizielle Zeit-Abstraktion. Doch noch zweieinhalb Jahre später ist sie in vielen Projekten unbekannt.
6 Minuten
1. Jul 2026
Fünf freie .NET Decompiler - Mark Pelf, CodeProject
Der serbische Softwareentwickler Mark Pelf stellt bei CodeProject fünf freie .NET Decompiler vor.
2 Minuten
6. Mär 2023
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige