USB kam für Elektroniker einer Vertreibung aus dem Serail gleich - viele früher einfach realisierbare MSR-Aufgaben arbeiteten nun in Arbeit aus. Mit der für die Desktop-Programmierung vorgesehenen Meadow.Windows-Umgebung versucht Bryan Costanich, dieses Problem zu beheben.
Worum geht es hier?
Dass die Meadow F7-Ausführungsumgebung umfangreiche Treiber-Unterstützung mitbringt, ist aufgrund diverser Besprechungen in Microcontroller.net bekannt. Mit Meadow.Desktop für Windows versuchen Bryan Costanichs Mannen wie in der Abbildung gezeigt das Einschreiben eine Abstraktionsschicht.
Bildquelle: Autor.
Für die eigentliche Hardware-Kommunikation kommen GPIO-Extender zum Einsatz-der Autor wird in den folgenden Schritten ein FTDI FT2232H-MiniModule verwenden, das über MicroUSB Verbindung mit der mit Windows 11 ausgestatteten Workstation aufnimmt.
Einrichtung einer Arbeitsumgebung.
Ob des noch sehr frühen Entwicklungsstand ist Meadow Desktop derzeit nur leidlich in das Visual Studio-Plug-in integriert-im ersten Schritt öffnen wir die Arbeitsumgebung Visual Studio 2022 Developer Command Prompt, um danach durch Eingabe der folgenden Kommandos ein Arbeitsverzeichnis zu erzeugen:
1 |
C:\Users\tamha\source\repos>mkdir devexperiment |
2 |
C:\Users\tamha\source\repos>cd devexperiment |
3 |
C:\Users\tamha\source\repos\devexperiment> |
Die eigentliche Generierung des Projektskeletts erfolgt dann in einem zweistufigen Verfahren. Als „erstes“ erzeugen wir eine neue Kommandozeilen-Applikation:
1 |
C:\Users\tamha\source\repos\devexperiment> dotnet new console --output MeadowWindowsSampleApp |
Im zweiten Schritt bekommt diese das Grundpaket Meadow.Windows eingeschrieben - es kümmert sich (unter anderem) um das Bereitstellen der in Abbildung eins gezeigten Treiberkomponenten:
1 |
C:\Users\tamha\source\repos\devexperiment> cd MeadowWindowsSampleApp |
2 |
C:\Users\tamha\source\repos\devexperiment\MeadowWindowsSampleApp> dotnet add package Meadow.Windows |
Im nächsten Schritt können wir auch schon eine charakteristische Wellenform ausgeben. Hierzu bearbeiten wir die Datei Program.cs, deren Deklaration nun nach folgendem Schema beginnt:
1 |
using Meadow; |
2 |
using Meadow.Devices; |
3 |
using Meadow.Foundation.ICs.IOExpanders; |
4 |
using Meadow.Hardware; |
5 |
|
6 |
public class MeadowApp : App<Windows> |
7 |
{
|
8 |
private Ft232h _expander = new Ft232h(); |
9 |
private IDigitalOutputPort _c0; |
Neben der Ableitung der App-Klasse von generischen Parameter Windows ist hier auch die Erzeugung der Klasse Ft232h interessant - sie erzeugt ein Abstraktionsobjekt, das den FTDI-GPIO-Expander für unseren .net-Code ansprechbar macht. Im nächsten Schritt ist das eigentliche Hochfahren des Betriebssystemkerns erforderlich:
1 |
static async Task Main(string[] args) |
2 |
{
|
3 |
await MeadowOS.Start(args); |
4 |
}
|
Zu guter Letzt findet sich dann das eigentliche Prozessrechnerprogramm, das sich vom Aufbau her stark daran orientiert, was man von der gewöhnlichen Meadow F7-Entwicklung kennt:
1 |
public override Task Initialize() |
2 |
{
|
3 |
Console.WriteLine("Creating Outputs"); |
4 |
_c0 = _expander.CreateDigitalOutputPort(_expander.Pins.C0); |
5 |
while (true) |
6 |
{
|
7 |
_c0.State = !_c0.State; |
8 |
Thread.Sleep(1); |
9 |
}
|
10 |
return Task.CompletedTask; |
11 |
}
|
12 |
public override Task Run() |
13 |
{
|
14 |
Resolver.Log.Info("Run..."); |
15 |
Resolver.Log.Info("Hello, Meadow.Windows!"); |
16 |
return base.Run(); |
17 |
}
|
18 |
}
|
Sodann bietet sich eine erstmalige Kompilation an, was auf Kommandozeilenebene in der Eingabeaufforderung nach folgendem Schema erfolgt:
1 |
C:\Users\tamha\source\repos\devexperiment\MeadowWindowsSampleApp> dotnet build |
Wie die „Prozessrechner-Variante“ ist auch der Desktop-Version der Meadow-Arbeitsumgebung vollständig modularisiert. Aus diesem Grund erscheint die Fehlermeldung error CS0234: Der Typ- oder Namespacename "ICs" ist im Namespace "Meadow.Foundation" nicht vorhanden., die auf das Nicht-vorhanden-sein eines NuGet-Pakets hinweist. Die Behebung erfolgt folgendermaßen:
1 |
C:\Users\tamha\source\repos\devexperiment\MeadowWindowsSampleApp> dotnet add package Meadow.Foundation.Ics.IOExpanders.FT232h |
Im nächsten Schritt ist eine abermalige Kompilation und Ausführung erforderlich, was die beiden folgenden Befehle erledigen:
1 |
C:\Users\tamha\source\repos\devexperiment\MeadowWindowsSampleApp> dotnet build |
2 |
C:\Users\tamha\source\repos\devexperiment\MeadowWindowsSampleApp> dotnet run |
Zum Zeitpunkt der Drucklegung dieses Artikels gilt, dass das Basispaket die benötigten Treiber für das FTDI-Modul nicht „vollständig“ bereitstellt. Stattdessen erscheint die folgende Fehlermeldung:
1 |
C:\Users\tamha\source\repos\devexperiment\MeadowWindowsSampleApp> dotnet run |
2 |
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. |
3 |
---> System.TypeInitializationException: The type initializer for 'Meadow.Foundation.ICs.IOExpanders.Ft232h' threw an exception. |
4 |
---> System.DllNotFoundException: Unable to load DLL 'libmpsse' or one of its dependencies: Das angegebene Modul wurde nicht gefunden. (0x8007007E) |
Zur Behebung öffnen Sie die URL https://ftdichip.com/software-examples/mpsse-projects/libmpsse-spi-examples/ in einem Browser ihrer Wahl, und klicken auf den Link LibMPSSE V1.0.3. Entpacken Sie das Archiv dann, und erbeuten Sie die Datei im Ordner LibMPSSE_1.0.3\Windows\libmpsse-windows-1.0.3.zip\release\build\x64 befindlichen Dateien - sie wandern in das Verzeichnis C:\Users\tamha\source\repos\devexperiment\MeadowWindowsSampleApp\bin\Debug\net7.0. Danach ist eine abermalige Ausführung möglich.
Evaluation der Ausgabegeschwindigkeit per Picoscope.
Unser hier verwendetes MiniModule besteht aus „zwei“ FTDI-Modulen - die API arbeitet normalerweise mit dem A-Modul. Aus diesem Grund verbinden wir den Kanal eins des PicoScope mit Pin AC0, wo wir das in der Abbildung gezeigte Schirmbild sehen.
Bildquelle: Autor.
Im nächsten Schritt bietet es sich an, nach folgendem Schema vier Zustandsänderungen in der Arbeitsschleife zu platzieren und so Rückschlüsse über die „Arbeitsgeschwindigkeit“ zu gewinnen:
1 |
while (true) { |
2 |
_c0.State = !_c0.State; |
3 |
_c0.State = !_c0.State; |
4 |
_c0.State = !_c0.State; |
5 |
_c0.State = !_c0.State; |
6 |
Thread.Sleep(1); |
7 |
}
|
An dieser Stelle erweist sich die Nutzung der Persistenzfunktion als wenig vorteilhaft, weil sie zu „Verwachschungen“ der extrem instabilen Ausgabe führt. Die beiden Abbildungen erlauben eine Abschätzung.
Bildquelle: Autor
Experimente mit höherwertigen Interfaces.
FTDI exponiert am FT232 sowohl einen I2C-als auch einen SPI-Bus - zum Zeitpunkt der Drucklegung weisen Bryan Costanichs Mannen in der Dokumentation an mehrerlei Stelle hin, dass derzeit nur die SPI-Implementierung funktionsfähig ist. Für ein nächstes Experiment wollen wir auf das unter https://github.com/WildernessLabs/Meadow.Core.Samples/tree/main/Source/Meadow.Windows.Samples bereitstehende Beispiel setzen, dass das XXX-TFT-Display ansteuert. Erste Amtshandlung ist auch hier die Wiederherstellung der diversen benötigten Pakete - öffnen Sie hierzu die Datei https://github.com/WildernessLabs/Meadow.Core.Samples/blob/main/Source/Meadow.Windows.Samples/IO/SPI/SPI.csproj, und analysieren Sie das nach folgendem Schema aufgebaute Mark-Up:
1 |
<ItemGroup> |
2 |
<PackageReference Include="Meadow.Foundation.ICs.IOExpanders.Ft232h" Version="0.*" /> |
3 |
<PackageReference Include="Meadow.Units" Version="0.*" /> |
4 |
<PackageReference Include="Meadow.Windows" Version="0.*" /> |
5 |
<PackageReference Include="Meadow.Foundation.Displays.TftSpi" Version="0.*" /> |
6 |
</ItemGroup> |
Im Fall des vorliegenden Beispiels lassen sich die fehlenden Elemente nach folgendem Schema importieren:
1 |
C:\Users\tamha\source\repos\devexperiment\MeadowWindowsSampleApp> dotnet add package Meadow.Foundation.Displays.TftSpi |
2 |
|
3 |
C:\Users\tamha\source\repos\devexperiment\MeadowWindowsSampleApp> dotnet add package Meadow.Units |
Leider gilt, dass die Ausführung des vorliegenden Programms im Moment zu folgenden Problemen führt:
1 |
C:\Users\tamha\source\repos\devexperiment\MeadowWindowsSampleApp> dotnet run |
2 |
Update Service is disabled. |
3 |
Creating SPI Bus |
4 |
Creating Display |
5 |
App Error in App Initialize: Native error: FT_INVALID_PARAMETER |
6 |
System.Exception: Native error: FT_INVALID_PARAMETER |
7 |
at Meadow.Foundation.ICs.IOExpanders.Native.CheckStatus(FT_STATUS status) |
8 |
at Meadow.Foundation.ICs.IOExpanders.Ft232SpiBus.OnConfigurationChanged(Object sender, EventArgs e) |
9 |
at Meadow.Hardware.SpiClockConfiguration.set_Speed(Frequency value) |
10 |
at Meadow.Hardware.SpiCommunications.AutoSetBusSpeedAndMode() |
In der „Theorie“ ist es möglich, nach folgendem Schema „andere“ Werte einzuschreiben - die-Definitionen finden sich dabei im unter http://www.ftdichip.com/Support/Documents/AppNotes/AN_114_FTDI_Hi_Speed_USB_To_SPI_Example.pdf bereitstehenden Dokument, das die FTDI-SPI-Implementierung en Detail erklärt und auf die Pin-Zuweisungen eingeht:
1 |
public override Task Initialize() |
2 |
{
|
3 |
Console.WriteLine("Creating SPI Bus"); |
4 |
var clk = new SpiClockConfiguration(new Frequency(4000000, Frequency.UnitType.Hertz)); |
5 |
var bus = _expander.CreateSpiBus(_expander.Pins.D0, _expander.Pins.D1, _expander.Pins.D2, clk); |
In der Praxis gilt derzeit allerdings, dass auch diese „fortgeschrittene“ Variante nicht zum Ziel führt - das Problem ist Bryan Costanich mittlerweile bekannt, und wird in einem Folgeteil behoben.
Was bringt es?
Mit Meadow.Desktop erleben mit COM-und LPT-Port aufgewachsene Entwickler in vielerlei Hinsicht die „Rückkehr ins Serail“. Im Zusammenspiel mit einem FTDI-MiniModule - der OEMSecrets-Bestpreis des hier verwendeten Bauteils (siehe https://www.oemsecrets.com/compare/FT2232H-56Q%20MINI%20MDL) liegt bei 30 EUR - bekommen Entwickler wieder niederschwelligen Zugang zu Hardware unter Nutzung von C# und Visual Basic. Schon aus diesem Grund sind die „Kinderkrankheiten“ zu tolerieren!