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.
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 ¶m, 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.



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.