A tiny smart lamp. The ESP32 shows a web page with a colour picker. Choose a colour on your phone, press Set, and the RGB LED glows in that colour. There's also an Off button.
What you need
- ESP32 board, expansion board and USB cable
- RGB LED
- 3 resistors, 220 Ω
- Breadboard and jumper wires (all from the ESP32 IoT Starter Kit)
- A 2.4 GHz Wi-Fi network
Good to know
Plug the ESP32 into the expansion board from the kit, or place it next to the breadboard, and connect the pins with jumper wires.
The RGB LED has four legs. The longest leg is the common one. With the LED placed so the longest leg is second from the left, the legs are R, common, G, B. This project assumes a common-cathode LED (common leg to GND); see Troubleshooting if yours is common anode.
Wiring

| From | Through | To |
|---|---|---|
| ESP32 GPIO 27 | 220 Ω resistor | LED red leg |
| ESP32 GPIO 26 | 220 Ω resistor | LED green leg |
| ESP32 GPIO 25 | 220 Ω resistor | LED blue leg |
| LED common (longest) leg | GND |
Build it step by step
- Place the RGB LED and the three resistors on the breadboard.
- Connect the colour legs through the resistors to GPIO 27, 26 and 25, and the common leg to GND.
- Enter your Wi-Fi details and upload the code. You need a recent ESP32 board package (version 3 or newer) for
analogWrite(). - Open the address shown in the Serial Monitor on your phone.
- Choose a colour and press Set.
The code
Replace YOUR_WIFI_NAME and YOUR_WIFI_PASSWORD with your own network details. The ESP32 only connects to 2.4 GHz Wi-Fi. After uploading, open the Serial Monitor at 115200 baud to see the address to open on your phone. The phone must be on the same Wi-Fi network.
#include <WiFi.h>
#include <WebServer.h>
const char* WIFI_NAME = "YOUR_WIFI_NAME";
const char* WIFI_PASSWORD = "YOUR_WIFI_PASSWORD";
const int RED_PIN = 27;
const int GREEN_PIN = 26;
const int BLUE_PIN = 25;
const bool COMMON_ANODE = false; // set to true if your LED is common anode
WebServer server(80);
String currentColor = "#000000";
void setColor(int r, int g, int b) {
if (COMMON_ANODE) { r = 255 - r; g = 255 - g; b = 255 - b; }
analogWrite(RED_PIN, r);
analogWrite(GREEN_PIN, g);
analogWrite(BLUE_PIN, b);
}
String page() {
String html = "<!DOCTYPE html><html><head><meta charset='utf-8'>";
html += "<meta name='viewport' content='width=device-width, initial-scale=1'><title>Smart lamp</title></head>";
html += "<body style='font-family:sans-serif;padding:16px;text-align:center'><h1>Smart lamp</h1>";
html += "<form action='/set'><input type='color' name='c' value='" + currentColor + "' style='width:160px;height:160px;border:0'>";
html += "<p><button style='font-size:22px'>Set</button></p></form>";
html += "<p><a href='/set?c=%23000000'><button style='font-size:18px'>Off</button></a></p></body></html>";
return html;
}
void setup() {
Serial.begin(115200);
pinMode(RED_PIN, OUTPUT);
pinMode(GREEN_PIN, OUTPUT);
pinMode(BLUE_PIN, OUTPUT);
setColor(0, 0, 0);
WiFi.begin(WIFI_NAME, WIFI_PASSWORD);
Serial.print("Connecting to Wi-Fi");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.print("Open http://");
Serial.println(WiFi.localIP());
server.on("/", []() { server.send(200, "text/html", page()); });
server.on("/set", []() {
String c = server.arg("c"); // for example "#ff8800"
if (c.length() == 7 && c[0] == '#') {
long value = strtol(c.substring(1).c_str(), NULL, 16);
setColor((value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF);
currentColor = c;
}
server.sendHeader("Location", "/");
server.send(303);
});
server.begin();
}
void loop() {
server.handleClient();
}
How it works
The colour picker sends the colour as a hex code such as #ff8800: two digits each for red, green and blue. The sketch turns that into a number with strtol() and separates the three parts with bit shifts. analogWrite() then uses PWM to set each colour's brightness from 0 to 255, and your eye mixes the three into one colour.
Make it your own
- Add buttons for favourite colours, like "Reading" (warm white) or "Night" (dim blue).
- Make a "rainbow" button that cycles slowly through all colours.
- Combine it with the DHT11 so the colour shows the room temperature.
Troubleshooting
-
The LED is on when it should be off, or the colours are inverted: your LED is common anode. Connect the common leg to 3V3 and set
COMMON_ANODEto true. - Compile error about analogWrite: update the ESP32 board package in the Boards Manager.
- One colour is missing: check that colour's resistor and wire.
Learn the basics first
New to these parts? These lessons explain them step by step: Mix colours with the RGB LED module and Control a relay from your phone over Wi-Fi.
0 comments