ChatMagLev Der KI-Weg der Levitation
über
Der neue hilfreiche Hammer im Werkzeugkasten des Software-Bastlers ist ChatGPT. Diese KI kann nicht nur völlig neuen Code schreiben, sondern auch handgeschriebene Software erweitern und verbessern. In diesem Artikel probiert Elektor-Autor Peter Neufeld dies aus und kommt zu einigen Verbesserungen an seinen beliebten Projekten mit magnetischer Levitation.
Jeder, der Hard- und Softwareprojekte entwickelt, weiß, dass sie noch lange nach der Fertigstellung nachhallen. Auch wenn der Bau- und Programmierprozess Spaß macht und das resultierende Projekt recht gut funktioniert, gibt es in der Regel Funktionen, die man gerne ändern oder der Software hinzufügen möchte, doch scheint es, dass man aufgrund anderer Verpflichtungen nie die Zeit dafür findet.
Dies war auch beim Arduino-C++-Code für mein Projekt Magnetische Levitation, die digitale Art der Fall, das ich in Elektor , auf Elektor Labs und auf meiner eigenen Website beschrieben habe. Die Hardware funktioniert einwandfrei, aber der Arduino-Code war nur ein Schnellschuss, um zu zeigen, dass es im Prinzip funktioniert. Aber „funktioniert“ und „schön“ sind zwei verschiedene Dinge!
Als ich anfing, mich ein wenig mit den Möglichkeiten der KI zu beschäftigen, kam schnell der Gedanke auf, ob ChatGPT mir bei meinen Hobby-Softwareprojekten helfen könnte. In ersten Experimenten konnte ich sehr schnell kleine Codeschnipsel und auch komplette Arduino C++ Programme von ChatGPT generieren lassen, die meinen groben, in einfacher Fachsprache formulierten Vorgaben entsprachen. Am Ende kristallisierten sich zwei Ansätze heraus, mein Hobby mit KI zu unterstützen:
1. Erweiterung bestehender Programme: Ist es möglich, bereits laufenden Arduino C++ Code mit zusätzlichen Softwarefunktionen zu erweitern, indem man den alten Code und spezifische Fragen an ChatGPT übergibt?
2. Völlig neuer Code: Kann ein komplett neues ausführbares Arduino C++ Programm von ChatGPT generiert werden, indem eine Aufgabe als beinahe konversationelle Funktionsbeschreibung an die KI übergeben wird?
Ich habe beide Ansätze an meinem ESP32-basierten Projekten „Magnetische Levitation“ getestet. Bild 1 zeigt zur Erinnerung den Hardwareaufbau und Bild 2 die damalige Schaltung. Um mein Ergebnis vorwegzunehmen: Für mich als Gelegenheits- und Hobbyprogrammierer öffnen sich plötzlich einige Türen, die vorher nur halb offen oder sogar ganz geschlossen waren. Das lässt die zweifelsohne dunklen Seiten des Einsatzes von KI-Systemen fast vergessen. Das gut funktionierende MagLev-System im Titelbild ist ein sichtbares Ergebnis von KI-gestützter Arbeit.
Ansatz 1: Erweiterungen des alten Programmcodes
Mein alter Code erfüllte die Aufgabe, war aber eher ein nacktes Skelett eines Programms, das noch auf einige nützliche Erweiterungen wartete. Ich habe versucht, meine Gedanken in einer einzigen, etwas umfangreicheren Frage und Aufgabe zusammenzufassen. Grundsätzlich aber erlaubt ChatGPT auch den Aufbau von Dialogen und die Bearbeitung von aufeinander folgenden Fragen.
Hier ist meine halb-komplexe Frage an ChatGPT:
Der folgende Arduino C++ Code für einen ESP32 soll erweitert werden. Die Triggerwerte sollen nun mit dem Zeichen „T“ beziehungsweise „t“, gefolgt von CR und LF auf der seriellen Leitung jeweils für den Hysteresewert um 1 erhöht beziehungsweise verringert werden. Ein vierter Befehl speichert alle aktuellen Werte im nichtflüchtigen RAM. Sie werden beim Start verwendet, wenn sie vorhanden sind. Verwende die Preferences-Bibliothek. Die neuen Werte werden an der seriellen Schnittstelle angezeigt. Fügen Sie den notwendigen Programmcode ein und geben Sie das komplette Programm aus.
/**************************************
Magnetic Levitation object:
Lets a LEGO man, glued together with
a neobodymium magnet, float under a modified 5V relay
- SoC: ESP32, very good:
M5Stack's ATOM LITE or ATOM MATRIX
- Electromagnet: Modified 5V-Relais HW-482
with 3V3/5V transistor input
- Sensor: HALL-sensor A1302 or A1308
***************************************/
// int TRIGGER = 2740;
// Triggerlevel is set to a level where
// weight of payload is equal to the force
// between magnet and electromagnet
int TRIGGER = 2740;
// good for payload =
// 2 Neobdym-Magnets and a LEGO-Man
int HYST = 35;
// Hysterese for trigger level
int HALL_PIN = 33;
// analog Signal from HALL-sensor at GPIO33
int HALL_VAL = 0;
int RELAIS_PIN = 23;
// GPIO23 to drive the transistor input of
// the modified 5V-relais that is used as electromagnet
int X = 0;
void setup(){
Serial.begin(115200);
pinMode(RELAIS_PIN, OUTPUT);
Serial.print("Magnetic Levitation: START " );
}
void loop(){
HALL_VAL =analogRead(HALL_PIN);
//read HALL-Sensor with
//default 0-3.9V input >> 12bit
if (HALL_VAL < (TRIGGER + X) ){
digitalWrite(RELAIS_PIN, HIGH);
// lift the payload
X = HYST;
}
else{
digitalWrite(RELAIS_PIN, LOW);
// drop the payload
X = 0 - HYST;
}
}
Sie können meinen alten Code und die Antwort von ChatGPT mit dem verbesserten Code in Listing 1 sehen.
Meine erste Reaktion: Wow! Das war einfach! Es scheint ein korrekter und logischer Code zu sein, der meine Anforderungen erfüllt und beim Testen super läuft! Ich hätte es vielleicht genauso geschrieben, aber nur, wenn ich mich mit der C++-Programmierung besser auskennen würde und/oder viel Beispielcode gesucht und angepasst hätte - und zweifellos hätte ich dafür einige Zeit gebraucht.
Gut so! Lassen wir jetzt den alten Code weg und versuchen es mit ein paar klaren Sätzen ganz von vorne.
Ansatz 2: Völlig neuer Arduino C++ Code
Ermutigt ging ich dann zu einer dialogischen Beschreibung meines verbesserungsbedürftigen Levitation-Aufbaus und der gewünschten Softwarefunktionen über ... und war sehr erstaunt, wie gut das Ergebnis war. Hier ist mein Dialog mit ChatGPT:
Der folgende Aufbau einer magnetischen Levitation soll mit einem ESP32 und einem C++ Arduino-Programm gesteuert werden. Pin 23 steuert einen Elektromagneten mit Eisenkern, Pin 33 ist der ADC-Eingang, an den ein analoger Hall-Sensor angeschlossen ist.
Unterhalb des Elektromagneten befindet sich der analoge Hall-Sensor. Der Elektromagnet ist zunächst eingeschaltet. Ein Permanentmagnet nähert sich dem Elektromagneten und seinem Eisenkern sowie dem Hallsensor von unten. Der Magnet wird von dem Kern angezogen. Er soll jedoch in der Schwebe gehalten werden. Dazu soll der Elektromagnet kurzzeitig abgeschaltet werden.
Der Hallsensor erzeugt im schwebenden Zustand eine Spannung von circa 2,4 V und ohne Dauermagnet etwa 1,5 V. Kommt der Magnet sehr nahe an den Sensor heran, steigt die Spannung auf maximal 3 V an.
Während des Programmablaufs sollte der Triggerwert für den Schwebezustand über die serielle Schnittstelle (115200Baud, 8N1) in kleinen Schritten nach oben korrigiert werden, wenn „T“ empfangen wird. Mit „t“ wird er nach unten korrigiert.
Zusätzlich sollte, wie der Triggerwert, auch ein Hysteresewert von ungefähr 50 mV eingestellt und per Tastaturbefehl entsprechend korrigiert werden.
Die manuell korrigierten Werte von Trigger und Hysterese sollen beide ausgegeben werden, wenn sie verändert wurden. Beide Werte sollen bei Eingabe von „S“ oder „s“ sicher im nichtflüchtigen Speicher des ESP32 abgelegt werden. Nur wenn bereits alte Werte im nicht-flüchtigen Speicher vorhanden sind, sollten diese als Programmstartwerte verwendet werden.
Beim Start sollte eine sehr kurze Beschreibung des Vorgangs angezeigt werden.
Schreibe das Arduino-Programm sehr kompakt und mit möglichst wenig Kommentaren, damit es vollständig in der Antwort ausgegeben werden kann.
In Listing 2 ist die Antwort von ChatGPT zu sehen, die mich immer noch verblüfft und sogar ein wenig erschreckt.
Danach habe ich den Bot gebeten, eine kurze Beschreibung des Codes zu Dokumentationszwecken zu geben.
ChatGPT antwortete:
Der bereitgestellte Code ist ein kompaktes, in C++ geschriebenes Arduino-Programm zur Steuerung eines Aufbaus zur magnetischen Levitation mit einem ESP32-Mikrocontroller. Der Aufbau besteht aus einem Elektromagneten mit einem Eisenkern und einem analogen Hall-Sensor.
Beim Starten initialisiert das Programm die serielle Kommunikation mit einer Baudrate von 115200. Pin 23 wird zur Steuerung des Elektromagneten verwendet und Pin 33 ist als Analogeingang konfiguriert, um die Ausgangsspannung des Hall-Sensors zu lesen.
Das Programm ruft die Trigger- und Hysteresewerte aus dem nichtflüchtigen Speicher (EEPROM) ab, wenn sie zuvor gespeichert wurden. Werden keine Werte gefunden, verwendet es die Standardwerte. Der Triggerwert stellt die Spannungsschwelle für das Ausschalten des Elektromagneten dar, der Hysteresewert definiert den Spannungsbereich, innerhalb dessen der Elektromagnet ausgeschaltet bleibt, auch wenn der Magnet etwas vom Sensor entfernt ist.
Das Programm zeigt dann eine kurze Beschreibung des Betriebs und die verfügbaren Befehle auf dem seriellen Monitor an. Die Befehle ermöglichen die Einstellung der Trigger- und Hysteresewerte durch Erhöhen oder Verringern. Die aktualisierten Werte werden sofort auf dem seriellen Monitor angezeigt. Um die Trigger- und Hysteresewerte im nichtflüchtigen Speicher zu speichern, kann der Benutzer den Befehl „S“ oder „s“ eingeben.
In der Hauptschleife liest das Programm den Analogwert des Hallsensors und vergleicht ihn mit dem Auslösewert plus dem Hysteresewert. Liegt der Sensorwert über diesem Schwellenwert, was bedeutet, dass sich der Magnet in der Nähe befindet, wird der Elektromagnet ausgeschaltet, indem Pin 23 auf Low gesetzt wird. Andernfalls, wenn der Magnet weit entfernt ist, wird der Elektromagnet eingeschaltet, indem Pin 23 auf High gesetzt wird.
Das Programm prüft ständig, ob Befehle vom seriellen Monitor eingehen. Wird ein Befehl empfangen, passt es den Trigger- oder Hysteresewert entsprechend an. Wenn der Befehl „S“ oder „s“ eingegeben wird, werden die Trigger- und Hysteresewerte im nichtflüchtigen Speicher gespeichert.
Die aktuellen Trigger- und Hysteresewerte werden bei jeder Änderung oder beim Programmstart an den seriellen Monitor ausgegeben.
Dieses Programm bietet eine einfache und kompakte Lösung für die Steuerung einer Magnetschwebeanlage mit einem ESP32-Mikrocontroller.
Verbesserungen
So weit, so gut, aber alles kann immer noch optimiert werden. Ich habe den Bot gebeten, mir drei kurze Vorschläge zur Verbesserung des Regelkreises zu machen. ChatGPT gab mir folgende Vorschläge zurück:
1. PID-Regelung implementieren: Erwägen Sie die Implementierung eines PID-Regelkreises (Proportional-Integral-Differential), um die Stabilität und Reaktionsfähigkeit des Magnetschwebesystems zu verbessern. Durch die Verwendung von Rückmeldungen des Hallsensors und die Anwendung geeigneter Regelverstärkungen kann der PID-Regler die Leistung des Elektromagneten dynamisch anpassen, um die gewünschte Schwebedistanz aufrechtzuerhalten. Dies verbessert die Fähigkeit des Systems, mit Störungen umzugehen, und sorgt für eine gleichmäßigere Steuerung.
2. Verwenden Sie ein gleitendes Durchschnittsfilter: Um Rauschen und Schwankungen in den Messwerten des Hallsensors zu reduzieren, sollten Sie ein Filter für den gleitenden Mittelwert anwenden. Anstatt sich nur auf einzelne Messwerte zu verlassen, berechnen Sie den Durchschnittswert über ein kleines Fenster der letzten Messwerte. Auf diese Weise erhalten Sie eine stabilere und zuverlässigere Messung, um die Position des Magneten zu bestimmen und die Leistung des Elektromagneten entsprechend anzupassen.
3. Integrieren Sie eine Sicherheitszeitüberschreitung: Fügen Sie einen Sicherheits-Timeout in den Regelkreis ein, um zu verhindern, dass der Elektromagnet ständig mit Strom versorgt wird, wenn der Magnet oder der Sensor abwesend ist oder ausfällt. Wenn das System innerhalb eines bestimmten Zeitraums keinen gültigen Wert des Hallsensors empfängt, kann es davon ausgehen, dass etwas nicht stimmt, und entsprechende Maßnahmen ergreifen, zum Beispiel den Elektromagneten abschalten oder einen Fehlerzustand auslösen.
Wenn Sie diese Vorschläge umsetzen, können Sie die Leistung des Regelkreises, die Störfestigkeit und die Sicherheitsfunktionen verbessern, was zu einer präziseren und zuverlässigeren Steuerung der Magnetschwebetechnik führt.
Ich gebe zu, dass meine anfänglichen Fragen nach einigen längeren Dialogen entstanden sind, in denen ich auch lernen musste, wie ich meine Fragen in einer für die ChatGPT-KI verständliche Weise formulieren kann.
Im Übrigen: Die Antworten von ChatGPT wurden oft einfach abrupt abgebrochen. Eine konkrete Anfrage nach einer möglichen Begrenzung der Länge der Antwort führte zu einem sehr wortreichen und hier sehr verkürzten „Ja, 2048 Zeichen“. Deshalb habe ich auch Hinweise für eine geeignete Verkürzung der Antwort aufgenommen.
Wenn man sich aber ein wenig mit den Reaktionen des Systems vertraut gemacht hat, sind die Ergebnisse auch nach einem einzigen etwas komplexeren Block von Fragen, Anforderungen und Anweisungen sehr gut. Gezielte Abfragen fügen weitere, auch umfangreichere Funktionen hinzu.
Wenn das Ergebnis technisch falsch erscheint, ist es interessant zu sehen, dass dieselbe Frage, die mehrmals wiederholt wurde, jedes Mal anders beantwortet wird, was sich in einem manchmal völlig anders strukturierten, aber meist funktionalen Code manifestiert. Es ist dann äußerst hilfreich, vielleicht sogar notwendig, den generierten Code zumindest gut lesen zu können und zu überprüfen, ob alle Anforderungen eingehalten werden. ChatGPT lässt schnell den einen oder anderen Aspekt außer Acht!
Vorschläge der KI, die dem eigenen Fachwissen widersprechen, können gezielt in Frage gestellt werden. Dies führt oft zu entschuldigenden Formulierungen und verbesserten Vorschlägen. Manchmal aber vermittelt ChatGPT Ihnen neues technisches Wissen!
Alles in allem hat sich die Verwendung von ChatGPT zur Erstellung von Software auf der Grundlage einer Problembeschreibung in natürlicher Sprache als sehr nützlich erwiesen. Vielleicht nicht als Hammer, wie oben behauptet, sondern eher als ein fein abstimmbares und kontrollierbares Werkzeug.
Selbst ein weniger erfahrener C++-Programmierer wie ich kann jetzt schnell komplexere Programme (-teiele) erstellen, für die ich früher zumindest deutlich länger gebraucht hätte. Die Dokumentation ist jetzt sehr einfach. Und man kann sogar eine Art tieferes Verständnis für die gestellte Aufgabe erwarten, was den Horizont für unerwartete, technisch fundierte und detaillierte Randbereiche öffnet.
Dennoch: Derzeit ist KI, insbesondere ChatGPT, ein hilfreiches, aber keineswegs unfehlbares Werkzeug für den Gelegenheitsprogrammierer, und es braucht immer noch einen menschlichen Operator! Ich bin sehr gespannt auf weitere Projekte mit diesem neuen Toolset in meinem Werkzeugkasten.
Einige Probleme beheben
Nun, als ob meine Schlussfolgerungen noch eines weiteren Beweises bedürften: Beim Testen des generierten Codes habe ich festgestellt, dass es zwei Probleme im Code gibt. OK ... fragen wir die Maschine danach:
Korrigiere zwei Probleme:
1. Der Wert des Hall-Sensors wird immer mit einem festen Wert ohne Hysterese verglichen.
2. Dieser Code speichert die Werte nicht korrekt im NV-RAM meines ESP32. Verwende eine andere Methode zum Speichern und Lesen.
Schreibe den obigen Code sehr kompakt und mit deutlich weniger Kommentaren, damit er vollständig in der Antwort ausgegeben werden kann.
ChatGPT antwortete höflich „Entschuldigung für das Versehen“ (!) und gab mir den Code in Listing 3 zurück.
Nun, das hat jetzt sehr gut funktioniert. Beim Testen entdeckte mein menschliches Gehirn allerdings noch ein weiteres, eher kleines Problem! Aber jetzt, in diesem verbesserten Zustand, bin ich zu dem Schluss gekommen, dass dies auch ein unvollendetes Softwareprojekt bleiben sollte. Also beendete ich den Chat und ging mit meiner Frau einen Kaffee trinken.
Dieser Artikel (230360-02) erscheint in der Ausgabe Januar/Februar 2024 von Elektor Mag.
Haben Sie Fragen oder Kommentare?
Haben Sie technische Fragen oder Kommentare zu diesem Artikel? Dann wenden Sie sich bitte per E-Mail an den Autor unter peter.neufeld@gmx.de oder an die Elektor Redaktion unter redaktion@elektor.de.
Diskussion (2 Kommentare)