Doel
Het idee was simpel: een LED aansturen vanaf mijn telefoon. Geen Bluetooth en geen app, alleen een webpagina die de ESP32 zelf serveert en die elk apparaat op mijn thuis-wifi kan openen. Een schuifregelaar in de browser, en de LED volgt die in realtime. Daarmee komen WiFi, HTTP en PWM in één klein bouwsel samen, en daarom koos ik dit als oefening.
De ESP32 is hier zowel WiFi-client als webserver.
Hardware
- ESP32-WROOM-32-ontwikkelbord
- Ingebouwde LED (GPIO 2)
- USB-kabel
Ik begon met de ingebouwde LED om het aantal onderdelen op nul te houden: geen breadboard, geen externe componenten, alleen het ontwikkelbord en een USB-kabel. De LED op het bord zit op GPIO 2 met de stroombegrenzingsweerstand er al bij, dus aan de hardwarekant viel er niets mis te gaan voordat er code geschreven was.
Software
Arduino IDE met de ESP32 Arduino Core.
#include <WiFi.h>
#include <WebServer.h>
Beide bibliotheken zitten bij de core, dus er hoefde niets extra’s geïnstalleerd te worden. WiFi.h doet de verbinding en WebServer.h levert een lichtgewicht HTTP-server, en meer had dit niet nodig.
Implementatie
WiFi-webserver
De ESP32 meldt zich aan op mijn lokale wifi en serveert een bedieningspagina.
Elk apparaat op hetzelfde netwerk kan het toegewezen IP-adres openen, bijvoorbeeld http://192.168.x.x/.
Dit is het onderdeel van de ESP32 dat ik het leukst vind. Een handvol regels zet een webserver op, en ineens is de microcontroller bereikbaar vanaf alles op het netwerk. Geen routerconfiguratie, geen port forwarding, gewoon een lokaal adres.
PWM-helderheidsregeling
De helderheid loopt op 8-bits PWM, dus 0–255 valt samen met 0%–100%.
De schuifregelaar stuurt een HTTP-verzoek dat de dutycycle verandert:
Browser → /set?value=brightness → PWM-uitgang van de ESP32
8 bits was de voor de hand liggende keuze, want dat sluit aan op het bereik dat ledcWrite aanneemt en op de min- en max-attributen van de schuifregelaar. De pagina gebruikt fetch() om bij elke beweging van de schuifregelaar een GET naar /set?value=128 te sturen, en de ESP32 parst de waarde en schrijft die naar het PWM-kanaal. Op 5000 Hz is er geen zichtbare flikkering.
Testen
- Upload de sketch.
- Open de Serial Monitor en noteer het IP-adres dat na het verbinden wordt getoond.
- Ga in een browser naar dat IP-adres.
- Beweeg de schuifregelaar om de LED-helderheid te wijzigen.
Resultaat
De ESP32 maakt verbinding, serveert de interface, ontvangt HTTP-helderheidswaarden en stuurt de LED aan via PWM. De hele keten werkt van begin tot eind, van hardware via netwerk en interface naar de fysieke uitgang, en daarmee staat er een basis om interactievere dingen op te bouwen.
In ongeveer 160 regels code staat er een werkend, webgestuurd licht. Dezelfde combinatie van WiFi, webserver en PWM gaat net zo goed op voor motortoeren, servopositie of het aansturen van een LED-strip via een MOSFET.
Volledige code
#include <WiFi.h>
#include <WebServer.h>
// Replace with your WiFi name and password
const char* ssid = "YOUR_WIFI_USERNAME_HERE";
const char* password = "YOUR_WIFI_PASSWORD_HERE";
WebServer server(80);
// LED pin
#define LED_PIN 2
// PWM settings
#define PWM_CHANNEL 0
#define PWM_FREQ 5000
#define PWM_RESOLUTION 8 // 8-bit = 0–255
void setup() {
Serial.begin(115200);
// Configure PWM
ledcAttach(LED_PIN, PWM_FREQ, PWM_RESOLUTION);
// Start at 50% brightness
ledcWrite(PWM_CHANNEL, 128);
// Connect to WiFi
WiFi.begin(ssid, password);
Serial.print("Connecting WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.println("WiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
// Home page
server.on("/", []() {
String html = R"rawliteral(
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ESP32 LED Control</title>
<style>
body { text-align: center; font-family: Arial; }
input { width: 80%; }
</style>
</head>
<body>
<h1>ESP32 LED Control</h1>
<h2>Brightness Control</h2>
<input type="range" min="0" max="255" value="128" id="brightness"
oninput="changeBrightness(this.value)">
<p>Current Brightness: <span id="value">128</span></p>
<script>
function changeBrightness(value) {
document.getElementById("value").innerHTML = value;
fetch("/set?value=" + value);
}
</script>
</body>
</html>
)rawliteral";
server.send(200, "text/html;charset=utf-8", html);
});
// Receive brightness data from web page
server.on("/set", []() {
if (server.hasArg("value")) {
int brightness = server.arg("value").toInt();
// Output PWM signal
ledcWrite(LED_PIN, brightness);
Serial.print("Brightness: ");
Serial.println(brightness);
}
server.send(200, "text/plain", "OK");
});
server.begin();
Serial.println("Web server started");
}
void loop() {
server.handleClient();
}
