Wi-Fi RGB Light Show Functions Using NodeMCU

Overview

In this project, we will build a Wi-Fi-controlled RGB lighting system using NodeMCU (ESP8266) and the Blynk app. It features: individual control of 3 RGB LEDs, a color pickers for custom hues, and pattern mode for automated light shows.

Designed for applications in home automation, commercial ambiance control, and educational demonstrations, it features smooth PWM-based color transitions and energy efficiency. With straightforward hardware connections and intuitive software integration via Blynk, this project highlights how low-cost IoT devices can deliver dynamic lighting effects, laying the groundwork for future enhancements like audio-reactive visuals or AI-driven color adaptation.

 

Hardware Used

Software Used

Application Discussion


NodeMCU is an open-source firmware and development board based on the ESP8266 Wi-Fi microcontroller, designed for IoT and embedded projects. Originally developed to run Lua scripts, it now supports programming via Arduino IDE and MicroPython, offering Wi-Fi connectivity (802.11 b/g/n), GPIO pins for sensors/actuators, and a built-in USB interface for easy flashing and power. 

 

Specifications:

  • Microcontroller: ESP8266 (32-bit Tensilica L106 @ 80–160 MHz)

  • Wi-Fi: 802.11 b/g/n (2.4 GHz), supports STA/AP/STA+AP modes

  • Flash Memory: 4MB (varies by model)

  • RAM: 64KB (for user programs) + 96KB (system reserved)

  • GPIO Pins: 10–17 (multiplexed, some support PWM/I²C/SPI)

  • Analog Input: 1x 10-bit ADC (max 3.3V input)

  • Digital Interfaces: UART, SPI, I²C

  • USB-to-Serial: CH340G/CP2102 (for programming)

  • Power Supply: 3.3V (board includes 3.3V regulator, input: 5V via USB or 7–12V via Vin)

  • Operating Voltage: 3.3V (GPIOs are not 5V-tolerant!)

 

 

RGB LED, Diffused

Specifications:

  • 5mm / 10mm diameter
  • Tricolor Red(R) Green(G) Blue(B) Common Cathode(CC), R:620nm-625nm / G:515nm-523nm / B:450nm-467nm, Luminous Intensity(Brightness): R:1000-2000mcd / G:4000-5000mcd / B:3000-4000mcd, Viewing Angle: 20-50 Degrees
  • Parameters : DC 1.8V-2.2V(R) 3V-3.4V (G/B) Volt 20mA, Polarity (2 V) : Cathode "-" (Longer Leg) | Anode "+" (Shorter Leg), Foggy Round Small Lens
  • Led diode(Through Hole DIP 4pins leads mini LEDs Set) Three Colour
  • Compatible with: DIY PCB Board Circuit, Arduino, Raspberry Pi, Hobby, Science Experiments, Throwies Project, Breadboard, Bulb, Bulk Parts Replacement
  • 4 pin, Tiny Bright Light, Low Voltage & Low Power Consumption, 1.8v 2.2v 3.2v 3.4v

RGB LED PINOUT

How RGB LEDs work and how to control color

 

Hardware Setup

NodeMCU Pins:

LED1:

  • D0(R)
  • D1(G)
  • D2(B)

LED2:

  • D3(R)
  • D4(G)
  • D5(B)

LED3:

  • D6(R)
  • D7(G)
  • D8(B)

All LED cathodes → GND

 

Software Setup

Below is the Arduino sketch for the project.

#define BLYNK_TEMPLATE_ID "TMPL6bYnZicw8"
#define BLYNK_TEMPLATE_NAME "RGB LIGHT SHOW"
#define BLYNK_AUTH_TOKEN "3dnat1_YCGM6TwpRnW4i4O3eBx8rgW7N"

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

char ssid[] = "dyemwifi";
char pass[] = "dy3mdyem098";

// LED Pins
const int ledPin11 = D0;  // LED1 Red
const int ledPin12 = D1;  // LED1 Green
const int ledPin13 = D2;  // LED1 Blue

const int ledPin21 = D3;  // LED2 Red
const int ledPin22 = D4;  // LED2 Green
const int ledPin23 = D5;  // LED2 Blue

const int ledPin31 = D6;  // LED3 Red
const int ledPin32 = D7;  // LED3 Green
const int ledPin33 = D8;  // LED3 Blue

// Control variables
struct RGBColor {
  int r;
  int g;
  int b;
};

// For RGB widget control
RGBColor selectedColor = {255, 255, 255};
int brightness = 100;  // 0-100%
bool rgbWidgetMode = false;
bool runningEffect = false;
unsigned long effectMillis = 0;
int effectSpeed = 300;  // milliseconds between changes
int currentRunningLED = 1;

// For pattern control
enum Pattern { NONE, RED_RUN, GREEN_RUN, BLUE_RUN, RAINBOW_CHASE };
Pattern currentPattern = NONE;
unsigned long patternMillis = 0;
int patternPosition = 0;

void turnOffAllLEDs() {
  analogWrite(ledPin11, 0);
  analogWrite(ledPin12, 0);
  analogWrite(ledPin13, 0);
  analogWrite(ledPin21, 0);
  analogWrite(ledPin22, 0);
  analogWrite(ledPin23, 0);
  analogWrite(ledPin31, 0);
  analogWrite(ledPin32, 0);
  analogWrite(ledPin33, 0);
}

void setLEDColor(int ledNumber, int color) {
  // For individual color control (0=red, 1=green, 2=blue)
  int r = (color == 0) ? 255 : 0;
  int g = (color == 1) ? 255 : 0;
  int b = (color == 2) ? 255 : 0;
 
  switch(ledNumber) {
    case 1:
      analogWrite(ledPin11, r);
      analogWrite(ledPin12, g);
      analogWrite(ledPin13, b);
      break;
    case 2:
      analogWrite(ledPin21, r);
      analogWrite(ledPin22, g);
      analogWrite(ledPin23, b);
      break;
    case 3:
      analogWrite(ledPin31, r);
      analogWrite(ledPin32, g);
      analogWrite(ledPin33, b);
      break;
  }
}

void setLEDRGB(int ledNumber, RGBColor color) {
  // Apply brightness to each color channel
  int r = map(color.r, 0, 255, 0, brightness * 2.55);
  int g = map(color.g, 0, 255, 0, brightness * 2.55);
  int b = map(color.b, 0, 255, 0, brightness * 2.55);

  switch(ledNumber) {
    case 1:
      analogWrite(ledPin11, r);
      analogWrite(ledPin12, g);
      analogWrite(ledPin13, b);
      break;
    case 2:
      analogWrite(ledPin21, r);
      analogWrite(ledPin22, g);
      analogWrite(ledPin23, b);
      break;
    case 3:
      analogWrite(ledPin31, r);
      analogWrite(ledPin32, g);
      analogWrite(ledPin33, b);
      break;
  }
}

void updateEffects() {
  unsigned long currentMillis = millis();
 
  // Handle RGB widget running effect
  if (runningEffect && rgbWidgetMode) {
    if (currentMillis - effectMillis >= effectSpeed) {
      effectMillis = currentMillis;
      turnOffAllLEDs();
      setLEDRGB(currentRunningLED, selectedColor);
      currentRunningLED = (currentRunningLED % 3) + 1;  // Cycle through 1-3
    }
  }
 
  // Handle color patterns
  else if (currentPattern != NONE) {
    if (currentMillis - patternMillis >= effectSpeed) {
      patternMillis = currentMillis;
     
      switch(currentPattern) {
        case RED_RUN:
          turnOffAllLEDs();
          setLEDColor(patternPosition + 1, 0);
          break;
        case GREEN_RUN:
          turnOffAllLEDs();
          setLEDColor(patternPosition + 1, 1);
          break;
        case BLUE_RUN:
          turnOffAllLEDs();
          setLEDColor(patternPosition + 1, 2);
          break;
        case RAINBOW_CHASE:
          turnOffAllLEDs();
          setLEDColor(1, patternPosition % 3);
          setLEDColor(2, (patternPosition + 1) % 3);
          setLEDColor(3, (patternPosition + 2) % 3);
          break;
        case NONE:
          break;
      }
      patternPosition = (patternPosition + 1) % 3;
    }
  }
}

// Individual LED control (V0-V8)
BLYNK_WRITE(V0) { if (!rgbWidgetMode) setLEDColor(1, param.asInt() ? 0 : -1); }
BLYNK_WRITE(V1) { if (!rgbWidgetMode) setLEDColor(1, param.asInt() ? 1 : -1); }
BLYNK_WRITE(V2) { if (!rgbWidgetMode) setLEDColor(1, param.asInt() ? 2 : -1); }
BLYNK_WRITE(V3) { if (!rgbWidgetMode) setLEDColor(2, param.asInt() ? 0 : -1); }
BLYNK_WRITE(V4) { if (!rgbWidgetMode) setLEDColor(2, param.asInt() ? 1 : -1); }
BLYNK_WRITE(V5) { if (!rgbWidgetMode) setLEDColor(2, param.asInt() ? 2 : -1); }
BLYNK_WRITE(V6) { if (!rgbWidgetMode) setLEDColor(3, param.asInt() ? 0 : -1); }
BLYNK_WRITE(V7) { if (!rgbWidgetMode) setLEDColor(3, param.asInt() ? 1 : -1); }
BLYNK_WRITE(V8) { if (!rgbWidgetMode) setLEDColor(3, param.asInt() ? 2 : -1); }

// Pattern control (V9-V12)
BLYNK_WRITE(V9) { handlePatternControl(param, RED_RUN); }
BLYNK_WRITE(V10) { handlePatternControl(param, GREEN_RUN); }
BLYNK_WRITE(V11) { handlePatternControl(param, BLUE_RUN); }
BLYNK_WRITE(V12) { handlePatternControl(param, RAINBOW_CHASE); }

void handlePatternControl(const BlynkParam &param, Pattern pattern) {
  if (param.asInt()) {
    rgbWidgetMode = false;
    runningEffect = false;
    currentPattern = pattern;
    patternPosition = 0;
    patternMillis = millis();
  } else if (currentPattern == pattern) {
    currentPattern = NONE;
    turnOffAllLEDs();
  }
}

// RGB Widget control (V13-V17)
BLYNK_WRITE(V13) { // COLOR datastream
  selectedColor.r = param[0].asInt();
  selectedColor.g = param[1].asInt();
  selectedColor.b = param[2].asInt();
 
  if (rgbWidgetMode && !runningEffect) {
    setLEDRGB(1, selectedColor);
    setLEDRGB(2, selectedColor);
    setLEDRGB(3, selectedColor);
  }
}

BLYNK_WRITE(V14) { // BUTTON datastream (power)
  bool state = param.asInt();
  if (state) {
    rgbWidgetMode = true;
    runningEffect = false;
    currentPattern = NONE;
    setLEDRGB(1, selectedColor);
    setLEDRGB(2, selectedColor);
    setLEDRGB(3, selectedColor);
  } else {
    turnOffAllLEDs();
  }
}

BLYNK_WRITE(V15) { // BRIGHTNESS datastream
  brightness = param.asInt();
  if (rgbWidgetMode && !runningEffect) {
    setLEDRGB(1, selectedColor);
    setLEDRGB(2, selectedColor);
    setLEDRGB(3, selectedColor);
  }
}

BLYNK_WRITE(V16) { // ANIMATION SPEED datastream
  // Invert the mapping so higher values = slower speed
  effectSpeed = map(param.asInt(), 0, 100, 5000, 100); // 100ms to 5000ms
}

BLYNK_WRITE(V17) { // EFFECT TOGGLE
  bool state = param.asInt();
  if (state) {
    rgbWidgetMode = true;
    currentPattern = NONE;
    runningEffect = true;
    currentRunningLED = 1;
    effectMillis = millis();
  } else {
    runningEffect = false;
    if (rgbWidgetMode) {
      setLEDRGB(1, selectedColor);
      setLEDRGB(2, selectedColor);
      setLEDRGB(3, selectedColor);
    }
  }
}

void setup() {
  // Initialize all LED pins
  pinMode(ledPin11, OUTPUT);
  pinMode(ledPin12, OUTPUT);
  pinMode(ledPin13, OUTPUT);
  pinMode(ledPin21, OUTPUT);
  pinMode(ledPin22, OUTPUT);
  pinMode(ledPin23, OUTPUT);
  pinMode(ledPin31, OUTPUT);
  pinMode(ledPin32, OUTPUT);
  pinMode(ledPin33, OUTPUT);
 
  // Start with all LEDs off
  turnOffAllLEDs();
 
  // Connect to Blynk
  Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
}

void loop() {
  Blynk.run();
  updateEffects();
}


Blynk Setup

Below are the Blynk configurations and setup.

 

 

Video Demonstration

Conclusion

This project successfully demonstrates how low-cost microcontrollers can achieve professional-grade lighting effects. Its modular design allows easy adaptation to art installations, stage lighting, or smart home systems, while the Blynk platform eliminates complex app development. Future iterations could integrate machine learning for adaptive color schemes based on room occupancy or audio input.

References

  • How to set up the new Blynk app step by step | Nodemcu ESP8266 with Blynk app
  • How to Setup and Program NodeMCU ESP8266–Complete Guide

 

BlynkControl lightEsp8266LedcontrolLight sensorLight showNodemcuRgb

Leave a comment

All comments are moderated before being published