Smart RGB lamp

Pick any colour on your phone and the RGB LED lights up in that colour, over Wi-Fi.
  • Level:Beginner
  • Duration: 45 min
  • Ages 10+
  • Platform: ESP32
Community project EEMENTOR team
Smart RGB lamp – EEMENTOR STEM™ project

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

Breadboard wiring diagram: Smart RGB lamp
Breadboard view. Check each connection against the wiring table below.
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

  1. Place the RGB LED and the three resistors on the breadboard.
  2. Connect the colour legs through the resistors to GPIO 27, 26 and 25, and the common leg to GND.
  3. Enter your Wi-Fi details and upload the code. You need a recent ESP32 board package (version 3 or newer) for analogWrite().
  4. Open the address shown in the Serial Monitor on your phone.
  5. 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_ANODE to 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

Leave a comment

Please note, comments need to be approved before they are published.

Build it yourself

Get the parts used in this project, tested by our engineers.

ESP32 IoT Starter Kit | Arduino IDE Compatible | Free Tutorials $57.00

Shop the parts

More projects

  • Pulse visualiser

    • Level:Intermediate
    • Duration: 45 min
    • Platform: Arduino

    by EEMENTOR team

  • Flame alarm

    • Level:Beginner
    • Duration: 40 min
    • Platform: Arduino

    by EEMENTOR team

Community projects

Built something awesome? Share it.

Send us your project and we'll feature it in the hub, credited to you, so other makers can learn from it.

  1. Sign in and tell us about your build
  2. Our team reviews your submission
  3. We publish it in the hub, credited to you