ESP32 - Farbsensor via Web

In diesem unterhaltsamen Projekt verbinden Sie einen TCS3200D/TCS230 Farbsensor mit einem ESP32 und streamen die erkannten Farben in Echtzeit an einen Webbrowser. Die Webseite zeigt einen verspielten animierten Minion-Charakter, dessen Hautfarbe live basierend auf dem, was der Sensor erkennt, aktualisiert wird. Um die Erstellung der Web-Oberfläche und die Verwaltung der WebSocket-Kommunikation zu vereinfachen, verwendet dieses Projekt die DIYables ESP32 WebApps Bibliothek.

ESP32 TCS3200 TCS230 Farbsensor Web Minion

Hier ist eine Zusammenfassung dessen, was passiert:

Eine Schritt-für-Schritt Video-Anleitung ist auch am Ende dieses Tutorials verfügbar.

Hardware Erforderlich

1×ESP32 ESP-WROOM-32 Entwicklungsmodul
1×(Alternativ) ESP32 Uno-form board
1×(Alternativ) ESP32 S3 Uno-form board
1×USB Kabel Type-C
1×TCS3200D/TCS230 Farberkennungs-Sensormodul
1×Jumper Kabel
1×(Empfohlen) Schraubklemmen-Erweiterungsboard für ESP32
1×(Empfohlen) Breakout Expansion Board for ESP32
1×(Empfohlen) Stromverteiler für ESP32

Oder Sie können die folgenden Kits kaufen:

1×DIYables ESP32 Starter-Kit (ESP32 enthalten)
1×DIYables Sensor-Kit (30 Sensoren/Displays)
1×DIYables Sensor-Kit (18 Sensoren/Displays)
Offenlegung: Einige der in diesem Abschnitt bereitgestellten Links sind Amazon-Affiliate-Links. Wir können eine Provision für Käufe erhalten, die über diese Links getätigt werden, ohne zusätzliche Kosten für Sie. Wir schätzen Ihre Unterstützung.

Voraussetzungen

Falls Sie neu beim TCS3200D/TCS230 Farbsensor oder den DIYables ESP32 WebApps sind, helfen Ihnen die folgenden Tutorials dabei, sich einzuarbeiten:

Verdrahtungsdiagramm

Das folgende Diagramm zeigt, wie Sie den TCS3200 Farbsensor mit einem ESP32 verbinden:

TCS3200 FarbsensorESP32
VCC5V (VIN)
GNDGND
S0GPIO 17
S1GPIO 16
S2GPIO 18
S3GPIO 5
OUTGPIO 19
ESP32 und TCS3200 Farbsensor Verdrahtungsdiagramm

Dieses Bild wurde mit Fritzing erstellt. Klicken Sie, um das Bild zu vergrößern.

Wenn Sie nicht wissen, wie Sie ESP32 und andere Komponenten mit Strom versorgen, finden Sie Anleitungen im folgenden Tutorial: Wie man ESP32 mit Strom versorgt.

So funktioniert es

Hier ist der schrittweise Ablauf dieses Projekts:

  1. Jede Sekunde liest der ESP32 den Farbsensor, indem er zwischen den rot-, grün- und blau-Filtern über die S2/S3 Steuerpins wechselt und die Pulsbreite am OUT-Pin misst.
  2. Die rohen Pulsbreiten-Werte werden mithilfe von Kalibrierungsdaten (erhalten vom Sensor-Kalibrierungsschritt) in 0–255 RGB-Werte konvertiert.
  3. Die RGB-Werte werden in einen HEX-Farbstring wie #FF8000 formatiert.
  4. Dieser Farbstring wird über WebSocket durch die DIYables ESP32 WebApps Bibliothek an alle verbundenen Webbrowser gesendet.
  5. Auf der Webseite empfängt JavaScript die Farbe und wendet sie sofort auf Körper, Arme und Augenlider des Minion-Charakters an.

ESP32 Code - Farbsensor Minion Web-App

Dieses Projekt besteht aus 4 Dateien:

  • ColorSensorESP32.ino - Haupt-Sketch: initialisiert den Sensor, liest Farben und sendet sie an die Webseite
  • CustomWebApp.h - Header-Datei: deklariert die benutzerdefinierte Web-App-Seitenklasse
  • CustomWebApp.cpp - Implementierungsdatei: verwaltet WebSocket-Nachrichten mit der "Color sensor:" Kennung
  • custom_page_html.h - Webseite: der animierte Minion erstellt mit HTML/CSS/JavaScript, der auf eingehende Farben reagiert

ColorSensorESP32.ino

/* * Dieser ESP32 Code wurde von newbiely.de entwickelt * Dieser ESP32 Code wird der Öffentlichkeit ohne jegliche Einschränkung zur Verfügung gestellt. * Für vollständige Anleitungen und Schaltpläne besuchen Sie bitte: * https://newbiely.de/tutorials/esp32/esp32-color-sensor-via-web */ #include <DIYables_ESP32_Platform.h> #include <DIYablesWebApps.h> #include "CustomWebApp.h" // CHANGE THESE TO YOUR WIFI DETAILS const char WIFI_SSID[] = "YOUR_WIFI_SSID"; const char WIFI_PASSWORD[] = "YOUR_WIFI_PASSWORD"; // Configure TCS3200 pins for ESP32 const int S0 = 17; const int S1 = 16; const int S2 = 18; const int S3 = 5; const int sensorOut = 19; // Create server and pages ESP32ServerFactory serverFactory; DIYablesWebAppServer webAppsServer(serverFactory, 80, 81); DIYablesHomePage homePage; CustomWebAppPage customPage; unsigned long lastColorRead = 0; void setup() { Serial.begin(9600); delay(1000); Serial.println("Starting Custom WebApp..."); // Initialize TCS3200 pins pinMode(S0, OUTPUT); pinMode(S1, OUTPUT); pinMode(S2, OUTPUT); pinMode(S3, OUTPUT); pinMode(sensorOut, INPUT); // Set frequency scaling to 20% digitalWrite(S0, HIGH); digitalWrite(S1, LOW); // Add pages to server webAppsServer.addApp(&homePage); webAppsServer.addApp(&customPage); // Start WiFi and web server if (!webAppsServer.begin(WIFI_SSID, WIFI_PASSWORD)) { while (1) { Serial.println("Failed to connect to WiFi!"); delay(1000); } } Serial.println("Custom WebApp ready!"); customPage.sendToWeb("Arduino is ready!"); } void loop() { // Handle web server webAppsServer.loop(); // Send sensor data every 1 second if (millis() - lastColorRead > 1000) { // Read Red color digitalWrite(S2, LOW); digitalWrite(S3, LOW); int r = map(pulseIn(sensorOut, LOW), 31, 150, 255, 0); // Read Green color digitalWrite(S2, HIGH); digitalWrite(S3, HIGH); int g = map(pulseIn(sensorOut, LOW), 35, 180, 255, 0); // Read Blue color digitalWrite(S2, LOW); digitalWrite(S3, HIGH); int b = map(pulseIn(sensorOut, LOW), 30, 150, 255, 0); // Convert to HEX color and send to Web char hexColor[8]; sprintf(hexColor, "#%02X%02X%02X", constrain(r, 0, 255), constrain(g, 0, 255), constrain(b, 0, 255)); customPage.sendToWeb(String(hexColor)); Serial.println("Sent to Minion: " + String(hexColor)); lastColorRead = millis(); } }

CustomWebApp.h

/* * Dieser ESP32 Code wurde von newbiely.de entwickelt * Dieser ESP32 Code wird der Öffentlichkeit ohne jegliche Einschränkung zur Verfügung gestellt. * Für vollständige Anleitungen und Schaltpläne besuchen Sie bitte: * https://newbiely.de/tutorials/esp32/esp32-color-sensor-via-web */ #ifndef CUSTOM_WEBAPP_H #define CUSTOM_WEBAPP_H #include <DIYablesWebApps.h> /** * Simple Custom WebApp Page * * This is a template for creating your own custom web applications. * It provides basic controls like buttons and sliders that communicate * with your Arduino in real-time. */ class CustomWebAppPage : public DIYablesWebAppPageBase { private: // WebSocket message identifier for this custom app static const String APP_IDENTIFIER; public: CustomWebAppPage(); // ======================================== // REQUIRED METHODS - USED BY LIBRARY - DON'T CHANGE THESE! // ======================================== void handleHTTPRequest(IWebClient& client) override; void handleWebSocketMessage(IWebSocket& ws, const char* message, uint16_t length) override; const char* getPageInfo() const override; String getNavigationInfo() const override; // ======================================== // YOUR METHODS - USE THESE IN YOUR CODE! // ======================================== void onCustomMessageReceived(void (*callback)(const String& payload)); void sendToWeb(const String& message); }; #endif

CustomWebApp.cpp

/* * Dieser ESP32 Code wurde von newbiely.de entwickelt * Dieser ESP32 Code wird der Öffentlichkeit ohne jegliche Einschränkung zur Verfügung gestellt. * Für vollständige Anleitungen und Schaltpläne besuchen Sie bitte: * https://newbiely.de/tutorials/esp32/esp32-color-sensor-via-web */ #include "CustomWebApp.h" #include "custom_page_html.h" // Define the static member - WebSocket message identifier for this custom app const String CustomWebAppPage::APP_IDENTIFIER = "Color sensor:"; // Callback function for handling messages from web browser void (*customMessageCallback)(const String& payload) = nullptr; CustomWebAppPage::CustomWebAppPage() : DIYablesWebAppPageBase("/custom") { } void CustomWebAppPage::handleHTTPRequest(IWebClient& client) { // Send the HTML page to web browser sendHTTPHeader(client); client.print(CUSTOM_PAGE_HTML); } void CustomWebAppPage::handleWebSocketMessage(IWebSocket& ws, const char* message, uint16_t length) { String messageStr = String(message, length); Serial.print("Color sensor WebApp received: "); Serial.println(messageStr); // Only handle messages that start with our app identifier if (messageStr.startsWith(APP_IDENTIFIER)) { String payload = messageStr.substring(APP_IDENTIFIER.length()); // Remove identifier // Call your callback function with the payload if (customMessageCallback) { customMessageCallback(payload); } } } void CustomWebAppPage::onCustomMessageReceived(void (*callback)(const String& payload)) { customMessageCallback = callback; } void CustomWebAppPage::sendToWeb(const String& message) { // Send message to web browser with app identifier String fullMessage = APP_IDENTIFIER + message; broadcastToAllClients(fullMessage.c_str()); } const char* CustomWebAppPage::getPageInfo() const { return "🔧 Color sensor WebApp"; } String CustomWebAppPage::getNavigationInfo() const { String result = "<a href=\""; result += getPagePath(); result += "\" class=\"app-card custom\" style=\"background: linear-gradient(135deg, #007bff 0%, #0056b3 100%);\">"; result += "<h3>🔧 Color sensor WebApp</h3>"; result += "<p>Simple template for your own apps</p>"; result += "</a>"; return result; }

custom_page_html.h

/* * Dieser ESP32 Code wurde von newbiely.de entwickelt * Dieser ESP32 Code wird der Öffentlichkeit ohne jegliche Einschränkung zur Verfügung gestellt. * Für vollständige Anleitungen und Schaltpläne besuchen Sie bitte: * https://newbiely.de/tutorials/esp32/esp32-color-sensor-via-web */ #ifndef CUSTOM_PAGE_HTML_H #define CUSTOM_PAGE_HTML_H const char CUSTOM_PAGE_HTML[] PROGMEM = R"HTML_WRAPPER( <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> <title>Mobile Laughing Minion</title> <style> /* GIỮ NGUYÊN TOÀN BỘ CSS GỐC CỦA BẠN */ body { margin: 0; padding: 20px; box-sizing: border-box; display: flex; flex-direction: column; justify-content: flex-start; align-items: center; background-color: #f0f8ff; font-family: sans-serif; overflow-x: hidden; } .text { font-size: clamp(16px, 5vw, 24px); font-weight: bold; color: #333; margin-bottom: 20px; text-align: center; z-index: 10; } .scale-wrapper { transform-origin: top center; display: flex; justify-content: center; align-items: flex-start; } .minion-container { position: relative; width: 200px; height: 400px; } .body { position: absolute; top: 20px; left: 25px; width: 150px; height: 300px; background-color: #FFD90F; border-radius: 75px; box-shadow: inset -10px -10px 20px rgba(0,0,0,0.1); overflow: hidden; z-index: 2; transition: background-color 0.5s; } .overalls { position: absolute; bottom: 0; width: 100%; height: 90px; background-color: #225A94; border-radius: 0 0 75px 75px; box-shadow: inset -10px -10px 20px rgba(0,0,0,0.2); } .pocket { position: absolute; bottom: 30px; left: 50px; width: 50px; height: 40px; background-color: #1A4674; border-radius: 10px 10px 20px 20px; border: 2px dashed #fce144; } .strap { position: absolute; top: 65px; left: 0; width: 100%; height: 25px; background-color: #333; z-index: 1; } .goggles-wrapper { position: absolute; top: 50px; left: -5px; width: 160px; display: flex; justify-content: center; z-index: 3; } .goggle { position: relative; width: 50px; height: 50px; background-color: white; border: 12px solid #999; border-radius: 50%; box-shadow: 3px 3px 8px rgba(0,0,0,0.2), inset 3px 3px 8px rgba(0,0,0,0.1); margin: 0 -2px; overflow: hidden; } .pupil { position: absolute; top: 50%; left: 50%; width: 20px; height: 20px; background-color: #4B3621; border-radius: 50%; transform: translate(-50%, -50%); transition: transform 0.2s ease-out; } .pupil::after { content: ''; position: absolute; top: 4px; left: 4px; width: 6px; height: 6px; background-color: black; border-radius: 50%; } .catchlight { position: absolute; top: 2px; right: 4px; width: 4px; height: 4px; background-color: white; border-radius: 50%; z-index: 4; } .eyelid { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: #FFD90F; border-bottom: 3px solid #D4B200; transform-origin: top; transform: scaleY(0); z-index: 5; animation: blink 4s infinite; } .mouth { position: absolute; top: 145px; left: 35px; width: 80px; height: 45px; background-color: #3E2723; border-radius: 10px 10px 60px 60px; overflow: hidden; z-index: 3; box-shadow: inset 0 5px 10px rgba(0,0,0,0.5); animation: laugh 0.2s infinite alternate ease-in-out; } .teeth { position: absolute; top: 0; left: 0; width: 100%; height: 14px; background-color: #fff; border-radius: 0 0 5px 5px; } .tongue { position: absolute; bottom: -5px; left: 20px; width: 40px; height: 25px; background-color: #FF5252; border-radius: 50%; animation: wag 0.2s infinite alternate ease-in-out; } .arm { position: absolute; top: 140px; width: 25px; height: 80px; background-color: #FFD90F; border-radius: 12px; z-index: 1; transition: background-color 0.5s; } .arm.left { left: 10px; transform: rotate(35deg); } .arm.right { right: 15px; transform: rotate(-35deg); } .glove { position: absolute; bottom: -15px; left: -5px; width: 35px; height: 35px; background-color: #333; border-radius: 50%; } .leg { position: absolute; bottom: 50px; width: 25px; height: 40px; background-color: #225A94; z-index: 1; } .leg.left { left: 60px; } .leg.right { left: 115px; } .shoe { position: absolute; bottom: -15px; left: -10px; width: 45px; height: 20px; background-color: #222; border-radius: 20px 20px 5px 5px; border-bottom: 5px solid #111; } @keyframes blink { 0%, 94%, 100% { transform: scaleY(0); } 97% { transform: scaleY(1); } } @keyframes laugh { 0% { height: 40px; transform: scaleX(1); } 100% { height: 55px; transform: scaleX(1.05); } } @keyframes wag { 0% { transform: translateY(0); } 100% { transform: translateY(-3px); } } </style> </head> <body> <div class="text" id="status-text">Just watch him look around! 👀</div> <div class="scale-wrapper" id="minionWrapper"> <div class="minion-container"> <div class="arm left" id="armL"><div class="glove"></div></div> <div class="arm right" id="armR"><div class="glove"></div></div> <div class="leg left"><div class="shoe"></div></div> <div class="leg right"><div class="shoe"></div></div> <div class="body" id="minionBody"> <div class="overalls"> <div class="pocket"></div> </div> <div class="strap"></div> <div class="goggles-wrapper"> <div class="goggle"><div class="pupil"><div class="catchlight"></div></div><div class="eyelid" id="eyelidL"></div></div> <div class="goggle"><div class="pupil"><div class="catchlight"></div></div><div class="eyelid" id="eyelidR"></div></div> </div> <div class="mouth"> <div class="teeth"></div> <div class="tongue"></div> </div> </div> </div> </div> <script> // LOGIC KẾT NỐI WEBSOCKET const APP_IDENTIFIER = 'Color sensor:'; let ws = null; function connectWebSocket() { ws = new WebSocket('ws://' + location.hostname + ':81'); ws.onopen = () => document.getElementById('status-text').textContent = "ESP32 - Color Sensor"; ws.onclose = () => setTimeout(connectWebSocket, 2000); ws.onmessage = (event) => { if (event.data.startsWith(APP_IDENTIFIER)) { let color = event.data.substring(APP_IDENTIFIER.length); // Cập nhật màu cho thân, tay và mí mắt document.getElementById('minionBody').style.backgroundColor = color; document.getElementById('armL').style.backgroundColor = color; document.getElementById('armR').style.backgroundColor = color; document.getElementById('eyelidL').style.backgroundColor = color; document.getElementById('eyelidR').style.backgroundColor = color; document.getElementById('status-text').style.color = color; } }; } // GIỮ NGUYÊN LOGIC RESIZE & MẮT GỐC function resizeMinion() { const wrapper = document.getElementById('minionWrapper'); const availableWidth = window.innerWidth - 40; const minionTrueWidth = 260; const minionHeight = 400; let scaleFactor = availableWidth / minionTrueWidth; if (scaleFactor > 1.5) scaleFactor = 1.5; wrapper.style.transform = `scale(${scaleFactor})`; wrapper.style.height = `${minionHeight * scaleFactor}px`; } window.addEventListener('resize', resizeMinion); resizeMinion(); connectWebSocket(); const pupils = document.querySelectorAll('.pupil'); function moveEyesAutomatically() { const angle = Math.random() * Math.PI * 2; const distance = Math.random() * 15; const pupilX = Math.cos(angle) * distance; const pupilY = Math.sin(angle) * distance; pupils.forEach(pupil => { pupil.style.transform = `translate(calc(-50% + ${pupilX}px), calc(-50% + ${pupilY}px))`; }); } setInterval(moveEyesAutomatically, 600); </script> </body> </html> )HTML_WRAPPER"; #endif

Schnelle Schritte

Befolgen Sie diese Schritte, um das Projekt zum Laufen zu bringen:

  • Falls Sie zum ersten Mal mit ESP32 arbeiten, schauen Sie sich das Tutorial zur Einrichtung der ESP32-Entwicklungsumgebung in Arduino IDE an.
  • Führen Sie zuerst die Kalibrierung durch mit dem TCS3200D/TCS230 Kalibrierungsleitfaden für ESP32. Notieren Sie sich Ihre Kalibrierungsergebnisse (redMin, redMax, greenMin, greenMax, blueMin, blueMax).
  • Verbinden Sie die Hardware wie im obigen Verdrahtungsdiagramm gezeigt.
  • Stecken Sie das ESP32-Board mit einem USB-Kabel in Ihren Computer.
  • Öffnen Sie die Arduino IDE.
  • Wählen Sie das korrekte ESP32-Board (z.B. ESP32 Dev Module) und den korrekten COM-Port.
  • Gehen Sie zum Libraries Symbol in der linken Seitenleiste der Arduino IDE.
  • Suchen Sie nach "DIYables ESP32 WebApps" und finden Sie die Bibliothek von DIYables.
  • Klicken Sie Install, um sie zu installieren.
  • Wenn Sie nach zusätzlichen Abhängigkeiten gefragt werden, klicken Sie Install All.
DIYables ESP32 WebApps Bibliothek
DIYables ESP32 WebApps Abhängigkeit
  • Erstellen Sie einen neuen Sketch in der Arduino IDE und nennen Sie ihn ColorSensorESP32.
  • Kopieren Sie alle 4 oben aufgelisteten Dateien in das Projekt. Ihre Arduino IDE sollte 4 Registerkarten wie folgt anzeigen:
ESP32 Farbsensor Web-App Projektdateien in Arduino IDE
  • Ersetzen Sie in ColorSensorESP32.ino die Wi-Fi-Zugangsdaten durch Ihre eigenen Netzwerkdetails:
const char WIFI_SSID[] = "IHR_WIFI_NAME"; const char WIFI_PASSWORD[] = "IHR_WIFI_PASSWORT";
  • Ersetzen Sie die Kalibrierungswerte in den map()-Aufrufen innerhalb von loop() durch die Zahlen, die Sie während der Kalibrierung notiert haben. Wenn Ihre Kalibrierung beispielsweise redMin = 42, redMax = 210, greenMin = 55, greenMax = 185, blueMin = 60, blueMax = 172 ergeben hat, aktualisieren Sie die Zeilen zu:
int r = map(pulseIn(sensorOut, LOW), 42, 210, 255, 0); int g = map(pulseIn(sensorOut, LOW), 55, 185, 255, 0); int b = map(pulseIn(sensorOut, LOW), 60, 172, 255, 0);
  • Klicken Sie den Upload Button, um den Code auf den ESP32 zu laden.
  • Öffnen Sie den Serial Monitor. Sie sollten etwas wie folgt sehen:
COM6
Send
Starting Custom WebApp... Custom WebApp ready! INFO: Added app / INFO: Added app /custom DIYables ESP32 WebApp Library Network connected! IP address: 192.168.0.5 HTTP server started on port 80 WebSocket server started on port 81 ========================================== DIYables WebApp Ready! ========================================== 📱 Web Interface: http://192.168.0.5 🔗 WebSocket: ws://192.168.0.5:81 📋 Available Applications: 🏠 Home Page: http://192.168.0.5/ 🔧 Color sensor WebApp: http://192.168.0.5/custom ========================================== Sent to Minion: #FFD200 Sent to Minion: #00C832 Sent to Minion: #0028FF
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  
  • Falls nichts erscheint, versuchen Sie, die Reset-Taste am ESP32 zu drücken.
  • Kopieren Sie die im Serial Monitor angezeigte IP-Adresse und öffnen Sie sie in einem Webbrowser auf Ihrem Telefon oder Computer.
  • Zum Beispiel: http://192.168.0.5
  • Auf der Startseite tippen Sie auf die Farbsensor WebApp Karte, um die Minion-Seite zu öffnen.
  • Alternativ gehen Sie direkt zu http://[IP_ADRESSE]/custom.
  • Sie sehen den animierten lachenden Minion auf Ihrem Bildschirm.
  • Halten Sie ein farbiges Objekt nahe an den TCS3200 Sensor — die Hautfarbe des Minions wird sich sofort entsprechend der erkannten Farbe aktualisieren!

Sie können der Schritt-für-Schritt Video-Anleitung unten folgen.

Den Code verstehen

ESP32 Seite (ColorSensorESP32.ino)

Der Haupt-Sketch führt folgende Aufgaben aus:

  • Richtet den TCS3200 Sensor ein: Konfiguriert S0/S1 für 20% Frequenzskalierung und bereitet S2/S3 für die Filterauswahl vor.
  • Sampelt Farbe einmal pro Sekunde: Innerhalb von loop() wechselt der ESP32 zwischen den rot-, grün- und blau-Farbfiltern, misst die Pulsbreite mit pulseIn() und konvertiert jeden Messwert mit map() und Ihren Kalibrierungsdaten zu einem 0–255 Wert.
  • Formatiert als HEX: Die drei RGB-Werte werden mit sprintf() und constrain() zu einem HEX-String (z.B. #FF8000) kombiniert.
  • Sendet an Browser: Die HEX-Farbe wird über customPage.sendToWeb() an jeden verbundenen Web-Client übertragen.

Webseiten Seite (custom_page_html.h)

Die HTML-Datei enthält:

  • Einen rein CSS-animierten Minion: Der Charakter verfügt über blinkende Augen, einen lachenden Mund mit wedelnder Zunge und sich zufällig bewegende Pupillen — alles angetrieben durch CSS-Animationen und ein kleines JavaScript-Intervall.
  • WebSocket-Listener: JavaScript öffnet eine dauerhafte Verbindung zum WebSocket-Server des ESP32 auf Port 81 und verarbeitet eingehende Farbnachrichten.
  • Live-Farbanwendung: Jede empfangene HEX-Farbe wird mit einem CSS transition für einen flüssigen visuellen Effekt sanft auf Körper, Arme und Augenlider des Minions angewendet.
  • Automatische Wiederverbindung: Falls die WebSocket-Verbindung abbricht, versucht die Seite alle 2 Sekunden ohne Benutzereingriff eine Wiederverbindung.
  • Responsives Layout: Der Minion skaliert automatisch, um auf jede Bildschirmgröße zu passen, von Telefonen bis zu Desktop-Computern.

Nachrichtenprotokoll

Dieses Projekt folgt dem DIYables ESP32 WebApps Custom App Framework. Nachrichten werden mit der Kennung "Color sensor:" gekennzeichnet:

  • ESP32 sendet: Color sensor:#FF8000 (Kennungsprefix + HEX-Farbwert)
  • Browser empfängt: JavaScript entfernt das Color sensor: Prefix und wendet das verbleibende #FF8000 auf den Minion an

Um mehr über dieses Kommunikationsmuster zu erfahren und wie Sie Ihre eigenen benutzerdefinierten Apps erstellen können, besuchen Sie das DIYables ESP32 WebApps Custom WebApp Tutorial.

※ UNSERE NACHRICHTEN

  • Sie können gerne den Link zu diesem Tutorial teilen. Bitte verwenden Sie jedoch unsere Inhalte nicht auf anderen Websites. Wir haben viel Mühe und Zeit in die Erstellung der Inhalte investiert, bitte respektieren Sie unsere Arbeit!