Neopixels/RGB LED example

I read a lot of posts on people having trouble with controlling neopixels or RGB LED’s from OpenHab so for beginners ( I am still a beginner too) I will include some simple files here of a working system.
Using a Colorpicker
The sitemap and items file are fairly easy, just using a Colorpicker. I will describe some additions, but the basic files are quite simple

itemsfile

Group All
Color RGBLed "NeoPixel Color" (All)
String RGBLedColor (All) {mqtt=">[mosquitto:OpenHab/RGB:command:*:default]"}

There are 2 items here. One item contains the HSB value, coming from the colorpicker, The other item, that will not be visible on the screen, will contain the calculated RGB code that will be sent out via MQTT.

sitemap file is as follows:

sitemap NeoPixel label="NeoPixel"
{
	Frame label="NeoPixel" {
		Colorpicker item=RGBLed icon="slider"
	}
}

The colorpicker sends an HSB (Hue, Saturation, Brightness) code, but that isnt anything a regular Neopixel LED or regular RGB LED can use, so I set up a rule that triggers on any change of the RGB item to change the HSB code into a regular RGB code. That RGBcode is joined in 1 string called ’ color’. The rule then assigns that ‘color’ string to a new item called “RGBLedColor”

rules file

import org.openhab.core.library.types.*

rule "Set HSB value of item RGBLed to RGB color value"
when
	Item RGBLed changed
then
	val hsbValue = RGBLed.state as HSBType

	val brightness = hsbValue.brightness.intValue 
	val redValue = ((((hsbValue.red.intValue * 255) / 100) *brightness) /100).toString
	val greenValue = ((((hsbValue.green.intValue * 255) / 100) *brightness) /100).toString
	val blueValue = ((((hsbValue.blue.intValue * 255) / 100) *brightness) /100).toString

	val color = redValue + "," + greenValue + "," + blueValue

	sendCommand( RGBLedColor, color)
end

//part of Neopixel conf files

On the receiving end, there is a Wemos D1 mini that controls a NeoPix strip. The ‘color’ string is split in its separate RGB values. As such it could also be used for an RGB LED or seperate Red, Green, Blue Led’s.
The code is reacting to one MQTT topic, basically switching the entire strip at one go in the desired color and brightness, but I added a structure catching some other MQTT topics that now go to empty routines but that could be used for patterns like a breathing light or a moving pattern. As illustration I added a simple red-blue pattern that responds to MQTT “OpenHab/RGB/scene” with payload “2” (Edit, new code now has 3 scenes built in, all with topic “OpenHab/RGB/scene” and payloads 1 to 3) I am using the broker name ‘mosquitto’, if your broker has a different name you needto modify that.

I have to say though that this is not the most efficient way of adding topics, but for beginners it is easiest to follow.
A much more efficient way is to keep the topics of one specified length with only say the last 2 or 3 characters defining the desired action and then only checking for those last characters. A good example of this is for instance in the gateway or sonoff code on https://github.com/computourist/ESP8266-MQTT-client. For readability sake however, in this example I have chosen to use a more traditional approch and as long as you just want to control some LEDs it is easier.

The ESP8266 code does send some information back: it returns the software version, the IP number and the RSSI.
With regard to the software version and IP number… if you have several ESP8266’s and or Arduino’s in your system, it is easy to lose track which one does what and with what software.

The ESP8266 code is OTA updateable
I have used a fork of the O’Leary PubSub library that makes it easier to send variables as the MQTT payload without having to resort to setting up buffer space and using c_string. Library is here: https://github.com/Imroy/pubsubclient.
If you already have the O’Leary PubSub library installed, you will need to put the library files in your sketch folder and change #include <PubSubClient.h> into #include “PubSubClient.h”

Sending predefined colors
If next to the Colorpicker you also want to be able to send predefined colors via a button, then you only need to add some lines in the items and sitemap file:

add to itemsfile:

    Switch NEO_RED	"Red"	<red> {mqtt=">[mosquitto:OpenHab/RGB:command:ON:255,0,0]"}
    Switch NEO_YELLOW	"Yellow"	<yellow>	{mqtt=">[mosquitto:OpenHab/RGB:command:ON:100,96,0]"}
    Switch NEO_BLUE	"Blue"	<darkblue>{mqtt=">[mosquitto:OpenHab/RGB:command:ON:0,0,255]"}

add to the sitemap:

Switch item=NEO_RED mappings=[ON="ON"]
Switch item=NEO_YELLOW mappings=[ON="ON"]
Switch item=NEO_BLUE mappings=[ON="ON"]

As it can be a bit of a bother to find and type all the codes for the colors you may want, I added for download some 160 predefined color settings to pick and add to your sitemap and itemsfile, including some simple icons. As these items already send an R,G,B, code they do not need the rulesfile, only the colorpicker does.

How about Sliders
Perhaps you do not want to use a colorpicker but just individual sliders for Red, Green and Blue.
That is quite easy too.
add the following to your itemsfile:

Dimmer NEO_SLIDERRED "Neopixel Red [%d %%]"  <red> {mqtt=">[mosquitto:OpenHab/RGB/RED:command:*:default]"}
Dimmer NEO_SLIDERGREEN "Neopixel Green [%d %%]" <green> {mqtt=">[mosquitto:OpenHab/RGB/GREEN:command:*:default]"}
Dimmer NEO_SLIDERBLUE "Neopixel Blue [%d %%]" <blue> {mqtt=">[mosquitto:OpenHab/RGB/BLUE:command:*:default]"}

and this to your sitemap

Slider item=NEO_SLIDERRED 
Slider item=NEO_SLIDERGREEN
Slider item=NEO_SLIDERBLUE

Normally that would be enough already, but our ESP8266 program is expecting one input rather than seperate RGB inputs. That is because the colorpicker we used before sends one string of info.
Ofcourse we could add topics to the ESp8266 program to respond to individual RG and B values (and that is what the MQTT topics OpenHab/RGB/RED, OpenHab/RGB/GREEN, and OpenHab/RGB/Blue would be for), but it might be easier to combine those and send as one. For that we need a new rule.

add this to your rules file:

rule "Send  RGB items from slider"
when
Item NEO_SLIDERRED changed or
Item NEO_SLIDERGREEN changed or
Item NEO_SLIDERBLUE changed
then
val redValue=  Math::round(2.55* (NEO_SLIDERRED.state as DecimalType).intValue)
val greenValue=  Math::round(2.55* (NEO_SLIDERGREEN.state as DecimalType).intValue) //
val blueValue=  Math::round(2.55* (NEO_SLIDERBLUE.state as Number).intValue)
val color = redValue + "," + greenValue + "," + blueValue

	sendCommand( RGBLedColor, color)
end

While we are at it
If you want the Filename, IP number and RSSI to show up, add the following to your items file:

Number W_RSSI  "RSSI [%d dbm]" <signal>  {mqtt="<[mosquitto:home/nb/weer/RSSI:state:default]"}
String W_IP "IP [%s]" <network>   {mqtt="<[mosquitto:home/nb/weer/IP:state:default]"}
String W_version "Software versie [%s]" <version>  {mqtt="<[mosquitto:home/nb/weer/version:state:default]"}
String W_MAC "MAC [%s]" <mac> (Wweather) {mqtt="<[mosquitto:home/nb/weer/mac:state:default]"}
Number W_IP_Uptime "Uptime [%d min]" <clock> (Wweather) {mqtt="<[mosquitto:home/nb/weer/uptime:state:default]"}

and the following lines to your sitemap:

   Text item=W_RSSI
   Text item=W_IP
   Text item=W_version
   Text item=W_MAC
   Text item=W_IP_Uptime

download

Although I tried on a Wemos D1 mini, I presume this will also work perfectly on the ESP8266-01. Perhaps a great way to use those if you still have on your scrapheap as this is typically a minimal pin project.

The ESP8266 program
The Esp8266 program is rather self explanatory and going into it too deep might fall outside the openhab scope a bit, but in brief, you will find several ino files and a userconfig.h file. These all should be in the same directory and it is sufficient to open the NeopixelOpenhab_vx.ino file in your IDE. The other files will then open up too.
neopix7
You need to make a few modifications in the userdata.h file.


The essential changes are your password, your SSID and the address of your MQTT server. The other options are indeed ‘optional’, can leave them as is.
the Filename is sent back to openhab as an MQTT message, so in the future you will still know what file it was you put in your ESP8266. obviously you would need to fill out the correct filename. Maybe there is a possibility to automatically pull the filename from the system but if it is, then I haven’t found out about it yet

13 Likes

I did something similar and it’s a cool application. I implemented mine a little different though if anyone is interested.

I implemented mine with the Arduino bootloader on the ESP8266. And I just have one item:

Color       CounterLights               "Counter Lights"                                (Kitchen, Lights)           ["Lighting"]    {mqtt=">[HABroker:myhouse/kitchen/CounterLightsColor:command:*:${command}]"}

Then every time a color command comes in to openHAB (from the sitemap/alexa/google home/etc) it just gets forwarded to the ESP8266 via mqtt. Then I just use the FastLED library on the ESP8266. The nice thing about the FastLED library is it takes HSV values so it does the conversion and the color accuracy of their library is much better than I’ve found in anything else.

Just another option, there are lots of ways to accomplish the same thing. I’m happy to share the code for the ESP if anyone is interested.

Very interesting Matthew. Indeed many roads go to Rome. I know the FastLed library but have little experience with it. Though ‘my’ solution works for me I’d be very interested to see your code. Never too old to learn something new

I’ll post it tonight and you can take a look at it if you’d like. I love seeing how other people solve problems. It always gives me new things to learn and new tactics to solve things I’m working on. I’d really be interested in testing your solution beside mine and see who does color conversion the best (OpenHAB or FastLED). I’m a bit of a perfectionist so I always go for the solution that seems more accurate on the final result so I like to see who’s libraries get the best results.

The only down side to my solution is that my code isn’t easily OTA uneatable. I have to work out some bugs in the Arduino OTA setup.

Great.
With regard to perfection… I get you. However I must admit that in the actual color as shown on the NeoPixel, I dont always see clear difference between different colors. Maybe it is just a male thing to dont see 16 shades of green but just “green”

1 Like

Sorry for taking so long on this but here’s a link to my Arduino code. It’s not real clean yet, I’m still modifying and playing with things but take a look. I’m using something other than Neopixels for this project but that’s really easy to change without having to change the code.

Let me know what you think!

https://drive.google.com/drive/folders/0B02x81-uvEZLekgxUHdHRWFhMVE?usp=sharing

No problem. Will have a look

Seems like quite a handy Library with lots of routines built in to work directly from HSB. Whether it gives a more accurate color I do not know.
Seems that the FastLed library gives less overhead than the Adafruit Neopixel library and is faster, or at least delivers more frames per second, but it is clearly a bit harder to use in the beginning.

Nevertheless it seems a better library and I understand that even Adafruit in their ‘Uberguide’ recommend it for more complicated situations.
With Regard to your code, it looks quite OK, do you have the OTA working now?

It shows up in the Arduino environment but every time I attempt to download new code I get an error. I don’t have the error message on hand since I’m traveling for work right now but maybe I can post it and see if you’ve gotten it before.

With regards to the FastLED library, I agree, it’s harder to get started with and it’s much more in depth, so sometimes figuring out the documentation is a little bit of a challenge. I honestly didn’t try the Adafruit library against the FastLED library but they both seem to work well. There were just some functions built into the FastLED library I wanted to take advantage of so that’s kind of why I went that way.

Understood.
OTA can be a bit fickle sometimes. On occasion I had to restart my IDE for it to work, other times it would take a while for the port to show up and I have one computer It just never works on.

I implement OTA all in a seperate file that I have in the same directory as my sketch and then I only have to add I think 2 or 3 lines in the main code for it to work.

I’d be happy to send you that code seperately, although it is already in the full file in the earlier downloadlink

@Kees_van_Gelder thanks for this post. I’m setting up a smart Night Light with multi sensors and a new pixel and your items and rule example help me out!

1 Like

I am happy you found it of help

I am trying to test out your arduino code but I get this error:

NeopixelOpenHab_v3:95: error: 'MQTT' does not name a type

 void callback(const MQTT::Publish& pub) {

                     ^

NeopixelOpenHab_v3:95: error: expected unqualified-id before '&' token

What am I missing?
Also you have 3 .ino files in the zip folder, which one to use?

I’ll dig through what you put up already and look for it. It may also be that I’m developing on a virtual machine so there may be conflicts there. But I’ll keep playing with it and see what I can get to work. In the meantime I’m occupied full time with finishing the Insteon setup and Nest setup. But I’ll post back if I add things to my program or find something that helps.

you might be using the wrong PubSub library. I was using the one form Imroy because that is more flexible in handling variables.


The program uses ALL the files. keep them in the same directory. The various files contain different procedures. That way it is easier to add or delete specific functionality
your IDE will look like this:
info

If you add the proper library locally, the library files will also show up there.

Make sure to use #include <PubSubClient.h> for a shared library and #include “PubSubClient.h” for a local library

Great, will be looking out for that

Kees i dont know what i am doing wrong. ik cant get it to work.
The esp is load with te code. it is connect with the wifi.
but i cant find it in openhab. i am trying for 3 weeks now.
i think its something simple, i cant figger out.

sorry for my bad Englisch. my Dutch is mutch better.

You say the esp code is loaded, the esp connected but you cant find it in openhab.
Did you add the items en sitemap to your openhab?
It isn’t a matter of “I can’t find it in openhab” You have to put it there yourself and if you put it there, you know where to find it"

Je zegt dat je de esp geladen hebt met de code en dat de esp met de wifi is verbonden, maar heb je ook de items en de sitemap toegevoegd aan openhab? Het kan niet zo zijn dat je het ‘niet kunt vinden’ Je moet het zelf in openhab zetten en als je dat hebt gedaan dan weet je het ook te vinden

Items, rules and sitemap is in openhab. i copy and paste all the lines in too it.
i think thats not the isseu.
String topic = “OpenHab/RGB/#”;
I Think here is te problem, every option i can think off i attempt.
can you explain "OpenHab/RGB/#"
i Know if you change this line in your IDE, you have to change it in your items.
But i dont know now “???/???/#”

Items rules en sitemap is in openhab, geknipt en geplakt zoals hier boven staat
zelf denk ik dat mijn probleem hier in zit.
String topic = “OpenHab/RGB/#”;
Ik heb hier alles al geprobeerd om in te vullen.
Kun je me uitleggen wat "hier / hier / # moet komen te staan

if that is not the issue, please expand on what you mean 'cant find it in openhab’
The String topic = “OpenHab/RGB/#” is the MQTT string that the ESP8266 is listening too
The ‘#’ is a catchall and should not be replaced.

So if for instance you decide that you want openhab to send various MQTT strings that all have in common say “home/RGB” then your catchall in the IDE will be “home/RGB/#”

Als dat niet de issue is begrijp ik niet echt wat je bedoeld met ‘kan het niet vinden in openhab’
De String topic = “OpenHab/RGB/#” is de MQTT string waar de 8266 naar luistert. De ‘#’ is een wildcard en moet niet vervangen worden.
Dus als je bijvoorbeeld wilt dat openhab verschillende strings stuurt naar je ESP8266 die allemaal home/RGB als groottste gemene deler hebben dan zorg je met "home/RGB/#’ dat je ESp8266 naar al die commandos luistert