Nachdem ich euch in Teil 2 meiner ESP-Claw-Serie gezeigt habe, wie ich ESP-Claw zum ersten Mal kompiliert habe, kommen wir heute zum vermutlich kniffligsten Teil des ganzen Projekts: Wie bringe ich ESP-Claw dazu, mein Guition JC1060P470 als unterstütztes Board zu erkennen?

Wer Teil 2 gelesen hat, weiß: Mein erfolgreicher Build war für den ESP32-P4 Function EV Board konfiguriert. Espressifs eigenes Referenzboard. Würde ich diese Firmware ungeprüft auf mein Guition flashen, wären Display, Touch, Audio und WiFi nicht ansprechbar weil die Pin-Belegung komplett anders ist. Es musste also eine eigene Board-Adaption her.

Diese Geschichte hat einen klassischen Wendepunkt. Erst längere Ratlosigkeit da ich so eine Adaption schon länger nicht gemacht hatte, dann die nahe liegende Idee ein unscheinbarer Suchbegriff in der GitHub eigenen Suche und plötzlich war der Weg frei.

ESP-CLAW board adaption

ESP-CLAW board adaption

Was ist überhaupt eine Board-Adaption in ESP-Claw?

ESP-Claw bringt von Haus aus ein paar Referenzboards mit, die direkt funktionieren:

  • ESP32-P4 Function EV Board (Espressifs eigenes Entwicklungsboard)
  • M5Stack Tab5 (ein 5-Zoll HMI-Board mit ESP32-P4)
  • Waveshare ESP32-P4 Nano
  • Diverse weitere von Espressif und Drittanbietern

Mein Guition JC1060P470 ist nicht dabei aber dafür war es eben auch billig bei AliExpress zu haben. Damit ESP-Claw weiß, wie es mit der Hardware umgehen soll und welche Pins für I²C, welche für SDIO zum WiFi-Co-Prozessor, welcher LCD-Controller verbaut ist, wie das Audio-Codec angesprochen wird usw. braucht es eine maßgeschneiderte Konfiguration. Diese Konfiguration nennt ESP-Claw eine Board-Adaption, und sie besteht aus mehreren Dateien und gab es eben nicht direkt vom Hersteller in dessen angebotenen Download Daten zum Board:

Datei Was sie definiert Format
board_info.yaml Metadaten zum Board (Name, Hersteller, Chip) YAML
board_peripherals.yaml Hardware-Peripherie (I²C, I²S, GPIO, LDO, DSI, LEDC) YAML
board_devices.yaml Logische Geräte (Audio-Codec, Display, Touch, SD-Karte) YAML
setup_device.c Treiberspezifischer C-Code (z. B. JD9165 Init-Sequenz) C
sdkconfig.defaults.board Voreinstellungen für ESP-IDF (Flash-Größe, PSRAM, ESP-Hosted) Kconfig
README.md Dokumentation für andere Maker Markdown

Klingt überschaubar. Aber die Crux ist: Ich musste für jede dieser Dateien wissen, was genau auf meinem Board verbaut ist und mit welchen Pins es kommuniziert. Und das war bei einem AliExpress-Board mit chinesischer Dokumentation der erste echte Stolperstein.

Die Sackgasse: Datenblatt-Recherche

Mein erster Reflex war es, im AliExpress-Listing nach einem Datenblatt zu suchen. Vergebliche Mühe. Der Verkäufer hatte nur ein paar Marketing-Bilder online. Auf der Hersteller-Website von Guition fand ich zwar ein PDF, aber das war auf Englisch und Chinesisch und zeigte hauptsächlich Anschluss-Pinouts, nicht die internen Pin-Belegungen des ESP32-P4 zu Display, Touch oder Audio.

Hier noch ein Link zum Hersteller der dennoch recht hilfreich war: https://devices.esphome.io/devices/guition-esp32-p4-m3-dev/

In dieser ZIP Datei gibt es dann Schaltpläne (auf Chinesisch), Demo-Code (Arduino-basiert, nicht direkt nutzbar) und ein paar PNG-Screenshots. Hilfreich, aber nicht ausreichend, um daraus eine ESP-Claw-Adaption zu bauen.

Hier noch der Link auf die gesagte ZIP-Datei (auf eigene Gefahr): https://pan.jczn1688.com/directlink/1/HMI%20display/JC-ESP32P4-M3-DEV.zip

Auch ESP-Claws eigene Dokumentation half nur bedingt: Sie beschreibt zwar das YAML-Schema, aber ohne ein vollständiges Beispiel für einen exotischen Display-Controller wie den JD9165 ist man auf sich gestellt.

Etwas länger als mir recht war habe ich mich durch ESP-Claws Referenzboards gelesen:

  • boards/espressif/esp32_p4_function_ev/ für das P4-MIPI-DSI-Setup mit EK79007
  • boards/m5stack/m5stack_tab5/ für ein P4 mit anderem Display-Controller (ILI9881C)

Aus beiden konnte ich Struktur und Schema lernen, aber nicht die konkrete JD9165-Init-Sequenz oder die exakten Pin-Belegungen meines Guition-Boards.

Der Durchbruch: Eine GitHub-Suche nach „JC1060P470“

Frustriert habe ich schließlich versucht, was eigentlich immer der erste Schritt sein sollte: Eine globale GitHub-Suche nach dem genauen Boardnamen.

Link: https://github.com/search?q=JC1060P470&type=code

Und tatsächlich. Die Suche brachte mir ein eher unscheinbares Repository zu Tage:

Auf dieses Repository habe ich aufgesetzt: https://github.com/Deep-start9527/guition_product_demo

Ein Maker hatte hier ein komplettes Demo-Projekt für das JC1060P470 in ESP-IDF veröffentlicht mit voll funktionsfähigem Code für Display, Touch, Audio und mehr. Genau die Information, die mir bei Guition gefehlt hat. Das war mein Hoffnungs-Moment.

Hier noch ein weiteres Repository das der Hersteller auf seiner Produktseite verlinkt hat: https://github.com/p1ngb4ck/unofficial_guition_esp32p4_repo/tree/main/JC-ESP32P4-M3-Dev

Aus diesem Repository wurden zwei Dateien zu meinen wichtigsten Verbündeten:

  • pingcfg.h – die komplette Pin-Map des Boards, sauber als Header-Konstanten dokumentiert
  • demo/main/lcd/lcd.c – die JD9165-Init-Sequenz, rund 50 Register-Schreibvorgänge mit Kommentaren

Die Pin-Map aus pingcfg.h

Aus der pingcfg.h konnte ich die komplette Pin-Belegung extrahieren. Hier eine gekürzte Übersicht der wichtigsten Anschlüsse:

Funktion Pin(s) Verwendung
I²C (Touch + Audio Codec) SDA=7, SCL=8 GT911, ES8311
I²S (Audio) MCLK=13, BCLK=12, WS=10, DOUT=9, DIN=48 ES8311 Mikro/Lautsprecher
Audio-Verstärker PA_EN=11 Speaker-Endstufe ein/aus
LCD Backlight BL=23 (LEDC, 20 kHz) Helligkeitssteuerung
LCD Reset RST=0 Hardware-Reset des Panels
microSD (4-bit Modus) CLK=43, CMD=44, D0–D3=39/40/41/42 SDMMC
ESP32-C6 SDIO CLK=18, CMD=19, D0–D3=14/15/16/17, RST=54 ESP-Hosted für WiFi/BT
UART0 (Konsole) TX=37, RX=38 Serielle Ausgabe via CH340

Mit diesem Projekt wurde aus den 6 leeren Konfigurationsdateien plötzlich eine machbare Aufgabe. Ich wusste jetzt, was wo angeschlossen war und das ist die halbe Miete.

Phase 1: Verzeichnisstruktur anlegen

ESP-Claw erwartet die Board-Adaptionen im Pfad application/edge_agent/boards/<Hersteller>/<Boardname>/. Bei mir also:

Befehl: mkdir -p D:\esp32-claw\esp-claw\application\edge_agent\boards\guition\jc1060p470_m3_dev

Den Suffix _m3_dev habe ich gewählt, weil das Board offiziell JC-ESP32P4-M3-DEV heißt. So bleibt der Verzeichnisname konsistent mit der Herstellerbezeichnung.

Phase 2: board_info.yaml – die Visitenkarte des Boards

Die einfachste Datei. Sie enthält nur Metadaten, die ESP-Claw verwendet, um das Board in seiner Auswahl zu listen:

  • Board-Name (intern und für die Anzeige)
  • Hersteller (Guition)
  • Chip-Familie (esp32p4)
  • Hardware-Revision

Diese Datei nimmt vielleicht 20 Zeilen ein und ist in fünf Minuten erledigt dank den LLMs dieser Welt.

Phase 3: board_peripherals.yaml – die Hardware-Schicht

Hier wird es spannend. In dieser Datei definiere ich alle Hardware-Peripherie-Blöcke des ESP32-P4, die ESP-Claw später verwenden soll. Bei meinem Board waren das 7 Peripherie-Definitionen:

  1. i2c_master – der I²C-Bus für Touch und Audio-Codec
  2. i2s_audio_out – I²S-Kanal für DAC (Lautsprecher)
  3. i2s_audio_in – I²S-Kanal für ADC (Mikrofon)
  4. gpio_pa_control – Steuer-GPIO für den Audio-Verstärker
  5. ldo_mipi – die interne Spannungsversorgung für MIPI-DSI
  6. dsi_display – der DSI-Bus für das Display
  7. ledc_backlight – LEDC-PWM-Kanal für die Hintergrundbeleuchtung

Mit den ersten Versionen meiner YAML-Datei lief der Build sofort auf Schema-Fehler. ESP-Claw ist beim Parsing sehr streng, und ich musste in mehreren Iterationen herausfinden, welche Feldnamen tatsächlich erwartet werden. Hier die wichtigsten Korrekturen, die ich aus meinen ersten Fehlversuchen gelernt habe:

Meine erste Annahme (falsch) Was ESP-Claw wirklich erwartet
type: mipi_dsi type: dsi
num_data_lanes: 2 data_lanes: 2
type: touch type: lcd_touch
I²S als ein Peripherie-Block Getrennt in i2s_audio_out + i2s_audio_in

Mein Tipp: Schaut euch das YAML eines bestehenden ähnlichen Boards aus dem ESP-Claw Projekt an (z. B. esp32_p4_function_ev) und kopiert die Struktur, bevor ihr eigene Feldnamen erfindet. Das spart enorm viel Zeit.

Phase 4: board_devices.yaml – die logische Schicht

Während die board_peripherals.yaml die rohe Hardware beschreibt, definiert board_devices.yaml die logischen Geräte, die auf dieser Hardware laufen. Also: Welcher Display-Treiber? Welcher Audio-Codec? Welcher Touch-Controller?

Bei meinem Board waren das ursprünglich 6 Geräte:

  1. audio_dac – ES8311 als DAC für die Audioausgabe
  2. audio_adc – ES8311 als ADC für den Mikrofoneingang
  3. fs_sdcard – FAT-Dateisystem auf der microSD-Karte
  4. lcd_brightness – Helligkeitssteuerung via LEDC
  5. display_lcd –-das eigentliche Display mit JD9165-Controller
  6. lcd_touch – GT911-Touch-Controller

Eine wichtige Erkenntnis: WiFi und Ethernet sind hier NICHT enthalten. ESP-Claw konfiguriert das Netzwerk komplett über die Kconfig-Voreinstellungen in sdkconfig.defaults.board, nicht über YAML. Das hat mich anfangs verwirrt, weil ich nach einem „wifi“-Eintrag gesucht hatte.

Phase 5: setup_device.c – die JD9165-Init-Sequenz

Hier kam der spannendste Teil. Display-Controller wie der JD9165 benötigen eine spezifische Initialisierungs-Sequenz aus rund 50 Register-Schreibvorgängen. Diese Sequenz steht in keinem Datenblatt, sondern nur in der Vendor-Demo des Boards. Ohne sie zeigt das Display nur Pixel-Müll oder bleibt schwarz.

Genau hier hat mir die lcd.c aus dem chinesischen Demo-Projekt das Leben gerettet. Ich konnte das gesamte Init-Array 1:1 in mein setup_device.c übernehmen:

  • Page-Select-Befehle (zur Auswahl interner Register-Bänke)
  • Power-Sequencing
  • Gamma-Korrektur
  • Timing-Parameter für die DSI-Schnittstelle
  • Display-On-Befehl mit 120 ms Wartezeit

Diese Sequenz selbst zu rekonstruieren hätte mich vermutlich Tage gekostet und wäre ohne Logic Analyzer oder MIPI-Sniffer praktisch unmöglich gewesen.

Mein Lerneffekt: Bei exotischen Display-Controllern immer nach einer existierenden Vendor-Demo suchen, bevor man versucht, die Init-Sequenz aus dem Datenblatt zu interpretieren. Datenblätter beschreiben Register, aber nicht die richtige Reihenfolge oder Timings.

Hinweis: Ich habe dann wieder alles ausdokumentiert zu dem Display da nach dem flashen der Microkontroller in einer Dauerschleife hing da er kein Display gefunden hat. Ich habe ja noch keines.

Phase 6: sdkconfig.defaults.board – die ESP-IDF-Voreinstellungen

In dieser Datei stelle ich die ESP-IDF-spezifischen Defaults für mein Board ein. Hier sind die wichtigsten Einträge:

  • CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y (16 MB Flash)
  • CONFIG_SPIRAM_MODE_HEX=y (Octal PSRAM)
  • CONFIG_SPIRAM_SPEED_200M=y (PSRAM bei 200 MHz)
  • CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_16MB.csv"
  • CONFIG_ESP_HOSTED_HOST_INTERFACE_SDIO=y (WiFi via C6 per SDIO)
  • CONFIG_ESP_CONSOLE_UART_DEFAULT=y (Konsole via UART0)

Genau diese Datei aktiviert die ESP-Hosted-Brücke zum ESP32-C6, die ich später für das WiFi brauche. Ohne diese Einstellung kann der P4 nicht mit seinem Funk-Co-Prozessor kommunizieren.

Phase 7: Den ESP Board Manager generieren lassen

ESP-Claw kommt mit einem hilfreichen Tool namens ESP Board Manager, das aus meinen YAML-Dateien automatisch C-Code generiert. Den rufe ich nach jeder Änderung an den YAMLs einmal auf:

Befehl: idf.py gen-bmgr-config -c ./boards -b jc1060p470_m3_dev

Wenn alles passt, sehe ich am Ende eine Ausgabe wie diese:

Successfully validated 7 peripherals
Successfully validated 6 devices

Wenn die Zahlen mit dem übereinstimmen, was ich in YAML definiert habe, ist die Adaption syntaktisch korrekt. Falls etwas falsch ist, bekommt man hier in der Regel eine sehr klare Fehlermeldung – mit Zeilennummer und konkretem Hinweis. Die Fehlermeldungen sind verständlich wenn man sich vorher mit der Konfiguration herum geschlagen hat…

Phase 8: Build und erste Tests

Nach all der Vorarbeit kam der entscheidende Moment:

Befehl: idf.py build

Beim ersten Versuch kam es wie zu erwarten zu Fehlern wie fehlende Felder, falsche Datentypen, vergessene dependencies:-Blöcke. Aber nach jeder Korrektur kam ich ein Stück weiter, bis schließlich ein sauberer Build durchlief:

edge_agent.bin binary size 0x28e3a0 bytes. Smallest app partition is 0x400000 bytes. 0x171c60 bytes (36%) free.

Etwa 2,6 MB Firmware für mein speziell angepasstes Board. Bereit zum Flashen.

Mein persönliches Fazit zu Teil 3

Eine Board-Adaption für ein nicht offiziell unterstütztes Board zu schreiben ist kein Selbstläufer. Ich hatte mehrfach Momente, in denen ich kurz davor war, das Projekt auf einen ESP32-P4 Function EV Board zu verschieben um mich nicht weiter mit dem Guition herumzuschlagen.

Was mir letztlich geholfen hat, war:

  1. Die GitHub-Suche nach dem exakten Boardnamen. Hat aus stundenlangem Rätselraten konkrete Pin-Maps und Init-Sequenzen gemacht.
  2. Die ESP-Claw-Referenzboards als Vorbild. Auch wenn keines exakt zu meinem passte, war die Struktur sehr lehrreich.
  3. Geduld beim iterativen YAML-Schema-Lernen. Jeder Schema-Fehler war ein Schritt zum Verstehen.
  4. Die JD9165-Init-Sequenz nicht selbst zu rekonstruieren. Wenn jemand vor euch Stunden in einem Logic Analyzer verbracht hat, nutzt das Ergebnis dankend.

Diese drei Teile meiner Serie (Installation, Build, Board-Adaption) sind die „langweiligen aber“ notwendigen Grundlagen. Sie waren die meiste Arbeit, aber sie sind auch die Basis für alles Spannende, was jetzt folgt. Ab Teil 4 wird es deutlich kurzweiliger denn dann kommt der KI-Teil ins Spiel.

Im nächsten Teil zeige ich euch, wie ich meinen ESP-Claw-Agenten mit meinem eigenen Ollama-Inferenz-Server verbinde. Wie ich die richtigen Konfigurationsfelder im Web-UI setze und welche Stolpersteine mich dabei erwartet haben. Spoiler: Es gab welche.

Wir lesen uns im nächsten Teil!

Was kommt in den nächsten Beiträgen?

  • Teil 1: Auftakt und Vorstellung der Vision
  • Teil 2: ESP-IDF v5.5.4 einrichten und ESP-Claw bauen – Schritt für Schritt
  • Teil 3 (dieser Beitrag): Ein neues Board zu ESP-Claw hinzufügen – meine Board-Adaption für das Guition JC1060P470
  • Teil 4: ESP-Claw mit dem eigenen Ollama-Server verbinden – Konfiguration und erste Chats
  • Teil 5: Capabilities und Skills verstehen – die Architektur eines ESP-Claw-Agenten
  • Teil 6: Eine eigene Skill schreiben – das Roboter-Auto fernsteuern oder den Geschirrspühler erklären
  • Teil 7: Sprache rein, Sprache raus – das HMI-Board als echter Voice-Assistant zur Unterstützung an der Waschmaschine
  • Teil 8: Lua-Skripte für Verhaltensmuster – wenn der Agent eigenständig handelt