Skip to content

Technik Blog

Programmieren | Arduino | ESP32 | MicroPython | Python | Raspberry Pi | Raspberry Pi Pico

Menu
  • Smarthome
  • Gartenautomation
  • Arduino
  • ESP32 & Co.
  • Raspberry Pi & Pico
  • Solo Mining
  • Deutsch
  • English
Menu

ChatGPT & ESP32

Posted on 29. April 202323. Mai 2025 by Stefan Draeger

In diesem Beitrag zeige ich dir, wie du auf deinem ESP32 eine Schnittstelle zur künstlichen Intelligenz ChatGPT herstellst und mit dieser kommunizierst.

Für diesen Beitrag verwende ich den ESP32-C3 von der Firma Seeed Studio, dieser kleine Mikrocontroller verfügt über eine WiFi-Schnittstelle und ein paar GPIO Pins (welche aber für diesen Beitrag nicht benötigt werden).

ESP32-C3 von Seeed Studio
ESP32-C3 von Seeed Studio
ESP32-C3 von Seeed Studio (Rückseite)
ESP32-C3 von Seeed Studio (Rückseite)

Den ESP32-C3 habe ich dir bereits im Beitrag Mikrocontroller ESP32C3 von Seeed Studio vorgestellt und gezeigt, wie dieser in der Arduino IDE 2.0 programmiert wird. An diesen Beitrag möchte ich nun anknüpfen. Ich gehe daher davon aus, dass der Mikrocontroller bereits auf deinem Computer eingerichtet und in der Arduino IDE 2.0 lauffähig ist.

Im letzten Beitrag Absenden eines Requests an ChatGPT per Postman hatte ich dir bereits erläutert, wie du mithilfe von der kostenfreien Anwendung Postman eine Anfrage absendest. Dort wird die Anfrage per JSON-Request gesendet und dieses möchte ich hier ebenso nutzen um die Anfrage vom ESP32 an ChatGPT zu senden.

  • Aufbau einer WiFi Verbindung zum lokalen Netzwerk
  • Erstellen einer HTML-Seite mit Eingabe-/Ausgabefeld
    • Platzhalter für Anfrage, Antwort und ggf. Fehlermeldungen
  • Aufbau eines JSON-Request an ChatGPT
  • Auswerten des HTTP Codes
  • Auswerten der Antwort von ChatGPT
  • Kompletter Code zum Download als ZIP-Datei

Aufbau einer WiFi Verbindung zum lokalen Netzwerk

Damit wir mit ChatGPT kommunizieren können, benötigen wir zunächst eine WiFi Verbindung zum lokalen Netzwerk oder zu einem Hotspot.

//Einbinden der Bibliotheken
//für die WiFi Verbindung des ESP32
#include <WiFi.h>
#include <WebServer.h>

//SSID & Passwort für das lokale WiFi
#define WIFI_SSID ""
#define WIFI_PASSWORD ""

//Initialisieren eines Webservers mit dem Port 80 (default http)
WebServer server(80);

void setup() {
  //begin der seriellen Kommunikation mit 115200 baud
  Serial.begin(115200);
  //Aufbau einer WiFi Verbindung mit den Daten
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  //maximal 10 Versuche zum aufbau der WiFi Verbindung
  int maxConnectionAttempts = 10;
  int counter = 0;
  //sollange die Verbindung nicht aufgebaut ist UND 
  //der Zähler der Verbindungsversuche kleiner als den Wert der Variable
  //maxConnectionAttempts ist, dann...
  while (WiFi.status() != WL_CONNECTED && counter < maxConnectionAttempts) {
    //schreiben eines Punktes auf der seriellen Schnittstelle
    Serial.print(".");
    //den Zähler um eins erhöhen
    counter++;
    //eine kleine Pause von 250 Millisekunden
    delay(250);
  }

  //Wenn die Verbindungsversuche "verbraucht" sind oder eine
  //Verbindung zum WiFi Netzwerk aufgebaut wurde, dann soll
  //dieses ausgegeben werden.
  Serial.println("");
  Serial.print("Zum WiFi Netzwerk ");
  Serial.print(WIFI_SSID);
  Serial.println(WiFi.isConnected() ? " verbunden" : " nicht verbunden");
  
  //Wenn die Verbindung erfolgreich aufgebaut wurde,
  //dann soll die IP-Adresse auf der seriellen Schnittstelle
  //ausgegeben werden.
  if (WiFi.isConnected()) {
    Serial.print("IP-Adresse: ");
    Serial.println(WiFi.localIP());
    Serial.println();

    server.begin();
    server.on("/", callWebsite);
  } else {
    //Wenn die Verbindung nicht aufgebaut wurde, dann soll
    //eine entsprechende Meldung ausgegeben werden.
    Serial.print("Fehler beim Aufbau der Verbindung zu ");
    Serial.println(WIFI_SSID);
    Serial.println();
  }
}

//Callback Funktion welche aufgerufen wird wenn der Benutzer
//im Browser die IP-Adresse eingibt.
void callWebsite() {
  //eine kleine einfache Webseite mit dem Text "Hallo Welt!"
  String htmlpage = "<html><body><h1>Hallo Welt!</h1></body></html>";
  //Absenden der Seite 
  //mit HTTP-Code 200 "OK", 
  //als MimeType "text/html"
  server.send(200, "text/html", htmlpage);
}

/**
* Funktion wird fortlaufen ausgeführt.
**/
void loop() {
  server.handleClient();
}

Wenn der Code erfolgreich hochgeladen wurde, muss die Taste Reboot „R“ auf dem Mikrocontroller betätigt werden.

Es sollte dann die nachfolgende Ausgabe im seriellen Monitor erscheinen und wir können nun bei erfolgreicher Verbindung die IP-Adresse ablesen.

ESP-ROM:esp32c3-api1-20210207
Build:Feb  7 2021
rst:0x15 (USB_UART_CHIP_RESET),boot:0x8 (SPI_FAST_FLASH_BOOT)
Saved PC:0x4203675c
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fcd5810,len:0x438
load:0x403cc710,len:0x91c
load:0x403ce710,len:0x25b0
entry 0x403cc710
.
Zum WiFi Netzwerk FRITZBox7590GI24 verbunden
IP-Adresse: 192.168.178.131

Wenn man nun die IP-Adresse 192.168.178.131 im Browser eingibt, erhält man den Text „Hallo Welt!“.

Nachfolgend das kleine Programm als ZIP-Datei zum download.

ESP32 mit WebseiteHerunterladen

Erstellen einer HTML-Seite mit Eingabe-/Ausgabefeld

Für das Absenden der Anfrage an ChatGPT benötigen wir ein Eingabefeld auf der Webseite und für die Antwort ein Ausgabefeld (in diesem Fall ein einfacher DIV-Container).

Die CSS & JavaScriptdateien für diese Seite lagere ich auf die Adresse http://progs.ressourcen-draeger-it.de/chatgptesp32 aus.

<html lang='de'>
   <head>
      <meta charset='utf-8'>
      <meta name='viewport' content='width=device-width, initial-scale=1.0'>
      <title>ChatGPT & ESP32</title>
      <script type='text/javascript' src='http://progs.ressourcen-draeger-it.de/chatgptesp32/js/jquery-3.6.3.min.js'> </script> <script type='text/javascript' src='http://progs.ressourcen-draeger-it.de/chatgptesp32/js/functions.js'></script> 
      <link rel='stylesheet' href='http://progs.ressourcen-draeger-it.de/chatgptesp32/css/styles.css'/>
   </head>
   <body>
      <div class='outer'>
         <h1>ChatGPT & ESP32</h1>
         <form id='chatgptmessages' name='chatgptmessages' action='/' method='get'>
            <center>
               <input type='text' placeholder='press return to submit' value='%inputFieldValue%' class='inputField' id='inputMsg' name='inputMsg'/></br></br>
               <div class='resultTxt'>%resultTxt%</div>
               <div class='errorMsg' %errorMsgStyle%>%errorMsg%</div>
            </center>
         </form>
      </div>
   </body>
</html>

Diese Seite wollen wir in einen String im Code speichern, daher muss diese noch komprimiert werden. Zum Komprimieren von HTML Seiten kann man zum Beispiel das Onlinetool https://www.textfixer.de/html/html-komprimieren.php nutzen. Dieses Tool entfernt unnötige Zeilenumbrüche und andere Formatierungen.

String page = "<html lang='de'> <head> <meta charset='utf-8'> <meta name='viewport' content='width=device-width, initial-scale=1.0'> <title>ChatGPT & ESP32</title> <script type='text/javascript' src='http://progs.ressourcen-draeger-it.de/chatgptesp32/js/jquery-3.6.3.min.js'> </script> <script type='text/javascript' src='http://progs.ressourcen-draeger-it.de/chatgptesp32/js/functions.js'></script> <link rel='stylesheet' href='http://progs.ressourcen-draeger-it.de/chatgptesp32/css/styles.css'/> </head> <body><div class='outer'><h1>ChatGPT & ESP32</h1><form id='chatgptmessages' name='chatgptmessages' action='/' method='get'><center><input type='text' placeholder='press return to submit' value='%inputFieldValue%' class='inputField' id='inputMsg' name='inputMsg'/></br></br><div class='resultTxt'>%resultTxt%</div><div class='errorMsg' %errorMsgStyle%>%errorMsg%</div></center></form></div> </body></html>";

Platzhalter für Anfrage, Antwort und ggf. Fehlermeldungen

In den HTML-Code betten wir noch 3 Platzhalter für die Kommunikation mit ChatGPT und den später gezeigten JSON-Parser ein. Des Weiteren noch einen Platzhalter zum Steuern, ob die Fehlermeldung angezeigt werden soll oder nicht.

  • %inputFieldValue%
  • %resultTxt%,
  • %errorMsgStyle%,
  • %errorMsg%

Diese Platzhalter werden später mit einer Funktion durch den Text ersetzt (String.replace)

Aufbau eines JSON-Request an ChatGPT

Nachdem wir nun eine Verbindung zu einem lokalen WiFi Netzwerk erfolgreich aufgebaut und eine kleine Webseite erstellt haben, können wir einen Request / eine Anfrage an ChatGPT stellen.

Dazu benötigen wir einen API Key welchen man unter https://platform.openai.com/account/api-keys anlegen können.

Für die JSON Verarbeitung nutze ich die Bibliothek ArduinoJson.h welche über den internen Bibliotheksverwalter installiert werden kann.

Dazu öffnen wir den Bibliotheksverwalter (1) und suchen nach ArduinoJson (2) danach klicken wir auf die Schaltfläche INSTALL (3). Es werden dann die Dateien geladen und installiert, wenn dieser Vorgang abgeschlossen ist, wird dieses mit dem Label INSTALLED (4) angezeigt.

installieren der Bibliothek ArduinoJson über den Bibliotheksverwalter
installieren der Bibliothek ArduinoJson über den Bibliotheksverwalter

Zunächst müssen wir unseren Request an die KI aufbauen. Wie erwähnt, senden wir ein JSON an das System ab.

//definieren das wir Daten vom Typ "application/json" senden
https.addHeader("Content-Type", "application/json");
//den API Key mit 
String token_key = "Bearer " + chatgptApiKey;
https.addHeader("Authorization", token_key);

StaticJsonDocument<200> data;
//das verwendete Model
data["model"] = "text-davinci-003";
//die Anfrage an das System
data["prompt"] = chatgptQuestion;
//die Komplexität
data["temperature"] = 0;
//die gewünschte länge der Antwort von ChatGPT
//Dieser Wert darf nicht zu groß gewählt werden,
//der ESP32 hat nur begrenzten Speicherplatz.
data["max_tokens"] = 300;
String requestBody;
//serialisieren des JSON in einen String
serializeJson(data, requestBody);
//absenden des Requests
https.POST(requestBody);

Auswerten des HTTP Codes

Die Methode „POST“ liefert als Rückgabewert einen ganzzahligen Integerwert als HTTP-Code. Wenn es funktioniert hat, d.h. der Service hat die Anfrage angenommen und verarbeitet, dann erhalten wir ein HTTP-200 Code.

Nachfolgend habe ich einen kleinen Auszug von den möglichen HTTP-Codes entnommen.

//absenden des Requests
    int httpCode = https.POST(requestBody);
    if (httpCode != 200) {
      errorMsg = "HTTP-Code: " + String(httpCode);

      switch (httpCode) {
        case 401: errorMsg += " Unauthorized"; break;
        case 403: errorMsg += " Forbidden"; break;
        case 404: errorMsg += " Not Found"; break;
        case 405: errorMsg += " Method Not Allowed"; break;
        case 408: errorMsg += " Timeout Error"; break;
        case 500: errorMsg += " Internal Server Error"; break;
        case 501: errorMsg += " Not Implemented"; break;
        case 502: errorMsg += " Bad Gateway"; break;
        case 504: errorMsg += " Gateway Timeout"; break;
        default: errorMsg += "";
      }
    }

Eine Fehlermeldung vom System wird auf der Seite in einem kleinen, roten Fenster angezeigt. In diesem Fall habe ich den API Key falsch eingegeben.

Auswerten der Antwort von ChatGPT

In jedem Fall (Fehler oder Erfolg) erhalten wir eine Antwort im JSON Format vom System.

Diese Antwort engl. Response müssen wir nun deserialisieren und in einen String ablegen.
Wenn der empfange, JSON-String zu groß für die Verarbeitung auf dem Mikrocontroller ist, erhalten wir eine Fehlermeldung.

String response = https.getString();
if (response.length() > 0) {
  StaticJsonDocument<1024> doc;
  DeserializationError error = deserializeJson(doc, response);
  if (error) {
     errorMsg = error.f_str();
     Serial.print("error: ");
     Serial.println(errorMsg);
     return;
  }
...
}

Wenn die Deserializierung erfolgreich war, dann prüfen wir, ob wir einen HTTP-Code größer als 200 erhalten haben (also einen Fehler). Dann lesen wir die Fehlermeldung aus dem JSON, andernfalls lesen wir die Antwort und schreiben diese in den jeweiligen Platzhalter auf die Webseite.

if (httpCode > 200) {
   errorMsg += "<br/>";
   String errorMessage = doc["error"]["message"];
   errorMsg += errorMessage;
   htmlpage.replace("%resultTxt%", "");
} else {
   String chatGPTAnswer = doc["choices"][0]["text"];
   Serial.print("answer: ");
   Serial.println(chatGPTAnswer);
   htmlpage.replace("%resultTxt%", chatGPTAnswer);
}

Zum Schluss befüllen wir noch das Feld mit der eventuellen Fehlermeldung und senden die modifizierte Webseite ab.

htmlpage.replace("%errorMsg%", errorMsg);
String errorMsgStyle = " style='display:none;' ";
if (errorMsg.length() > 0) {
  errorMsgStyle = " style='display:block;' ";
}

htmlpage.replace("%errorMsgStyle%", errorMsgStyle);

server.send(200, "text/html", htmlpage);

Kompletter Code zum Download als ZIP-Datei

Den kompletten Code als ZIP-Datei biete ich dir hier als Download an.

ChatGPT Client auf dem ESP32Herunterladen

Externe Ressourcen für die Webseite Stylesheets, & JavaScript.

ChatGPT & ESP32 – Ressourcen für WebseiteHerunterladen

Schreibe einen Kommentar Antworten abbrechen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Fragen oder Feedback?

Du hast eine Idee, brauchst Hilfe oder möchtest Feedback loswerden?
Support-Ticket erstellen

Newsletter abonnieren

Bleib auf dem Laufenden: Erhalte regelmäßig Updates zu neuen Projekten, Tutorials und Tipps rund um Arduino, ESP32 und mehr – direkt in dein Postfach.

Jetzt Newsletter abonnieren

Unterstütze meinen Blog

Wenn dir meine Inhalte gefallen, freue ich mich über deine Unterstützung auf Tipeee.
So hilfst du mit, den Blog am Leben zu halten und neue Beiträge zu ermöglichen.

draeger-it.blog auf Tipeee unterstützen

Vielen Dank für deinen Support!
– Stefan Draeger

Kategorien

Tools

  • Unix-Zeitstempel-Rechner
  • ASCII Tabelle
  • Spannung, Strom, Widerstand und Leistung berechnen
  • Widerstandsrechner
  • 8×8 LED Matrix Tool
  • 8×16 LED Matrix Modul von Keyestudio
  • 16×16 LED Matrix – Generator

Links

Blogverzeichnis Bloggerei.de TopBlogs.de das Original - Blogverzeichnis | Blog Top Liste Blogverzeichnis trusted-blogs.com

Stefan Draeger
Königsberger Str. 13
38364 Schöningen
Tel.: 01778501273
E-Mail: info@draeger-it.blog

Folge mir auf

link zu Fabook
link zu LinkedIn
link zu YouTube
link zu TikTok
link zu Pinterest
link zu Instagram
  • Impressum
  • Datenschutzerklärung
  • Disclaimer
  • Cookie-Richtlinie (EU)
©2025 Technik Blog | Built using WordPress and Responsive Blogily theme by Superb
Cookie-Zustimmung verwalten
Wir verwenden Technologien wie Cookies, um Geräteinformationen zu speichern und/oder darauf zuzugreifen. Wir tun dies, um das Surferlebnis zu verbessern und um personalisierte Werbung anzuzeigen. Wenn Sie diesen Technologien zustimmen, können wir Daten wie das Surfverhalten oder eindeutige IDs auf dieser Website verarbeiten. Wenn Sie Ihre Zustimmung nicht erteilen oder zurückziehen, können bestimmte Funktionen beeinträchtigt werden.
Funktional Immer aktiv
Die technische Speicherung oder der Zugang ist unbedingt erforderlich für den rechtmäßigen Zweck, die Nutzung eines bestimmten Dienstes zu ermöglichen, der vom Teilnehmer oder Nutzer ausdrücklich gewünscht wird, oder für den alleinigen Zweck, die Übertragung einer Nachricht über ein elektronisches Kommunikationsnetz durchzuführen.
Vorlieben
Die technische Speicherung oder der Zugriff ist für den rechtmäßigen Zweck der Speicherung von Präferenzen erforderlich, die nicht vom Abonnenten oder Benutzer angefordert wurden.
Statistiken
Die technische Speicherung oder der Zugriff, der ausschließlich zu statistischen Zwecken erfolgt. Die technische Speicherung oder der Zugriff, der ausschließlich zu anonymen statistischen Zwecken verwendet wird. Ohne eine Vorladung, die freiwillige Zustimmung deines Internetdienstanbieters oder zusätzliche Aufzeichnungen von Dritten können die zu diesem Zweck gespeicherten oder abgerufenen Informationen allein in der Regel nicht dazu verwendet werden, dich zu identifizieren.
Marketing
Die technische Speicherung oder der Zugriff ist erforderlich, um Nutzerprofile zu erstellen, um Werbung zu versenden oder um den Nutzer auf einer Website oder über mehrere Websites hinweg zu ähnlichen Marketingzwecken zu verfolgen.
Optionen verwalten Dienste verwalten Verwalten von {vendor_count}-Lieferanten Lese mehr über diese Zwecke
Einstellungen anzeigen
{title} {title} {title}