ESP8266 + WS2812B = cool desk lamp

I had 2m leftover of ws2812b from my drones and I decide to make use of it as kinda cool led lighting for my desk. Anyway everything works, you can select few effects that come with adafruit ws2812b neopixel lib. Naming convention might be slightly messy in few places however project was finished initially in 1hour and wasn’t meant to be released elsewhere, therefore it wasn’t my concern. There might be few bugs here and there therefore report them, however in general code works. You can connect few ESPs with LED sets to the same token. Just change LED_SET define so each ESP has its unique LED_SET unless you want them to do exactly the same stuff. I use my custom ESP board that has built in LEDs so in your case you can get around somehow and change LED0 and LED1 pins.

Anyway apart from that everything should be fine and ready to play with - enjoy.

This is pretty much 15 min project if you replicate it do it:P

#define BLYNK_PRINT Serial    // Comment this out to disable prints and save space
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <Adafruit_NeoPixel.h>
#include <TimeLib.h>
#include <WidgetRTC.h>

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "well its a secret";

//Global variables
//
bool leds_enable;
bool blynk_connection;
bool change;
uint8_t red, green, blue, effect, led_speed;
float brightness = 1.0;
bool autoLED = false;
bool autoTime = false;
bool syncOnChange = false;

//WS2812B Config
//
#define PIXEL_PIN   14    // Digital IO pin connected to the NeoPixels.
#define PIXEL_COUNT 16    // Pixels Count

//Config leds used to display connection status
//LED0 is red
//LED1 is green
//If you don want to use remove any refrences in the code
//
#define LED0 13 //RED
#define LED1 4  //GREEN

//For multiple config
//
#define LED_SET 2
int currentLedSet = 0; // if not using multiple LED sets please set to LED_SET

Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);
WidgetLCD lcd(V0);
WidgetRTC rtc;

BLYNK_ATTACH_WIDGET(rtc, V7);

///Prototypes so some ArduinoIDEs wont cri
void leds_off();
void leds_on();
void colorWipe(uint32_t c, uint8_t wait);
void rainbow(uint8_t wait);
void rainbowCycle(uint8_t wait);
void theaterChase(uint32_t c, uint8_t wait);
void theaterChaseRainbow(uint8_t wait);
uint32_t Wheel(byte WheelPos);


void setup()
{
  led_speed = 0;
  red = 255;
  green = 255;
  blue = 255;
  leds_enable = true;
  pinMode(LED0, OUTPUT);
  pinMode(LED1, OUTPUT);
  digitalWrite(LED1, HIGH);
  digitalWrite(LED0, HIGH);
  Serial.begin(115200);
  Blynk.begin(auth, "gcwifi", "global82");
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  Serial.print("Connecting");
  while (Blynk.connect() == false) {
// Wait until connected
Serial.print(".");
delay(100);
  }
  Serial.println();
  Blynk.syncAll();
  rtc.begin();
  lcd.clear();
  lcd.print(0, 1, "Welcome Chris!");
}

BLYNK_WRITE(V1) {
  if (currentLedSet == LED_SET) {
leds_enable = param.asInt();
change = true;
if (leds_enable) {
  Blynk.virtualWrite(8, 0);
  autoLED = false;
}
  }
}

BLYNK_WRITE(V2) {
  if (currentLedSet == LED_SET) {
brightness = (float)param.asInt()/100;
  }
}

BLYNK_WRITE(V3) {
  if (currentLedSet == LED_SET) {
green = param.asInt();
change = true;
  }
}

BLYNK_WRITE(V4) {
  if (currentLedSet == LED_SET) {
red = param.asInt();
change = true;
  }
}

BLYNK_WRITE(V5) {
  if (currentLedSet == LED_SET) {
blue = param.asInt();
change = true;
  }
}

BLYNK_WRITE(V6) {
  if (currentLedSet == LED_SET) {
led_speed = param.asInt();
  }
}

BLYNK_WRITE(V8) {
  if (currentLedSet == LED_SET) {
autoLED = param.asInt();
if (autoLED) {
  Blynk.virtualWrite(1, 0);
  leds_enable = false;
}
  }
}

BLYNK_WRITE(V9) {
  if (currentLedSet == LED_SET) {
effect = param.asInt();
change = true;
lcd.clear();
switch (effect) {
  case 0:
    lcd.print(0, 0, "LEDS OFF");
    break;
  case 1:
    lcd.print(0, 0, "LEDS ON");
    break;
  case 2:
    lcd.print(0, 0, "Color Wipe");
    break;    
  case 3:
    lcd.print(0, 0, "Theater Chase");
    break;
  case 4:
    lcd.print(0, 0, "Theater Chase");
    lcd.print(0, 1, "Rainbow");
    break;
  case 5:
    lcd.print(0, 0, "Rainbow");
    break;
  case 6:
    lcd.print(0, 0, "Rainbow Cycle");
    break;
}
  }
}

BLYNK_READ(V10) {
  if (currentLedSet == LED_SET) {
String timeString = String(hour()) + ":" + String(minute()) + ":" +  String(second());
Blynk.virtualWrite(10, timeString);
  }
}


BLYNK_WRITE(V11) {
  autoTime = param.asInt();
  (autoTime) ? Blynk.virtualWrite(12, 255) : Blynk.virtualWrite(12, 0);
}

BLYNK_WRITE(V13) {
  if (currentLedSet != LED_SET) syncOnChange = true;
  currentLedSet = param.asInt();
}

void loop()
{
  if (syncOnChange) {
Blynk.syncAll();
syncOnChange = false;
  }
  change = false;
  if (Blynk.connected()) {
digitalWrite(LED1, HIGH);
digitalWrite(LED0, LOW);
  }
  else {
digitalWrite(LED0, HIGH);
digitalWrite(LED1, LOW);
  }
  Blynk.run();
  if (leds_enable) {
switch (effect) {
  case 0:
    leds_off();
    break;
  case 1:
    leds_on();
    break;
  case 2:
    colorWipe(strip.Color(brightness*(float)red, brightness*(float)green, brightness*(float)blue), led_speed);
    break;
  case 3:
    theaterChase(strip.Color(brightness*(float)red, brightness*(float)green, brightness*(float)blue), led_speed);
    break;
  case 4:
    theaterChaseRainbow(led_speed);
    break;
  case 5:
    rainbow(led_speed);
    break;
  case 6:
    rainbowCycle(led_speed);
    break;
}
  }
  else {
leds_off();
  }
  if (autoLED) {
if (autoTime) {
  leds_enable = true;
} else {
  leds_enable = false;
}
  }
}

////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////

void leds_off() {
  for (int i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, strip.Color(0, 0, 0));
  }
  strip.show();
  delay(20);
}

void leds_on() {
  for (int i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, strip.Color(brightness*(float)red, brightness*(float)green, brightness*(float)blue));
  }
  strip.show();
  delay(20);
}

/////////////////////////////////////////////////////////////////////////
//
//Any functions from now on are from Adafruit library with little mods.
//
/////////////////////////////////////////////////////////////////////////

// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
  delay(wait);
  leds_off();
  for(uint16_t i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, c);
strip.show();
delay(wait);
Blynk.run();
if (change) {return;}
  }
  delay(wait);
  leds_off();
  delay(wait);
  for(int i=strip.numPixels(); i>=0; i--) {
strip.setPixelColor(i, c);
strip.show();
delay(wait);
Blynk.run();
if (change) {return;}
  }
  return;
}

void rainbow(uint8_t wait) {
  uint16_t i, j;

  for(j=0; j<256; j++) {
for(i=0; i<strip.numPixels(); i++) {
  strip.setPixelColor(i, Wheel((i+j) & 255));
}
strip.show();
delay(wait);
Blynk.run();
if (change) {return;}
  }
}

// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
  uint16_t i, j;

  for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
for(i=0; i< strip.numPixels(); i++) {
  strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
}
strip.show();
delay(wait);
Blynk.run();
if (change) {return;}
  }
}

//Theatre-style crawling lights.
void theaterChase(uint32_t c, uint8_t wait) {
  for (int j=0; j<10; j++) {  //do 10 cycles of chasing
for (int q=0; q < 3; q++) {
  for (int i=0; i < strip.numPixels(); i=i+3) {
    strip.setPixelColor(i+q, c);    //turn every third pixel on
  }
  strip.show();

  delay(wait);
  Blynk.run();
  if (change) {return;}
  for (int i=0; i < strip.numPixels(); i=i+3) {
    strip.setPixelColor(i+q, 0);        //turn every third pixel off
  }
}
  }
}

//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow(uint8_t wait) {
  for (int j=0; j < 256; j++) {     // cycle all 256 colors in the wheel
for (int q=0; q < 3; q++) {
  for (int i=0; i < strip.numPixels(); i=i+3) {
    strip.setPixelColor(i+q, Wheel( (i+j) % 255));    //turn every third pixel on
  }
  strip.show();

  delay(wait);
  Blynk.run();
  if (change) {return;}
  for (int i=0; i < strip.numPixels(); i=i+3) {
    strip.setPixelColor(i+q, 0);        //turn every third pixel off
  }
}
  }
}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) {
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if(WheelPos < 170) {
WheelPos -= 85;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

And QR code for rest of the stuff:

8 Likes

Great stuff! Thanks for sharing.

You need to recharge your phone asap! :slight_smile:

2 Likes

great will try my own

Thanks, I was after something to drive some led strips and here it is.

My compiler had issues with this;

  delay(wait);
  for(uint16_t i=strip.numPixels(); i>=0; i--) {
    strip.setPixelColor(i, c);
    strip.show();

It doesn’t believe an unsigned number can be less than zero, so it just got stuck in an infinite loop here, I had to change ‘i’ to an ordinary int.

Unsigned cant be less than 0 It kinda doesnt make sense to use signed int with number of leds cause it always should be more than 0. But I actually didn’t check how this was declared in library

Thanks, but I wasn’t after confirmation or explanation, I was just letting you know of a bug.

Inside library that I have this function (numPixels) is declared so it returns uint16_t you might have different library or something. In my case it is not a bug, in general it is not a bug as number of Pixels wont be ever less than 0.

Cool, so your say this line;

for(uint16_t i=strip.numPixels(); i>=0; i–) {

Will be able to decrement I to below zero, instead of 65535, and so it will be able to exit the for loop.

There is no problem then.

1 Like

It should be i>0 only true. Though why would your compiler throw an error witht that… Usually it doesn’t detect this kind of stuff

Doesn’t setting it to i>0 stop it from reaching the last (first) pixel.

Yeap it will sadly stay off, minute of silence for him. I’ll change it.

My brain refuses to work properly thinking about tomorrow exam…

I’m getting this error with the given code or anything with WS2812B + ESP8266 + Blynk

`Arduino: 1.6.7 (Windows 10), Board: “NodeMCU 1.0 (ESP-12E Module), 160 MHz, 115200, 4M (3M SPIFFS)”

C:\Users\Vibhor\Documents\Arduino\sketch_may11b\sketch_may11b.ino: In function ‘void loop()’:

sketch_may11b:198: error: ‘leds_off’ was not declared in this scope

     leds_off();

              ^

sketch_may11b:201: error: ‘leds_on’ was not declared in this scope

     leds_on();

             ^

sketch_may11b:204: error: ‘colorWipe’ was not declared in this scope

     colorWipe(strip.Color(brightness*(float)red, brightness*(float)green, brightness*(float)blue), led_speed);

                                                                                                             ^

sketch_may11b:207: error: ‘theaterChase’ was not declared in this scope

     theaterChase(strip.Color(brightness*(float)red, brightness*(float)green, brightness*(float)blue), led_speed);

                                                                                                                ^

sketch_may11b:210: error: ‘theaterChaseRainbow’ was not declared in this scope

     theaterChaseRainbow(led_speed);

                                  ^

sketch_may11b:213: error: ‘rainbow’ was not declared in this scope

     rainbow(led_speed);

                      ^

sketch_may11b:216: error: ‘rainbowCycle’ was not declared in this scope

     rainbowCycle(led_speed);

                           ^

sketch_may11b:221: error: ‘leds_off’ was not declared in this scope

 leds_off();

          ^

C:\Users\Vibhor\Documents\Arduino\sketch_may11b\sketch_may11b.ino: In function ‘void rainbow(uint8_t)’:

sketch_may11b:287: error: ‘Wheel’ was not declared in this scope

   strip.setPixelColor(i, Wheel((i+j) & 255));

                                           ^

C:\Users\Vibhor\Documents\Arduino\sketch_may11b\sketch_may11b.ino: In function ‘void rainbowCycle(uint8_t)’:

sketch_may11b:302: error: ‘Wheel’ was not declared in this scope

   strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));

                                                                         ^

C:\Users\Vibhor\Documents\Arduino\sketch_may11b\sketch_may11b.ino: In function ‘void theaterChaseRainbow(uint8_t)’:

sketch_may11b:335: error: ‘Wheel’ was not declared in this scope

     strip.setPixelColor(i+q, Wheel( (i+j) % 255));    //turn every third pixel on

                                                ^

exit status 1
‘leds_off’ was not declared in this scope
`

try it now should be fine, I mean copy the code from first edited post

great job,thanks for sharing , but now i want to have a try too , but i have sk6812 led , i don’t know if it can work or not on same code

1 Like

Looks like it’s pretty much the same as ws2812, if you have addition of white led you would have to alter the code to send 32bit data instead of traditional 24bit.

Great job.
Well done.
I build it my own and it works great.
It is a good example to learn how to do.
The LED_SET is a good idea .
Does it realy work with different ESP8266 sharing the same token ?

Yep it works with the same token, as long as nothing changed on blynk backend side, and multiple devices connections are allowed to the same token:)

Getting this error

Arduino: 1.6.12 (Windows 10), Board: “NodeMCU 1.0 (ESP-12E Module), 80 MHz, 115200, 4M (3M SPIFFS)”

sketch\ws2812b.ino.cpp.o: In function `BlynkWifi::connectWiFi(char const*, char const*)’:

C:\Users\Vishal\Documents\Arduino\libraries\Blynk\src/BlynkSimpleEsp8266.h:44: undefined reference to `setTime(long)’

sketch\ws2812b.ino.cpp.o: In function `BlynkParam::asLong() const’:

C:\Users\Vishal\Documents\Arduino\libraries\Blynk\src/BlynkSimpleEsp8266.h:47: undefined reference to `setTime(long)’

sketch\ws2812b.ino.cpp.o: In function `syncVirtual’:

C:\Users\Vishal\Documents\Arduino\libraries\Blynk\src/Blynk/BlynkApi.h:129: undefined reference to `hour()’

C:\Users\Vishal\Documents\Arduino\libraries\Blynk\src/Blynk/BlynkApi.h:129: undefined reference to `minute()’

sketch\ws2812b.ino.cpp.o: In function `WidgetRTC::requestTimeSync()’:

C:\Users\Vishal\Documents\Arduino\libraries\Blynk\src/WidgetRTC.h:39: undefined reference to `second()’

sketch\ws2812b.ino.cpp.o:(.text.BlynkWidgetRead10+0x30): undefined reference to `hour()’

sketch\ws2812b.ino.cpp.o:(.text.BlynkWidgetRead10+0x5e): undefined reference to `minute()’

sketch\ws2812b.ino.cpp.o: In function `BlynkWidgetRead10’:

C:\Users\Vishal\Documents\Arduino\ws2812b/ws2812b.ino:172: undefined reference to `second()’

sketch\ws2812b.ino.cpp.o:(.text.setup+0x2c): undefined reference to `setSyncProvider(long (*)())’

sketch\ws2812b.ino.cpp.o: In function `setup’:

C:\Users\Vishal\Documents\Arduino\ws2812b/ws2812b.ino:68: undefined reference to `setSyncProvider(long (*)())’

collect2.exe: error: ld returned 1 exit status

exit status 1
Error compiling for board NodeMCU 1.0 (ESP-12E Module).

This report would have more information with
“Show verbose output during compilation”
option enabled in File -> Preferences.

@Androidbean i have the same issue as you, did you resolve this issue? if so can you let me know how?

Hello techno friends, yes I got the same mistake. Did anybody solve it? if so, please can you share it?

Thanks a lot in advance