Dit voorbeeld laat zien hoe u meerdere webapplicaties gelijktijdig gebruikt met de DIYables ESP32 WebApps Library. Het demonstreert de integratie van diverse interactieve webinterfaces — zoals monitoring, bediening en communicatie — binnen één project. Ontworpen voor het ESP32-platform, is dit voorbeeld ideaal om te leren hoe u meerdere webgebaseerde functies combineert en beheert, wat een solide basis biedt voor geavanceerde IoT-projecten.
Volg deze instructies stap voor stap:
Verbind het ESP32-board met uw computer via een USB-kabel.
Start de Arduino IDE op uw computer.
Selecteer het juiste ESP32-board (bijvoorbeeld ESP32 Dev Module) en de juiste COM-poort.
Ga naar het Libraries-icoon in de linkerzijbalk van de Arduino IDE.
Zoek op "DIYables ESP32 WebApps" en zoek vervolgens de DIYables ESP32 WebApps Library van DIYables.
Klik op de Installeren-knop om de bibliotheek te installeren.


#include <DIYables_ESP32_Platform.h>
#include <DIYablesWebApps.h>
const char WIFI_SSID[] = "YOUR_WIFI_SSID";
const char WIFI_PASSWORD[] = "YOUR_WIFI_PASSWORD";
ESP32ServerFactory factory;
DIYablesWebAppServer webAppsServer(factory, 80, 81);
DIYablesHomePage homePage;
DIYablesWebMonitorPage webMonitorPage;
DIYablesWebSliderPage webSliderPage;
DIYablesWebJoystickPage webJoystickPage(false, 5);
DIYablesWebRotatorPage webRotatorPage(ROTATOR_MODE_CONTINUOUS);
DIYablesWebAnalogGaugePage webAnalogGaugePage(0.0, 100.0, "%");
DIYablesWebTablePage webTablePage;
int currentSlider1 = 64;
int currentSlider2 = 128;
int currentJoystickX = 0;
int currentJoystickY = 0;
int currentRotatorAngle = 0;
float currentGaugeValue = 50.0;
void setup() {
Serial.begin(9600);
delay(1000);
Serial.println("DIYables ESP32 WebApp - Multiple Apps Example");
webAppsServer.addApp(&homePage);
webAppsServer.addApp(&webMonitorPage);
webAppsServer.addApp(&webSliderPage);
webAppsServer.addApp(&webJoystickPage);
webAppsServer.addApp(&webRotatorPage);
webAppsServer.addApp(&webAnalogGaugePage);
webAppsServer.addApp(&webTablePage);
webAppsServer.setNotFoundPage(DIYablesNotFoundPage());
webTablePage.addRow("Arduino Status");
webTablePage.addRow("WiFi Connected");
webTablePage.addRow("Uptime");
webTablePage.addRow("Slider 1");
webTablePage.addRow("Slider 2");
webTablePage.addRow("Joystick X");
webTablePage.addRow("Joystick Y");
webTablePage.addRow("Rotator Angle");
webTablePage.addRow("Gauge Value");
if (!webAppsServer.begin(WIFI_SSID, WIFI_PASSWORD)) {
while (1) {
Serial.println("Failed to start WebApp server!");
delay(1000);
}
}
setupCallbacks();
}
void setupCallbacks() {
webMonitorPage.onWebMonitorMessage([](const String& message) {
Serial.println("Web Monitor: " + message);
webMonitorPage.sendToWebMonitor("Arduino received: " + message);
});
webSliderPage.onSliderValueFromWeb([](int slider1, int slider2) {
currentSlider1 = slider1;
currentSlider2 = slider2;
Serial.print("Slider 1: ");
Serial.print(slider1);
Serial.print(", Slider 2: ");
Serial.println(slider2);
webTablePage.sendValueUpdate("Slider 1", String(slider1));
webTablePage.sendValueUpdate("Slider 2", String(slider2));
currentGaugeValue = map(slider1, 0, 255, 0, 100);
webAnalogGaugePage.sendToWebAnalogGauge(currentGaugeValue);
char gaugeStr[16];
snprintf(gaugeStr, sizeof(gaugeStr), "%.1f%%", currentGaugeValue);
webTablePage.sendValueUpdate("Gauge Value", String(gaugeStr));
});
webSliderPage.onSliderValueToWeb([]() {
webSliderPage.sendToWebSlider(currentSlider1, currentSlider2);
});
webJoystickPage.onJoystickValueFromWeb([](int x, int y) {
currentJoystickX = x;
currentJoystickY = y;
Serial.print("Joystick - X: ");
Serial.print(x);
Serial.print(", Y: ");
Serial.println(y);
Serial.print(x);
Serial.print(", Y: ");
Serial.println(y);
webTablePage.sendValueUpdate("Joystick X", String(x));
webTablePage.sendValueUpdate("Joystick Y", String(y));
}
});
webJoystickPage.onJoystickValueToWeb([]() {
webJoystickPage.sendToWebJoystick(currentJoystickX, currentJoystickY);
});
webRotatorPage.onRotatorAngleFromWeb([](float angle) {
currentRotatorAngle = (int)angle;
Serial.println("Rotator angle: " + String(angle) + "°");
webTablePage.sendValueUpdate("Rotator Angle", String(angle, 0) + "°");
});
webAnalogGaugePage.onGaugeValueRequest([]() {
webAnalogGaugePage.sendToWebAnalogGauge(currentGaugeValue);
});
webTablePage.onTableValueRequest([]() {
webTablePage.sendValueUpdate("Arduino Status", "Running");
webTablePage.sendValueUpdate("WiFi Connected", "Yes");
webTablePage.sendValueUpdate("Uptime", "0 seconds");
webTablePage.sendValueUpdate("Slider 1", String(currentSlider1));
webTablePage.sendValueUpdate("Slider 2", String(currentSlider2));
webTablePage.sendValueUpdate("Joystick X", String(currentJoystickX));
webTablePage.sendValueUpdate("Joystick Y", String(currentJoystickY));
webTablePage.sendValueUpdate("Rotator Angle", String(currentRotatorAngle) + "°");
webTablePage.sendValueUpdate("Gauge Value", String(currentGaugeValue, 1) + "%");
});
}
void loop() {
webAppsServer.loop();
static unsigned long lastUptimeUpdate = 0;
if (millis() - lastUptimeUpdate > 5000) {
lastUptimeUpdate = millis();
unsigned long uptimeSeconds = millis() / 1000;
String uptimeStr = String(uptimeSeconds) + " seconds";
if (uptimeSeconds >= 60) {
uptimeStr = String(uptimeSeconds / 60) + "m " + String(uptimeSeconds % 60) + "s";
}
webTablePage.sendValueUpdate("Uptime", uptimeStr);
}
static unsigned long lastSensorUpdate = 0;
if (millis() - lastSensorUpdate > 3000) {
lastSensorUpdate = millis();
float sensorValue = 50.0 + 30.0 * sin(millis() / 10000.0);
currentGaugeValue = sensorValue;
webAnalogGaugePage.sendToWebAnalogGauge(currentGaugeValue);
webTablePage.sendValueUpdate("Gauge Value", String(currentGaugeValue, 1) + "%");
}
delay(10);
}
const char WIFI_SSID[] = "UW_WIFI_NETWERK";
const char WIFI_PASSWORD[] = "UW_WIFI_WACHTWOORD";
DIYables WebApp - Multiple Apps Example
INFO: Added app /
INFO: Added app /web-monitor
INFO: Added app /web-slider
INFO: Added app /web-joystick
INFO: Added app /web-rotator
INFO: Added app /web-gauge
INFO: Added app /web-table
DIYables WebApp Library
Platform: ESP32
Network connected!
IP address: 192.168.0.2
HTTP server started on port 80
Configuring WebSocket server callbacks...
WebSocket server started on port 81
WebSocket URL: ws://192.168.0.2:81
WebSocket server started on port 81
==========================================
DIYables WebApp Ready!
==========================================
📱 Web Interface: http://192.168.0.2
🔗 WebSocket: ws://192.168.0.2:81
📋 Beschikbare applicaties:
🏠 Homepagina: http://192.168.0.2/
📊 Web Monitor: http://192.168.0.2/web-monitor
🎚️ Web Slider: http://192.168.0.2/web-slider
🕹️ Web Joystick: http://192.168.0.2/web-joystick
🔄 Web Rotator: http://192.168.0.2/web-rotator
⏲️ Web Analoge Meter: http://192.168.0.2/web-gauge
📊 Web Tabel: http://192.168.0.2/web-table
==========================================
Als u niets ziet, start dan het ESP32-board opnieuw op.
Noteer het getoonde IP-adres en voer dit adres in de adresbalk van een webbrowser op uw smartphone of pc in.
Voorbeeld: http://192.168.0.2
U ziet de homepagina met alle webapplicaties zoals hieronder afgebeeld:
Klik op een willekeurige webapplicatielink (Chat, Web Monitor, Web Digital Pins, Web Slider, Web Joystick, enzovoort), u ziet dan de gebruikersinterface van de betreffende webapp.
U kunt ook elke pagina direct benaderen via het IP-adres gevolgd door het pad van de app, bijvoorbeeld: http://192.168.0.2/chat, http://192.168.0.2/web-monitor, enzovoort.
Verken alle webapplicaties: probeer te chatten met Arduino, bekijk seriële output, bedien digitale pinnen, stel schuifregelaars in en gebruik de virtuele joystick om de volledige mogelijkheden van de geïntegreerde webinterface te ervaren.
De homepagina fungeert als uw bedieningscentrum met links naar alle applicaties:
Web Monitor: /webmonitor - Seriële communicatie-interface
Chat: /chat - Interactief berichtenverkeer met Arduino
Digitale Pinnen: /digital-pins - Pinbediening en monitoring
Web Slider: /webslider - Dubbele analoge bedieningsschuifregelaars
Web Joystick: /webjoystick - 2D-positiebedieningsinterface
Toegang tot elke interface direct:
http://[ARDUINO_IP]/ # Homepagina
http://[ARDUINO_IP]/webmonitor # Seriële monitor interface
http://[ARDUINO_IP]/chat # Chat interface
http://[ARDUINO_IP]/digital-pins # Pin bediening
http://[ARDUINO_IP]/webslider # Slider bediening
http://[ARDUINO_IP]/webjoystick # Joystick bediening
Dit uitgebreide voorbeeld biedt een basis voor uw creatieve projecten. Pas onderstaande configuraties aan om verbluffende IoT-applicaties te bouwen die bij uw unieke visie passen.
Het voorbeeld heeft specifieke pinnen vooraf geconfigureerd voor verschillende doeleinden:
webDigitalPinsPage.enablePin(2, WEB_PIN_OUTPUT);
webDigitalPinsPage.enablePin(3, WEB_PIN_OUTPUT);
webDigitalPinsPage.enablePin(4, WEB_PIN_OUTPUT);
webDigitalPinsPage.enablePin(13, WEB_PIN_OUTPUT);
webDigitalPinsPage.enablePin(8, WEB_PIN_INPUT);
webDigitalPinsPage.enablePin(9, WEB_PIN_INPUT);
DIYablesWebJoystickPage webJoystickPage(false, 5);
Het voorbeeld houdt gesynchroniseerde status bij over alle interfaces:
int pinStates[16] = { LOW };
int currentSlider1 = 64;
int currentSlider2 = 128;
int currentJoystickX = 0;
int currentJoystickY = 0;
De chatinterface bevat diverse vooraf geprogrammeerde commando’s:
hello - Vriendelijke begroeting
time - Toont uptime van de ESP32 in seconden
status - Geeft status van ESP32 en LED weer
help - Lijst van beschikbare commando's
User: hello
ESP32: Hello! I'm your Arduino. How can I help you?
User: led on
ESP32: Built-in LED is now ON!
User: time
ESP32: I've been running for 1245 seconds.
User: status
ESP32: Status: Running smoothly! LED is ON
#include <Servo.h>
const int MOTOR_LEFT_PWM = 9;
const int MOTOR_RIGHT_PWM = 10;
const int SERVO_PAN = 11;
const int SERVO_TILT = 12;
const int LED_STRIP_PIN = 6;
Servo panServo, tiltServo;
void setup() {
panServo.attach(SERVO_PAN);
tiltServo.attach(SERVO_TILT);
pinMode(MOTOR_LEFT_PWM, OUTPUT);
pinMode(MOTOR_RIGHT_PWM, OUTPUT);
setupRobotCallbacks();
}
void setupRobotCallbacks() {
webJoystickPage.onJoystickValueFromWeb([](int x, int y) {
int leftSpeed = y + (x / 2);
int rightSpeed = y - (x / 2);
leftSpeed = constrain(leftSpeed, -100, 100);
rightSpeed = constrain(rightSpeed, -100, 100);
leftSpeed = map(leftSpeed, -100, 100, -currentSlider1, currentSlider1);
rightSpeed = map(rightSpeed, -100, 100, -currentSlider1, currentSlider1);
analogWrite(MOTOR_LEFT_PWM, abs(leftSpeed));
analogWrite(MOTOR_RIGHT_PWM, abs(rightSpeed));
Serial.println("Robot - Left: " + String(leftSpeed) + ", Right: " + String(rightSpeed));
});
webSliderPage.onSliderValueFromWeb([](int slider1, int slider2) {
int panAngle = map(currentJoystickX, -100, 100, 0, 180);
int tiltAngle = map(slider2, 0, 255, 0, 180);
panServo.write(panAngle);
tiltServo.write(tiltAngle);
Serial.println("Camera - Pan: " + String(panAngle) + "°, Tilt: " + String(tiltAngle) + "°");
});
webDigitalPinsPage.onPinWrite([](int pin, int state) {
switch (pin) {
case 2:
digitalWrite(pin, state);
Serial.println("Koplampen " + String(state ? "AAN" : "UIT"));
break;
case 3:
if (state) {
digitalWrite(pin, HIGH);
delay(200);
digitalWrite(pin, LOW);
}
break;
case 4:
if (state) {
analogWrite(MOTOR_LEFT_PWM, 0);
analogWrite(MOTOR_RIGHT_PWM, 0);
Serial.println("NOODSTOP GEACTIVEERD");
}
break;
}
});
chatPage.onChatMessage([](const String& message) {
String msg = message;
msg.toLowerCase();
if (msg.indexOf("stop") >= 0) {
analogWrite(MOTOR_LEFT_PWM, 0);
analogWrite(MOTOR_RIGHT_PWM, 0);
chatPage.sendToChat("Robot stopped!");
return;
}
if (msg.indexOf("center camera") >= 0) {
panServo.write(90);
tiltServo.write(90);
chatPage.sendToChat("Camera centered!");
return;
}
if (msg.indexOf("speed") >= 0) {
String response = "Current max speed: " + String(map(currentSlider1, 0, 255, 0, 100)) + "%";
chatPage.sendToChat(response);
return;
}
chatPage.sendToChat("Robot commands: stop, center camera, speed");
});
}
const int LIVING_ROOM_LIGHTS = 2;
const int BEDROOM_LIGHTS = 3;
const int KITCHEN_LIGHTS = 4;
const int FAN_CONTROL = 9;
const int AC_CONTROL = 10;
const int MOTION_SENSOR = 8;
const int DOOR_SENSOR = 9;
void setupHomeAutomation() {
pinMode(LIVING_ROOM_LIGHTS, OUTPUT);
pinMode(BEDROOM_LIGHTS, OUTPUT);
pinMode(KITCHEN_LIGHTS, OUTPUT);
pinMode(FAN_CONTROL, OUTPUT);
pinMode(AC_CONTROL, OUTPUT);
pinMode(MOTION_SENSOR, INPUT);
pinMode(DOOR_SENSOR, INPUT_PULLUP);
webDigitalPinsPage.onPinWrite([](int pin, int state) {
digitalWrite(pin, state);
String room;
switch (pin) {
case 2: room = "Woonkamer"; break;
case 3: room = "Slaapkamer"; break;
case 4: room = "Keuken"; break;
default: room = "Pin " + String(pin); break;
}
Serial.println(room + " verlichting " + String(state ? "AAN" : "UIT"));
String message = room + " verlichting is " + String(state ? "AAN" : "UIT");
chatPage.sendToChat(message);
});
webSliderPage.onSliderValueFromWeb([](int slider1, int slider2) {
analogWrite(FAN_CONTROL, slider1);
analogWrite(AC_CONTROL, slider2);
Serial.println("Ventilator: " + String(map(slider1, 0, 255, 0, 100)) + "%, " +
"AC: " + String(map(slider2, 0, 255, 0, 100)) + "%");
});
chatPage.onChatMessage([](const String& message) {
String msg = message;
msg.toLowerCase();
if (msg.indexOf("all lights on") >= 0) {
digitalWrite(LIVING_ROOM_LIGHTS, HIGH);
digitalWrite(BEDROOM_LIGHTS, HIGH);
digitalWrite(KITCHEN_LIGHTS, HIGH);
chatPage.sendToChat("Alle lichten aangezet!");
return;
}
if (msg.indexOf("all lights off") >= 0) {
digitalWrite(LIVING_ROOM_LIGHTS, LOW);
digitalWrite(BEDROOM_LIGHTS, LOW);
digitalWrite(KITCHEN_LIGHTS, LOW);
chatPage.sendToChat("Alle lichten uitgezet!");
return;
}
if (msg.indexOf("temperature") >= 0) {
String response = "Ventilator: " + String(map(currentSlider1, 0, 255, 0, 100)) + "%, " +
"AC: " + String(map(currentSlider2, 0, 255, 0, 100)) + "%";
chatPage.sendToChat(response);
return;
}
if (msg.indexOf("security") >= 0) {
bool motion = digitalRead(MOTION_SENSOR);
bool door = digitalRead(DOOR_SENSOR);
String status = "Beweging: " + String(motion ? "GEREGISTREERD" : "GEEN") +
", Deur: " + String(door ? "GESLOTEN" : "OPEN");
chatPage.sendToChat(status);
return;
}
chatPage.sendToChat("Home commands: all lights on/off, temperature, security");
});
}
void loop() {
server.loop();
static bool lastMotion = false;
static bool lastDoor = false;
bool currentMotion = digitalRead(MOTION_SENSOR);
bool currentDoor = digitalRead(DOOR_SENSOR);
if (currentMotion != lastMotion) {
if (currentMotion) {
chatPage.sendToChat("🚨 BEWEGING GEREGISTREERD!");
webMonitorPage.sendToWebMonitor("Security Alert: Motion detected");
}
lastMotion = currentMotion;
}
if (currentDoor != lastDoor) {
String status = currentDoor ? "GESLOTEN" : "GEOPEND";
chatPage.sendToChat("🚪 Deur " + status);
webMonitorPage.sendToWebMonitor("Security: Door " + status);
lastDoor = currentDoor;
}
delay(10);
}
const int HEATING_ELEMENT = 9;
const int COOLING_FAN = 10;
const int STIRRER_MOTOR = 11;
const int TEMP_SENSOR_PIN = A0;
const int PH_SENSOR_PIN = A1;
void setupScienceExperiment() {
webSliderPage.onSliderValueFromWeb([](int slider1, int slider2) {
int targetTemp = map(slider1, 0, 255, 20, 80);
analogWrite(STIRRER_MOTOR, slider2);
int currentTemp = readTemperature();
if (currentTemp < targetTemp) {
analogWrite(HEATING_ELEMENT, 200);
analogWrite(COOLING_FAN, 0);
} else if (currentTemp > targetTemp + 2) {
analogWrite(HEATING_ELEMENT, 0);
analogWrite(COOLING_FAN, 255);
} else {
analogWrite(HEATING_ELEMENT, 0);
analogWrite(COOLING_FAN, 0);
}
Serial.println("Doel: " + String(targetTemp) + "°C, Huidig: " + String(currentTemp) + "°C");
});
chatPage.onChatMessage([](const String& message) {
String msg = message;
msg.toLowerCase();
if (msg.indexOf("data") >= 0) {
int temp = readTemperature();
float ph = readPH();
String data = "Temperatuur: " + String(temp) + "°C, pH: " + String(ph, 2);
chatPage.sendToChat(data);
return;
}
if (msg.indexOf("start") >= 0) {
chatPage.sendToChat("🔬 Experiment gestart! Condities worden gemonitord...");
return;
}
if (msg.indexOf("stop") >= 0) {
analogWrite(HEATING_ELEMENT, 0);
analogWrite(COOLING_FAN, 0);
analogWrite(STIRRER_MOTOR, 0);
chatPage.sendToChat("⚠️ Experiment gestopt - alle systemen UIT");
return;
}
chatPage.sendToChat("Science commands: data, start, stop");
});
webMonitorPage.onWebMonitorMessage([](const String& message) {
if (message == "log") {
int temp = readTemperature();
float ph = readPH();
String logEntry = String(millis()) + "," + String(temp) + "," + String(ph, 2);
webMonitorPage.sendToWebMonitor(logEntry);
}
});
}
int readTemperature() {
int sensorValue = analogRead(TEMP_SENSOR_PIN);
return map(sensorValue, 0, 1023, 0, 100);
}
float readPH() {
int sensorValue = analogRead(PH_SENSOR_PIN);
return map(sensorValue, 0, 1023, 0, 14) / 10.0;
}
void synchronizeAllStates() {
webSliderPage.sendToWebSlider(currentSlider1, currentSlider2);
webJoystickPage.sendToWebJoystick(currentJoystickX, currentJoystickY);
for (int pin = 0; pin <= 13; pin++) {
if (webDigitalPinsPage.isPinEnabled(pin)) {
webDigitalPinsPage.updatePinState(pin, pinStates[pin]);
}
}
Serial.println("Alle interface-statussen gesynchroniseerd");
}
void setupCrossInterfaceCommunication() {
webJoystickPage.onJoystickValueFromWeb([](int x, int y) {
float distance = sqrt(x*x + y*y);
if (distance > 50) {
int maxValue = map(distance, 50, 100, 255, 128);
}
});
webDigitalPinsPage.onPinWrite([](int pin, int state) {
if (pin == 2 && state == HIGH) {
chatPage.sendToChat("📢 Systeem geactiveerd - extra commando's beschikbaar");
} else if (pin == 2 && state == LOW) {
chatPage.sendToChat("📢 Systeem gedeactiveerd - alleen beperkte commando's");
}
});
}
1. Sommige interfaces laden niet
Controleer dat alle applicaties in setup() aan de server zijn toegevoegd
Verifieer WebSocket-verbindingen in de browserconsole
Controleer of er voldoende geheugen beschikbaar is voor alle interfaces
2. Statusinconsistenties tussen interfaces
Implementeer status synchronisatie callbacks
Gebruik gedeelde globale variabelen voor statustracking
Roep synchronisatiefuncties aan na grote statuswijzigingen
3. Prestatieproblemen bij meerdere interfaces
Verlaag updatefrequenties voor niet-kritieke interfaces
Implementeer selectieve updates gebaseerd op actieve interface
Overweeg niet-gebruikte interfaces uit te schakelen in specifieke projecten
4. Geheugenbeperkingen
Monitor beschikbaar RAM met Serial.print(freeMemory())
Schakel ongebruikte interfaces uit bij beperkte geheugenruimte
Optimaliseer callbackfuncties om geheugenverbruik te minimaliseren
void debugSystemState() {
Serial.println("=== Debug systeemstatus ===");
Serial.println("Vrij geheugen: " + String(freeMemory()) + " bytes");
Serial.println("Digitale pinnen:");
for (int pin = 0; pin <= 13; pin++) {
if (webDigitalPinsPage.isPinEnabled(pin)) {
Serial.println(" Pin " + String(pin) + ": " + String(pinStates[pin] ? "HIGH" : "LOW"));
}
}
Serial.println("Sliders: " + String(currentSlider1) + ", " + String(currentSlider2));
Serial.println("Joystick: X=" + String(currentJoystickX) + ", Y=" + String(currentJoystickY));
Serial.println("============================");
}
void optimizeMemoryUsage() {
}
void controlUpdateFrequency() {
static unsigned long lastSlowUpdate = 0;
static unsigned long lastFastUpdate = 0;
if (millis() - lastFastUpdate > 10) {
lastFastUpdate = millis();
}
if (millis() - lastSlowUpdate > 1000) {
lastSlowUpdate = millis();
}
}
Na het beheersen van het MultipleWebApps voorbeeld:
Pas aan voor uw project: Verwijder ongebruikte interfaces en voeg project-specifieke logica toe
Voeg sensoren toe: Integreer echte sensorwaarden voor inputmonitoring
Implementeer veiligheid: Voeg noodstops en veiligheidsinterlocks toe
Maak aangepaste commando's: Breid chatinterface uit met project-specifieke commando’s
Voeg datalogging toe: Gebruik de webmonitor voor permanente gegevensopslag
Optimaliseer voor mobiel: Test en optimaliseer voor gebruik op mobiele apparaten
Voor extra hulp:
Raadpleeg de afzonderlijke voorbeelddocumentatie (Chat_Example.txt, WebMonitor_Example.txt, enz.)
Bekijk de API Reference documentatie
Bezoek DIYables tutorials: https://esp32io.com/tutorials/diyables-esp32-webapps
ESP32 communityforums
Dit uitgebreide voorbeeld vormt de basis voor vrijwel elk webgestuurd ESP32-project. Begin met deze template en pas hem aan uw specifieke behoeften aan!