Wir haben nun das Zeitalter der KI erreicht, weshalb hier weniger Lösungen und mehr das Technik Tagebuch Posts kommen.
Lösungen verlinke ich Kategorisch extra auf den weiteren Seiten des Blogs
Ist schon etwas länger her, daß ich an dem Thema gearbeitet habe. Aber Arbeit geht vor und da gibt es viele Aufgaben zu erledigen.
Dennoch wollte ich mal wieder mein Application Framework weiter ausbauen und mußte nach einem Update mit Visual Studio feststellen, daß mein Projekt sich nicht mehr Kompilieren ließ. Aus irgendeinem Grund, können in .NET 7 keine .NET MAUI-Elemente mehr erkannt werden. Lösung ist ein Update. Aktuell ist .NET 9 raus, aber das lief erstmal nicht und daher habe ich mich entschieden erstmal auf .NET 8 zu Upgraden. Richtig ich mußte Upgraden. Einfach die .NET-Version anheben, hat nicht funktioniert. Und richtig gelesen, die Funktion heißt „Upgrade“, das sich doch etwas, wie "Migrieren" anfühlte. Weil mein Projekt nicht so viele Abhängigkeiten hat, war die Ausführung mehr den Button für Weiter zu klicken.
Rechte Maustaste auf das Projekt und dann im Kontext Menü "Upgrade" drücken.
Die Option "In-place project upgrade" kam meiner Anforderung am nächsten.
Auswahl ist .NET 8, da bin ich mir sicher, dass die Dinge funktionieren, die funktionieren sollen.
Auswahl der zu Upgradenen Inhalte so belassen.
Und dann warten, bis alle Dateien bearbeitet wurden. In meinem Fall habe ich noch ein Problem mit SQLite, was aber die weitere Bearbeitung zunächst nicht stört.
Was ist das?
Brauche ich nicht, da ich nicht plane, die Anwendung auf einem Apple Gerät mit iOS zu entwickeln. Also weg mit dem drücken auf X. Und dann in die Projekt Eigenschaften öffnen.
Einfach den Haken rausnehmen.
Doch zu guter letzt
Bevor ich weiter am Projekt entwickeln kann, sollte die Unit Tests wieder laufen. Nur ein erfolgreicher Unit Test von sechs. Was allerdings auch noch sehr übersichtlich ist und auch der noch geringen Funktionalität der Anwendung zurückzuführen ist.
Die AdSense auf meinem Blog hatte ich mir letzten nochmal angesehen und muss sagen, dass Werbung mich nervt. Und das so sehr, dass ich Adsense entfernt habe. Den mit dem Popup Ähnlichen Werbung und Werbebanner zwischen den Blogpost empfinde ich als sehr penetrant und ist oft ein Grund, warum ich einige Blogs und Webseiten verlasse.
Brauche ich AdSense
Nicht wirklich. Damals wollte ich sehen, ob man damit Geld verdienen kann. Ja das geht, aber nach über 10 Jahren habe ich 24 € eingenommen. Ausgezahlt wird erst ab einer bestimmten Summe, ich glaube mit 70 € werden die Einnahmen ausgezahlt. Wenn das so bei mir bleibt, habe ich zum Renteneintritt meine erste Auszahlung.
Ok, ich poste nicht regelmäßig und meine Reichweite schöpfe ich nicht aus. Da ist noch Potenzial nach oben, mit dem ich die Zielsumme schneller erreichen könnte.
AdSense kann man einstellen
Ja das kann man einstellen und das hatte ich auch bereits so angepasst, dass nur oben und einen Seitenbanner erschien. Das fand ich ok. OK fand ich das nicht, als ich jemanden meinem Blog zeigte, dass sich ein Popup Ähnliche Werbung erschien, den ich nicht zugestimmt habe.
Und nachdem ich das Design geändert habe, war das so viel Werbung zu sehen, dass ich keine Notwendigkeit darin sah, AdSense weiter noch zu verwenden. Haben wir im Alltag eh schon zu viel Werbung?
Fazit
Wir wollen alle gerne an unseren Werken etwas verdienen. Aber wir wollen den Nutzer auch nicht vergraulen. Dezent und Sinnvolle Werbung ist in Ordnung, aber sobald eine Webseite voll mit Werbebannern ist, frage ich mich immer als erstes, wie seriös ist diese Webseite. Ab dem Punkt überlegt der Nutzer, sowie ich, ob ich die Webseite verlasse und weitersuche.
Ich befürchte immer auf einer Webseite mit zu viel Werbung, dass man sich verklickt und sich einen Virus einfangen könnte.
Im Januar hatte ich den Blog Post geschrieben, in dem ich das Problem mit der Resource aus andere Assembly gelöst hatte. Die Lösung war peinlich einfach gewesen, aber ich denke, das vielleicht die Information den einen oder anderen weiterhelfen kann.
Aber kommen wir zu dem Tool für Lagerverwaltung, das auf Grund erhöhten Aufwand bei meiner Arbeit, die ich bei meinem Kunden aktuell habe. Ein Thema, über das ich in meinem Zukünftigen Buch schreiben werde, wenn ich genug Erfahrungen aus den Projekten zusammengetragen und Humorvoll ausgearbeitet habe.
Aber kommen wir zu dem eigentlich Thema für heute. Wo stehe ich gerade mit dem Projekt?
Benötigt
Github
Visual Studio 2022
.NET 7 (oder höher)
Zusammenfassen
Was sind meine nächsten Ziele, damit ich das Tool weiter entwickeln kann und welche Funktionen kommen in das Codexzier Application Framework.
Aktueller Stand
Die Solution mit mehrere Projekten Inhalten ist da.
Das UI Projekt selbst ist noch in WPF. Beim letzten mal wurde nur das Codexzier Application Framework für .NET MAUI angelegt.
In den Issues habe ich nur die eine Aufgabe Konzept ausschreiben.
Das Konzept selbst steht noch nicht im Wiki und muss noch als eigenes Kapitel abgelegt werden.
Eine Wiki in Github anlegen für das Tool ist auch schon angelegt. Das andere Wiki war für das Codexzier Application Framework für WPF und eine neue Ausführung mit .NET MAUI ist offen.
Wo fange ich an?
Eigentlich worauf ich Lust habe, aber ich kann nicht alles auf einmal erledigen. Also Entwickle ich die Grundfunktionalitäten, die ich allgemein brauche und die ebenfalls für das Tool relevant sind, aber auch für meine anderen Pojekte, über die ich auch offen habe.
Ich brauche allgemein
Die Projekte in der Solution aktualisieren nach .NET 8
Eine Druckfunktion
Style anlegen für Datagrid
Kleine Schritte
Zeitlich bin ich viel eingebunden. Wer ist das nicht, wenn man Beruflich mehr als 40 Stunden arbeitet und darüber noch eine Familie hat, mit der man gerne Zeit verbringt. Eigentlich kann ich die Privaten Projekte lassen und auch das schreiben eines Blogpost lassen. Dennoch müssen wir hin und wieder Dinge erlernen und ich lerne durch Probieren und darüber schreiben.
Auf dem Markt gibt es viele verschiedene Module an Motortreibern. Diesmal
verwende ich einen recht einfachen, der zur Ansteuerung bis zu vier PWM
Signale verwendet. Der Motorschield für den Arduino hingegen benötigt noch
eine Steuerung eines Shiftregister 74HC595. Ich weiß, das geht auch ohne,
aber ich beziehe mich diesmal auf fertige Module, die kompakt aufgebaut
sind.
Aber nur ansteuern wäre diesmal zu langweilig und daher habe ich hier als
Ziel, den Lego Technic Stunt-Racer damit zu betreiben. Wer das Modell kennt,
weiß, dass dieser mit einer Infrarot Fernbedienung ausgeliefert wird und das
eher nur in der Wohnung funktioniert.
Benötigt wird:
Modul MX1508 (DC Motor Treiber)
Arduino Mini Pro (5V Ausführung)
2x Servo Kabel
2x Lego Power Function Verlängerungskabel
Lego Technic Fahrzeug mit Power Function
Zwei Kanal Fernsteuerung und ein Empfänger mit PWM Signal Ausgängen.
Betrieb mit Funk-Fernsteuerung
Der Microcontroller soll zwei PWM Signale verarbeiten, so das damit zwei
Motoren gesteuert werden können. Als Fernsteuerung soll links der Stick für
die Geschwindigkeit sein und rechts der Stick für das Lenken. Also wie bei
jedem anderen RC Auto.
Pin Belegung Power Function Kabel
Für die Umsetzung reicht es zu wissen, welche Leitung von den vier was ist.
Bei der Suche war immer die Beschriftung 9V, 0V, C1 und C2 gegeben, weshalb
ich das ebenfalls übernehme.
Für den nächsten Schritt müssen die beiden Power Function Kabel so
abgeschnitten werden, dass die Verbindung für das eigene Projekt passen.
Motor Treiber MX1508
Den verwendeten Motor Treiber MX1508 findet man fälschlicherweise auch unter
L298N. Der Motor Treiber L298N funktioniert ebenfalls für dieses Vorhaben,
ist allerdings etwas übertrieben und ist auch eher was für größere Projekte
geeignet.
Daten:
Betriebsspannung 2V bis 10V
Signal Spannung für IN1 bis IN4 1,8V bis 5V
Ausgangspannung für Motor-A und Motor-B 2V bis 10V
Betriebsstrom 1,5A
Maximaler Kurzstrom 2,5A
Aufbau der Schaltung
Der folgende Schaltplan zeigt, wie die Power Function Kabeln mit dem
Motortreiber verbunden werden. Die Schaltung funktioniert auch mit einem
Lipo Akku. Daher kommt neben dem Power Function Stecker noch ein JST
Anschluss. Der Arduino Mini Pro wird über die Spannungsversorgung
mitbetrieben und über den Pin RAW angeschlossen.
Der fertige Motortreiber
Anders als auf dem Bild zuvor habe ich noch einen weiteren Anschluss für die Spannungsversorgung angebracht. Das Ermöglicht auch zwei Zellen Lipo Akkus zu verwendend, anstatt der Lego Powerfunction Battery Box. Links auf dem Bild sind vier Leitungen mit Steckern, die für den Anschluss eines Empfängers da sind.
Programmcode einstellen
Diesmal beschreibe ich nicht den Aufbau des Programmcode, sondern gehe auf
einen fertigen Motortreiber von mir ein. Für das Zielprojekt soll die
Eingabe der Fernsteuerung links für die Geschwindigkeitsregelung sein und
rechts das Lenken. Also ganz klassisch. Natürlich ginge auch eine Steuerung,
wie sie bereits von Lego Power Function mit der Infrarot Fernbediendung
vorgegeben wird.
Einstellung für den Lego Technic Stunt-Racer
// Set this value true, for show all Value on Serial Monitor.
bool mSerialMonitor = false;
// 0 = Car, Input 1 for speed and input 2 for steer
// - Alternate: Tracked vehicle, Input 1 for speed motor A and
// Input 2 for speed motor B
// 1 = Tracked vehicle, Input 1 for speed and input 2 for steer
int mVehicleMode = 1;
// invert steering direction, only tracked vehicle
boolean mVehicleModeSteerInvert = false;
// Tolerance range in which no reaction should take
// place when sticks are in the middle position.
int mDeathbandPlusMinus = 10;
// change direction signal output for motor A
boolean mReverseA = true;
// middel state of the input signal. Example: stick on neutral position
int mInputMiddleA = 1500;
// minimum value of input signal. Example: stick is move complete down
int mInputMinA = 1000;
// minimum value of input signal. Example: stick is move complete up
int mInputMaxA = 2000;
// change direaction sinal output for motor B
boolean mReverseB = false;
// middel state of the input signal. Example: stick on neutral position
int mInputMiddleB = 1500;
// minimum value of input signal. Example: stick is move complete down
int mInputMinB = 1000;
// minimum value of input signal. Example: stick is move complete up
int mInputMaxB = 2000;
Lego Technic Stunt-Racer Umbau
Damit der Empfänger und der Motor Treiber nicht einfach so rum hängen,
sollte der Aufbau etwas geändert werden. Der Lego Technic Infrarot Empfänger
wird entfernt. Wie nun der Umbau aussieht, ist zweitrangig, Hauptsache die
Elektronik ist gut verstaut. Der folgende Umbau ist ein Beispiel.
Wort zum Schluss
Die Motoren lassen sich noch mit einer höheren Spannung betreiben.
Allerdings steigt dann auch die Belastung der Lego Teile in Form von
Verschleiß, wegen der fehlenden Kugellager.
Dann noch der hier verwendete Motor Treiber MX1508: Wegen einer falsch
ausgewiesenen Information zu L298N, dachte ich zunächst, dass eine höhere
Spannung möglich sei. Nach dem ich später für den Blog Eintrag mehr
Informationen über den verwendete Komponente suchte, stieß ich auf die
richtigen Werte. Zugegeben, ich hatte bereits mit der Fehlinformation den
Aufbau mit einem 3S Akku betrieben. Allerdings nur kurz. Für den Betrieb mit
einer hören Spannung würde dann der Motor Treiber L293D gehen, aber dann
könnten Probleme mit dem maximalen Strom geben, wenn XL-Motoren verwendet
werden.
Wenn die Ergebnisse nicht den Erwartungen entsprechen, dann ist mit Sicherheit etwas falsch. Das geschah diesmal mit dem Wemos D1 Mini. Einen bereits fertiges Code Beispiel für das Auslesen eines BMP085 Sensors mit einem Arduino, verwendete ich diesmal auf dem Wemos. Nach dem hochladen zeigten sich die nicht erwartenden Ergebnisse. Zumindest war offensichtlich, dass in meiner Wohnung keine 119 Grad Celsius herrschten und bei einem Luftdruck von 4000 Pascal wäre ich sicherlich an Sauerstoffmangel oder kochendem Blut auseinander gegangen. Also musste was an der Berechnung nicht stimmen.
Behoben
Der Fehler ließ sich relativ schnell beheben. Die Verwendeten ValueTypes int und unsigned int wurden ersetzt durch int16_t und unt16_t.
Aber warum
Ein ValueType INT ist immer das gleiche, solange die Variable als INT definiert wird auf einem System. Das eine System ist die Arduino Plattform mit dem 8Bit Mikrocontroller. Der Wemos verwendet wiederum einen 32Bit Mikrocontroller. Das sollte als erstes Auffallen und schnell sollte klar sein, dass etwas mit den Typen etwas nicht stimmt und folglich nicht mit den richtigen Werten rechnet. Eigentlich ist das von Compiler abhängig, welcher Type aus einem INT angelegt wird.
Der Folgende Code macht die Größe eines INT sichtbar, sobald ihr das auf der Ziel Plattform ausführt.
Wie man sieht, wird auf dem Wemos kein 16Bit INT, sondern 32Bit INTEGER angelegt
Arduino Nano
Wemos D1 Mini
Aber Moment mal. Damit wäre eine Berechnung auf dem Wemos genauer und der Rechenfehler dürfte erst gar nicht auftreten. Sieht man sich allerdings die Funktionsinhalte an, dann sind mehrere Stellen auffällig, wo die Werte durch Byteshifting hoch oder runter gerechnet werden. Das nur passt wiederum nur mit 16 Bit. Andernfalls muss die Funktion geändert werden.
Zur Vollständigkeit der Beispielcode mit den geänderten ValueTypes. In diesem Fall reichten die Änderungen für INT aus und kann nun für Arduino oder Wemos verwendet werden.
Kaum angeschaut, habe ich mir den Wemos mit OLED Display beim Chinesischen Händler bestellt. Dann ca. vier Wochen später lag nun das Wemos@Lolin auf meinem Tisch und versuchte gleich ein Beispiel Code darauf zu schreiben. Leider musste ich zunächst feststellen, dass die bereits bei mir installierte Bibliothek nicht dieses Board aufführte. Und damit fing die Abendliche Suche an.
Nach kurzer suche fand ich diesen Link zu espressif. Zugegeben wollte ich nicht noch ein Tool installieren, dass mir im Grunde nur die Dateien in das Ziel Verzeichnis kopiert, also klickte ich auf den Download Button von dieser Seite des Github Accounts. Anschließend kopierte ich die Sourcen in den selbst angelegten Ordner "esp32/esp32" im Unterverzeichnis der Arduino Anwendung "../Arduino/hardware/"
Nach dem Start der Arduino Anwendung konnte unter Werkzeuge => Bord => WEMOS LOLIN32 ausgewählt werden.
Dann noch den Port auswählen und die Verbindung konnte hergestellt werden. Weitere Einstellungen mussten nicht vorgenommen werden.
Zuletzt fehlt noch die Bibliothek für die OLED Display von squix78 Github Account.
Nach dem Zip Download kann der entpackte Inhalt unter "…/Dokumente/Arduino/libraries/.." hinein kopiert werden.
Jetzt kann endlich ein Programmcode auf den Wemos geschrieben werden, dass auch das integrierte OLED ansteuern kann. Zu der OLED Bibliothek liegen bereits ein paar Beispiele.
Damit diese auch funktionieren, muss die Pin Zuweisung geändert werden. Sonst erhält ihr die Meldung "'D3' was not decleared in this scope".
Hierzu ändert die Pin Zuweisung auf 5 und 4. Dann sollte sich er Programmcode kompilieren lassen.
Damit nun der Programmcode auch auf dem Wemos geschrieben werden kann, muss mit dem hochladen die ‚Boot‘ Taste gedrückt werden.
Erst dann lässt sich das Programm erfolgreich hoch laden und euer Ergebnis ansehen.
Für gewöhnlich erwartet man nach dem Kompilieren in Visual Studio, dass sich im Debug oder Release Ordner eine Datei mit der Endung *.exe befindet. Dass
die Dot NET Core Anwendung da anders ist, zeigt sich hier spätestens hier, uns
mit einer DLL Datei, die sich so zunächst nicht ausführen lässt.
Damit sich die Anwendung auch ohne Visual Studio Starten lässt, muss die Konsole geöffnet werden, dann in das Verzeichnis wechselt und dann 'dotnet ConsoleHelloDotNetCore.dll' eingegeben werden.
Jedes Mal die Console zu öffnen und bis in das entsprechende Verzeichnis zu Wechsel, kann sich als sehr langwierig und nervig erweisen. Eine einfache Lösung ist, eine Batch Datei (*.bat) zu erstellen, mit der sich dann anschließend wie gewohnt sich das Programm starten lässt.
Doppel Klick auf die Batch und die Anwendung läuft.