How to build a WS2812B LED strip with ESP8266 NodeMCU?

Hello everyone!

I’ve been searching through the forum and all over the internet for infos on building a LED lamp controlled by openHAB. It has been really hard to understand the whole concept because there is not many exemples on doing that with a WS2812b led strip. I’m not a programer by any means but I do understand the basics.

Is there an exemple/tutorial that follow or modify to get started? I want to build my own devices: smartplugs, LED lamps, etc.

I want to use an ESP8266 NodeMCU and WS2812b because I have plenty of those lying around.

Anyone has a clue of where I could find this info?

Thanks

JD

add here the code from the mosquito example
Pay attention to the peculiarity of this library, the tape can be divided into sectors (up to 10), it is very convenient!
UPD:
there is a firmware, for other purposes
with WS2812 I did not try it, but in the description of the commands there is a mention of these LEDs

if interested, I can give an example
UPD:
fast, dirty code, I think it will start;)
turn on, turn off, change the mode, ota (fill in your access point and mosquito credentials and the number of LEDs in the tape and the pin number to which the LED ribbon is connected):


#include <WS2812FX.h>
#include <ArduinoOTA.h>
#include <PubSubClient.h>
WiFiClient eClient;

#define mqtt_server     "192.168.1.14"
#define mqtt_port       1983
#define mqtt_client     "ws2812"
#define mqtt_user       "MQTT-login"
#define mqtt_password   "MQTT-password"
#define will_topic      "state/ws2812/LWT"
#define will_message    "Offline"
#define lwt_msg         "Online"
#define subscribe_topic "cmd/ws2812/#"
#define will_QoS        0
#define will_retain     true

#define LED_PIN         12
#define LED_COUNT       140
#define WIFI_SSID       "myAP"
#define WIFI_PASSWORD   "pin-ap"
#define host_name       "led-fx"

int fx_mode = 7;

unsigned long lastTime = millis();

WS2812FX ws2812fx = WS2812FX(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);

void callback(char*topic, byte* payload, unsigned int length);
PubSubClient client(mqtt_server, mqtt_port, callback, eClient);

void reconnect() {
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    if (client.connect(mqtt_client, mqtt_user, mqtt_password, will_topic, will_QoS, will_retain, will_message)) {
      Serial.println("connected");
      client.publish(will_topic, lwt_msg, will_retain);
      client.subscribe(subscribe_topic);
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      delay(5000);
    }
  }
}

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  String mqtt_data = "";
  for (int i = 0; i < length; i++) {
    mqtt_data += (char)payload[i];
  }
  Serial.println(mqtt_data);

  if (mqtt_data == "ON") {
    ws2812fx.start();
  } else if (mqtt_data == "OFF") {
    ws2812fx.stop();
  } else {
    fx_mode = mqtt_data.toInt();
    ws2812fx.setSegment(0, 0, LED_COUNT - 1, fx_mode, (const uint32_t[]) {0xff0000, 0x000000, 0x000000}, 240, false);
  }
}

void setup() {
  Serial.begin(115200);
  Serial.println("\r\n");

  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  WiFi.hostname(host_name);
  WiFi.mode(WIFI_STA);

  Serial.print("Connecting to " WIFI_SSID);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.print("\nServer IP is ");
  Serial.println(WiFi.localIP());

  ArduinoOTA.setHostname(host_name);
  ArduinoOTA.onStart([]() {
    Serial.println("OTA start");
  });
  ArduinoOTA.onEnd([]() {
    Serial.println("\nOTA end");
  });
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
  });
  ArduinoOTA.onError([](ota_error_t error) {
    Serial.printf("Error[%u]: ", error);
    if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
    else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
    else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
    else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
    else if (error == OTA_END_ERROR) Serial.println("End Failed");
  });
  ArduinoOTA.begin();

  ws2812fx.init();
  ws2812fx.setBrightness(127);

  ws2812fx.start();
  ws2812fx.setSegment(0, 0, LED_COUNT - 1, fx_mode, (const uint32_t[]) {0xff0000, 0x000000, 0x000000}, 240, false);
}

void loop() {

  if (!client.connected()) {
    reconnect();
  }
  client.loop();
  ArduinoOTA.handle();

  ws2812fx.service();
}
Switch  ws2812_power "power [%s]" { mqtt=">[mqtt-loc:cmd/ws2812/power:command:*:default]" }
Number  ws2812_mode  "mode [%d]"  { mqtt=">[mqtt-loc:cmd/ws2812/mode:command:*:default]" }
sitemap test label="ws2812"
{
	Frame {
        Switch		item=ws2812_power
        Setpoint	item=ws2812_mode step=1 minValue=0 maxValue=55
    }
}

Here is my example of how I did this.

It supports mqtt now.

1 Like

Thanks for the quick response guys!

I’ll look into that after work tonight!

JD

I can recommend the Fastled library (http://fastled.io/) for controlling pixel LEDs (including WS2812). Fastled has decent documentatiobn, and an active support group on Google+. I have a sketch running on an ESP8266 that uses a crude parser on mqtt commands, and I was able to wire it up to a Color item in OH2.0 really quickly. I’ll try to clean up the sketch a little bit and post it this evening.

Hi all, I am also interested in this. I have 100m ws2811(Identical ws2812?) laying around as well as nodemcu chip an arduina mega.

See this thread for more info

I’ll throw my design out there: https://www.thingiverse.com/thing:2690563 - it uses bruhAutomation’s MQTT LED controller code ( https://github.com/bkpsu/ESP-MQTT-JSON-Digital-LEDs ) with some minor mods I made to make it work with no flicker on the faster WS2812 chips (code changes and hookup explained on my Thingiverse page)

I also created a breakout board for the NodeMCU and an enclosure, to dress it all up and make it easier to assemble - I love the NodeMCUs and use them all over the house. Write up post:

2 Likes

Wow, this pretty much what I would like to do eventually. I found some cheap Ikea lamps that are pretty stylish. I would put one in every room. The lamp will be have a few RGB in it and home a few sensor so I could get some data for each room as well. I love what you did with your house.

Thanks for the share…I’m going to have a busy weekend!!!

JD

Glad you found it useful, and good idea on the lamps with embedded sensors! Keep that temp sensor far enough away from the bulb to prevent scary temperature readings, though! :smiley:

1 Like

Hi Bartus,

I’ve been looking closely at your Thingiverse page and I realized that I basically needed something like your LED controller module. Did you post it on Github by any chance? I just ordered a few OLED display to eventually reproduce your Kube project but it will take a while to get here.

Thanks and keep up the good work…

JD

@bartus I am trying to use your esp arduino code, however I get this error :

Arduino: 1.6.8 (Windows 7), Board: "NodeMCU 0.9 (ESP-12 Module), 80 MHz, Serial, 115200, 4M (3M SPIFFS)"

Build options changed, rebuilding all
In file included from C:\Users\kim\Documents\ArduinoCode\ESP-MQTT-JSON-Digital-LEDs-master\ESP_MQTT_Digital_LEDs\ESP_MQTT_Digital_LEDs.ino:26:0:

C:\Users\kim\Documents\Arduino\libraries\FastLED/FastLED.h:17:21: note: #pragma message: FastLED version 3.001.007

 #    pragma message "FastLED version 3.001.007"

                     ^

In file included from C:\Users\kim\Documents\Arduino\libraries\FastLED/FastLED.h:68:0,

                 from C:\Users\kim\Documents\ArduinoCode\ESP-MQTT-JSON-Digital-LEDs-master\ESP_MQTT_Digital_LEDs\ESP_MQTT_Digital_LEDs.ino:26:

C:\Users\kim\Documents\Arduino\libraries\FastLED/fastspi.h:110:23: note: #pragma message: No hardware SPI pins defined.  All SPI access will default to bitbanged output

 #      pragma message "No hardware SPI pins defined.  All SPI access will default to bitbanged output"

                       ^

C:\Users\kim\Documents\ArduinoCode\ESP-MQTT-JSON-Digital-LEDs-master\ESP_MQTT_Digital_LEDs\ESP_MQTT_Digital_LEDs.ino: In function 'void setup()':

ESP_MQTT_Digital_LEDs:184: error: 'setupStripedPalette' was not declared in this scope

   setupStripedPalette( CRGB::Red, CRGB::Red, CRGB::White, CRGB::White); //for CANDY CANE

                                                                      ^

ESP_MQTT_Digital_LEDs:187: error: 'setup_wifi' was not declared in this scope

   setup_wifi();

              ^

ESP_MQTT_Digital_LEDs:189: error: 'callback' was not declared in this scope

   client.setCallback(callback);

                      ^

C:\Users\kim\Documents\ArduinoCode\ESP-MQTT-JSON-Digital-LEDs-master\ESP_MQTT_Digital_LEDs\ESP_MQTT_Digital_LEDs.ino: In function 'void callback(char*, byte*, unsigned int)':

ESP_MQTT_Digital_LEDs:280: error: 'processJson' was not declared in this scope

   if (!processJson(message)) {

                           ^

ESP_MQTT_Digital_LEDs:302: error: 'sendState' was not declared in this scope

   sendState();

             ^

C:\Users\kim\Documents\ArduinoCode\ESP-MQTT-JSON-Digital-LEDs-master\ESP_MQTT_Digital_LEDs\ESP_MQTT_Digital_LEDs.ino: In function 'bool processJson(char*)':

ESP_MQTT_Digital_LEDs:388: error: 'MILLION' was not declared in this scope

       unsigned int kelvin  = MILLION / color_temp;

                              ^

ESP_MQTT_Digital_LEDs:390: error: 'temp2rgb' was not declared in this scope

       temp2rgb(kelvin);

                      ^

C:\Users\kim\Documents\ArduinoCode\ESP-MQTT-JSON-Digital-LEDs-master\ESP_MQTT_Digital_LEDs\ESP_MQTT_Digital_LEDs.ino: In function 'void reconnect()':

ESP_MQTT_Digital_LEDs:451: error: 'setColor' was not declared in this scope

       setColor(0, 0, 0);

                       ^

C:\Users\kim\Documents\ArduinoCode\ESP-MQTT-JSON-Digital-LEDs-master\ESP_MQTT_Digital_LEDs\ESP_MQTT_Digital_LEDs.ino: In function 'void loop()':

ESP_MQTT_Digital_LEDs:518: error: 'showleds' was not declared in this scope

     showleds();

              ^

ESP_MQTT_Digital_LEDs:532: error: 'showleds' was not declared in this scope

     showleds();

              ^

ESP_MQTT_Digital_LEDs:544: error: 'showleds' was not declared in this scope

     showleds();

              ^

ESP_MQTT_Digital_LEDs:556: error: 'showleds' was not declared in this scope

       showleds();

                ^

ESP_MQTT_Digital_LEDs:559: error: 'fadeall' was not declared in this scope

       fadeall();

               ^

ESP_MQTT_Digital_LEDs:567: error: 'showleds' was not declared in this scope

       showleds();

                ^

ESP_MQTT_Digital_LEDs:570: error: 'fadeall' was not declared in this scope

       fadeall();

               ^

ESP_MQTT_Digital_LEDs:590: error: 'showleds' was not declared in this scope

     showleds();

              ^

ESP_MQTT_Digital_LEDs:596: error: 'Fire2012WithPalette' was not declared in this scope

     Fire2012WithPalette();

                         ^

ESP_MQTT_Digital_LEDs:600: error: 'showleds' was not declared in this scope

     showleds();

              ^

ESP_MQTT_Digital_LEDs:609: error: 'addGlitterColor' was not declared in this scope

     addGlitterColor(80, realRed, realGreen, realBlue);

                                                     ^

ESP_MQTT_Digital_LEDs:613: error: 'showleds' was not declared in this scope

     showleds();

              ^

ESP_MQTT_Digital_LEDs:626: error: 'showleds' was not declared in this scope

     showleds();

              ^

ESP_MQTT_Digital_LEDs:643: error: 'showleds' was not declared in this scope

       showleds();    // Show a section of LED's

                ^

ESP_MQTT_Digital_LEDs:654: error: 'showleds' was not declared in this scope

     showleds();

              ^

ESP_MQTT_Digital_LEDs:672: error: 'showleds' was not declared in this scope

     showleds();

              ^

ESP_MQTT_Digital_LEDs:698: error: 'showleds' was not declared in this scope

     showleds();

              ^

ESP_MQTT_Digital_LEDs:710: error: 'showleds' was not declared in this scope

     showleds();

              ^

ESP_MQTT_Digital_LEDs:719: error: 'addGlitter' was not declared in this scope

     addGlitter(80);

                  ^

ESP_MQTT_Digital_LEDs:723: error: 'showleds' was not declared in this scope

     showleds();

              ^

ESP_MQTT_Digital_LEDs:735: error: 'showleds' was not declared in this scope

     showleds();

              ^

ESP_MQTT_Digital_LEDs:763: error: 'showleds' was not declared in this scope

     showleds();

              ^

ESP_MQTT_Digital_LEDs:785: error: 'showleds' was not declared in this scope

       showleds();

                ^

ESP_MQTT_Digital_LEDs:813: error: 'showleds' was not declared in this scope

       showleds();

                ^

ESP_MQTT_Digital_LEDs:868: error: 'calculateStep' was not declared in this scope

       stepR = calculateStep(redVal, realRed);

                                            ^

ESP_MQTT_Digital_LEDs:883: error: 'calculateVal' was not declared in this scope

         redVal = calculateVal(stepR, redVal, loopCount);

                                                       ^

exit status 1
'setupStripedPalette' was not declared in this scope

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

How did you get it to work?

@jdenommee I haven’t posted the code to Github yet, but I will take care of that this weekend. It’s not much different from bruhAutomation’s base version, I only added a couple of my own effects and fixed some flickering issues with my LED strips. Anyway, I’ll update the Thingiverse page with the Github link once I get that posted.

For the Kube, since I need to make a few more of them, I’ll try to put together a little video how-to, including the hardware (OLED, motion sensor hookup) as well as software (configuring the Github code). I’ll let you know when I post it up.

Thanks for the kind words!

@skatun , Hmm, two things I can think of:

  1. Are you sure you have the latest version of the FastLED library installed in your Arduino environment? Check Library Manager and see which version of FastLED you have (update to the latest).

  2. You’re using the code directly from burhAutomation’s Github repository, correct? There may have been some breaking changes, I haven’t pulled the latest from it since I did this a few months ago. Let me put my version of the code up on my GitHub (it’ll include the things I mentioned in my response to @jdenommee above), and try that version.

We’ll get your controller working!

1 Like

Thanks a bunch! This has become my new obsession! If I could setup these lights once and never climb up a ladder ever, that would be amazing!

JD

@jdenommee and @skatun ; please check out https://github.com/bkpsu/ESP-MQTT-JSON-Digital-LEDs where I posted my custom fork of bruhAutomation’s code, including a few of my own effects and the ability to group multiple strips into a single MQTT topic. I’m still working on some how-to videos, but I figured getting the code up would get you started.

Thanks-a-million Bartus!

Have a great weekend!

JD

I have the sk6812 led strip,seems the same as the ws2812b,
so it can use the same code ws2812b.

Can @bartus please share your items and sitemap of how you have implemented your nice neopixel in Openhab.

Tip to everyone using the arduino code from @bartus git, is that they need to remove the original file and only keep ESP_MQTT_Digital_LEDs/ESP_MQTT_Digital_LEDs_w_JSON.ino in the folder.

@skatun sure thing - here is a basic set of items/sitemap/rules/transforms for 1 strip

ledstrip.items:

    String LEDStrip_FF_Office_Window "Office String" {mqtt=">[broker:home/FF_Office_Window/set:state:*:default]"}
    Switch LEDStrip_FF_Office_Window_Power "Office Power" (Status){mqtt=">[broker:home/FF_Office_Window/set:command:*:MAP(LEDStripEffectJSON.map)]"}
    Number LEDStrip_FF_Office_Window_FX "Office Fx" (Status){mqtt=">[broker:home/FF_Office_Window/set:command:*:MAP(LEDStripEffectJSON.map)]"}
    Color LEDStrip_FF_Office_Window_Color "Office Color"	<rgb>	(Status)
    Number LEDStrip_FF_Office_Window_Speed "Office Speed [%.0f]"		(Status)
    Number LEDStrip_FF_Office_Window_Intensity "Office Intensity [%d]" (Status)

.sitemap:

				Switch item=LEDStrip_FF_Office_Window_Power
				Selection item=LEDStrip_FF_Office_Window_FX mappings=[1="BPM",2="Noise",3="Fire",4="Rainbow",5="Twinkle",6="Glitter",7="Solid",8="Sinelon",9="Juggle",10="Confetti",11="Dots",12="Lightning",13="Candy Cane",14="Cyclon Rainbow",15="Ripple",16="Christmas Alternate",17="Police All",18="Police One",19="Random Stars",20="Sine Hue"] 
				Colorpicker item=LEDStrip_FF_Office_Window_Color
				Setpoint item=LEDStrip_FF_Office_Window_Speed minValue=5 maxValue=240 step=5
				Setpoint item=LEDStrip_FF_Office_Window_Intensity minValue=0 maxValue=255 step=16

.rules:

rule "LED Strip Office Window JSON Color"
when Item LEDStrip_FF_Office_Window_Color received update
then LEDStrip_FF_Office_Window.sendCommand("{\"color\": {" + 
		"\"r\": " + (LEDStrip_FF_Office_Window_Color.state as HSBType).red + "," +
		"\"g\": " + (LEDStrip_FF_Office_Window_Color.state as HSBType).green + "," +
		"\"b\": " + (LEDStrip_FF_Office_Window_Color.state as HSBType).blue + "}}") end

rule "LED Strip Office Window JSON Speed"
when Item LEDStrip_FF_Office_Window_Speed received update
then LEDStrip_FF_Office_Window.sendCommand("{\"transition\": \"" + LEDStrip_FF_Office_Window_Speed.state + "\"}") end

rule "LED Strip Office Window JSON Intensity"
when Item LEDStrip_FF_Office_Window_Intensity received update
then LEDStrip_FF_Office_Window.sendCommand("{\"brightness\":" + LEDStrip_FF_Office_Window_Intensity.state + "}") end

LEDStripEffectJSON.map:

1={"effect":"bpm"}
2={"effect":"noise"}
3={"effect":"fire"}
4={"effect":"rainbow"}
5={"effect":"twinkle"}
6={"effect":"glitter"}
7={"effect":"solid"}
8={"effect":"sinelon"}
9={"effect":"juggle"}
10={"effect":"confetti"}
11={"effect":"dots"}
12={"effect":"lightning"}
13={"effect":"candy cane"}
14={"effect":"cyclon rainbow"}
15={"effect":"ripple"}
16={"effect":"christmas alternate"}
17={"effect":"police all"}
18={"effect":"police one"}
19={"effect":"random stars"}
20={"effect":"sine hue"}
ON={"state":"ON"}
OFF={"state":"OFF"}

I’m working on some how-to videos, but those may take a while still :slight_smile:

Enjoy!