Controlling RGBW LED strip from Node-RED
Tags: arduino, rgb, rgbw, raspberrypi
Published: 2021-04-19 22:28:33

Considering the discreet style I usually utilize at home, I would have never imagined myself installing some RGB LED strips for lighting, but this is exactly what I recently did.

There is a wooden skirting board on the wall of my living room and for some reason, I got stuck to the idea of attaching lighting on top of that.
![The skirting board](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d5wk1sf4woka2nevkhhj.jpg)

I knew from the very beginning that at minimum the LED strip I was adding there had to have addressable warm white LEDs. Why addressable? Because I am a developer and just changing the brightness by applying different voltage does not sound anywhere as fun as being able to tweak each LED by code individually. But to make it even more fun, why not add the RGB capability to the mix :thinking:

## RGBW - easy peasy to find one! No?

So there I was, searching for an addressable LED strip that would have RGB + warm white and was using 12V power. 12V was needed because the whole line is about 15m in length and I do not want to have multiple power sources nor additional wiring for injecting power to the middle of the strip.
Although there are many RGB LED strips available, it took me a while to find the right strip. Most of them are either not addressable at all, or when addressable, using 5V for power. And you might find one that is 12V addressable RGB, but it probably lacks the separate warm white output. By the way, there is the need to have a separate warm white light emitter because just mixing up RGB to get a good warm white simply does not work.

Anyways, eventually, I did find the right strips I needed from Aliexpress :tada:. They are 12V RGB + warm white driven by an SK6812 chip, 60 LEDs per meter, no dust/water resistance of course.

## The aluminum rail

At first, I bought an uncolored aluminum rail for the LEDs, and it looked nice, but then realized that the white-colored rail would give a stealthier look. That was a really good decision to switch to white rails.
Here is a picture of the cutting process:
![The cutting](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bkivjshk9nh4a7xnf1l9.jpg)

If you're after a picture where the rail is attached on top of the skirting board, take a look at the previous picture - it is already on the picture :wink:
The rail got attached using mostly double-sided tape and a few screws here and there.

## Zigbee

I was more than sure of from the very beginning that I need to be able to control the LED strip from my home automation system which consists of a few [Node-RED](https://nodered.org/) instances running on top of [zigbee2mqtt](https://www.zigbee2mqtt.io/) inside a Raspberry Pi 4. As I was planning to install the controller for the LED strip to the other side of the room then the Raspberry is sitting anyways, I had in mind to transmit the commands over Zigbee as most of the other smart devices at my home are communicating with.

So I was researching standalone Zigbee controllers, Arduino Zigbee shields, XBee, ESP32, etc. But I did not come up with any good setup for what I was trying to achieve - build a device that would connect to my Zigbee network, take commands from there and be able to connect the RGBW LED strip. It all would be fairly simple to implement over Bluetooth or Wifi, but I had the urge to use Zigbee - and there are reasons for this :laughing:.

### Arduino + XBee
The most straight forward would probably have been to have an Arduino with a shield for XBee and an XBee module on top of that - but that option I did not like for multiple reasons:
* It would be physically a huge pile of boards
* I just do not like the way XBee boards are configured :see_no_evil: (you need to use a proprietary Windows software)
* Each board separately (Arduino, XBee) has the potential to drive the LED strip, but I still would have needed to have them both :shrug:
* How come this pile of boards will cost you about $100 while you can buy a well-built Zigbee device for $10 :roll_eyes:

### CC2530
There is a cheap Texas Instrument chip widely available that is made for Zigbee. It is trivial to burn onto that chip software that connects it to my Zigbee network as a router but would need some low-level C programming (compared to using an available library for Arduino) with proprietary tools to make it control the RGBW strip. I do not want to go down that rabbit hole either. It would be the right thing to do if I made this thing a product, but this time I wanted to just make my idea happen.

### CC2530 + Arduino
The combination of CC2530 for communicating over Zigbee plus Arduino that would control the LED strip and talk to CC2530 over a serial interface seems appealing. I must admit I did order the CC2530 in many forms, but as none of them physically easily plugged into Arduino and I had (still have) some bits missing in the puzzle of putting them together and exposing the right interface through Zigbee, I gave up before truly trying to make this happen.

### Microduino :thinking:
The best possible option I found from the market would have been [Microduino Module CoreRF](https://wiki.microduinoinc.com/Microduino-Module_CoreRF). In theory, it should support Zigbee and can easily use libraries built for Arduino. But there is some lack of information on how exactly to use this, with no recent updates it seems like a dead project, and I could not find it anywhere in stock.
Although visiting the page now when writing this very article, I did find a [Microduino Zigbee module](https://microduinoinc.com/product/zigbee-diy/) available in their web store. I will probably get myself one :sunglasses:

## No wireless - no problem

While being a little stuck with my progress to have a neat controller I could easily control the RGBW light strip with, I started to curve my living room around in a different way and realized I could wire it all together in a way that would bring the controller very close to the Raspberry. That's what got me into thinking of dropping the wireless (Zigbee) connection idea.

As I did have some Arduinos laying around, I started from there. The device at hand appears to be an Arduino Nano v3.0 if you're curious.

## FastLED

Controlling Addressable LEDs with Arduino is very simple - there is a ready-made library to use: [FastLED](https://www.arduino.cc/reference/en/libraries/fastled/). The only issue was that it is not supporting SK6812 chipset and RGB+W output.

Luckily, Arduino is a well-established platform and there is a [patch for FastLED](https://www.partsnotincluded.com/fastled-rgbw-neopixels-sk6812/) to support the extra channel. I only needed to do some modifications for the values to represent the right color channels. :rainbow:

## Physical installation

This is the first test run of the LED strip:
![Testrun](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3ejyrv8eme4oz5pmnkiy.jpg)

This is the LED strip cutting and soldering in action. The picture does not paint the whole truth I must say. The floor was that clean only in the beginning :satisfied:
![Cutting and soldering LED strip](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vh8ls5j58l5dnlqmrviv.jpg)

This is the strip cut, inserted into the rail, and soldered to the following strip:
![LED strip installed](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/omjvw04o9v9hrz29uhyc.jpg)

This is the first test run of part of the strip is installed to the rail:
![The half test run](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ze23wol5dnaroiypvr1i.jpg)

The same run from a different angle - don't try this at home :smile:
![Power to the test](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/22lnbxs3zehst8gy0azq.jpg)

Here it is with the cover/diffusor installed on top of the rail and Arduino installed without an enclosure (also what it looks like today):
![The result](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8e55c0ycl84idxcz2yqg.jpg)

## The problems

Did you expect it all to go without any issues from here on? Oh well, it did not. Once I had the whole strip installed, I used up many days to debug/cut/resolder the strips to figure out why the signal was not spreading on all of the LED strip.

It was just cut off at a random place.
It all did function when I first tried it on the table :worried:
![Signal cut off](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fpqs4s5s77plgz9sdi1c.jpg)

### Maybe just some voltage drop in the supply power?
Of course, this was my initial thought as well, but that got debunked with the simplest math: the power was supplied to the strip from the other end - from where the strip was not lightened up.

### Maybe bad ground connection?
I must say - my experience tells me - when you ever observe some electrical anomalies, look for bad ground connections. But this time it was not the case. As said, the power was applied from the other end, the cutoff was about 30th LED from the digital signal provided by Arduino.

### There is just one LED broken that does not pass the signal
It was clear that this is the problem. After all, addressable LEDs must pass the data signal to the following LEDs and if they do not for some reason, the signal is cut off.

The only problem was that ... now that I hassled to unsolder, cut off, reinstall the last working LED in the strip ... the exact same problem was still there :flushed:

### Maybe there is an LED in the middle that somehow messes up a bit in the data signal?
So I did cut, course, test, resolder many parts of the strip, but the outcome was always the same - the LED strip just did not lighten up from somewhere on. But I did observe something interesting when doing this: there was always the same number of LEDs lighting up. I.e taking two LEDs away from the lightened part of the strip made the cutoff to move by two LEDs forward :thinking:

### Maybe the FastLED hack messed up with addressing the LEDs?
Well, it all was perfectly working on the table, but I did tweak it here and there to test this assumption up without a success.

### Then what?
Then I just trialed and errored more. At some point, I started to cut off the beginning of the strip and move Arduino to different places in the strip realizing there was a spot where the strip lightened up fully! I had found the broken LED! Only that, I had not. After another round of cut-course-resolder I found out the strip was once again not lighting from the same point on :confused:

I started to suspect a wire that was connecting the sides of a doorway already long before, but there was no evidence this could have been the problem. The signal was not moving forward about 10 LEDs after the wire. The spot where I had to attach Arduino for the signal to pass through all the strip was 2 LEDs before the wire.

Nevertheless, I replaced the wire. It was a regular power cable with non-solid 1.5mm2 wires that got replaced by a CAT5 cable (using a pair for each of the three wires). And that did the trick. Yup, that's the whole story. Apparently, the data signal does not like a regular cable :memo:. I got it all lighted up and could move forward. :relaxed:
![The problematic wire](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p59n5zqn39gyrblo49th.jpg)

## Control with Arduino

From that point on I felt pretty comfortable writing some LEDs-controlling code for Arduino. The main aim is that Arduino must be able to take commands from the Node-RED. I used the USB-serial connection that automatically gets created when Arduino is plugged into Raspberry Pi. That is very convenient because the same USB connection is used for powering up the Arduino.

At first, I was keeping the data sent very simple, serial-communication-like if you will but then realized I almost always need to include many parameters (i.e `red`, `green`, `blue`, `white`, `brightness`, `mode`) and switched to Arduino processing JSON string. It is overkill, I know, but it does work and is convenient to use on the other side.

Just pasting the whole Arduino code I have at the moment for you to review, not that it is polished nor I am proud of it, but maybe there is a thing or two you might find interesting.
{% gist https://gist.github.com/murjam/24da72cfae72b1b5e870e367326a3841 %}

### The window
Maybe you noticed in the code that there are some LEDs "within" a window. What it actually means, is that I installed the LED lights also on top of the window blind tree because I thought the window might be too big of a gap of darkness.
But once I had it installed, I was dissatisfied how the ceiling got lighted up by the LEDs on the blind tree.

This is a perfect example of why addressable LEDs are cool though! I was able to simply dim down the LEDs on top of the blind tree to create an even better effect that makes the lighting look very similar to how it does on other areas in the room. :tada:

![LEDs on blind tree](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bbumdv013fn3daixugy5.jpg)

## Node-RED

My main Node-RED instance runs in a docker container that does not have access to the system hardware. But I do have another Node-RED instance that does and is there only to route some of the hardware signals to the MQTT and vice versa. This was an easy task to convert serial to MQTT:
![Serial to main Node-RED](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zvdrh6us5keo79xxicrf.png)

The picture does show `/dev/ttyUSB0`, but this is actually mapped in my `docker-compose` to the serial from `/dev/serial/by-id/:theSerialDeviceId` - you should always point to the device by ID to be sure it is the same device after next plug-in.

One more minor thing to bring out is that although the LEDs can be commanded to turn themselves off, I'm using an external Zigbee relay to cut the power wholly when the LEDs are turned off. It does not look pretty under the windowsill :see_no_evil: and I pinky-promise I will tidy up the wiring once the lock-down backs up a little and stores get opened, but this is how the relay and 200W 12V AC/DC converter is hooked up under the windowsill right now:
![Under the windowsill](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kxcadydvbl0f7vie0aup.jpg)

## Any conclusions?

Would like to still get my hands on building custom Zigbee devices, but this time I am happy with just hooking up Raspberry to Arduino with a USB cable.

The next step I want to add to this is an array of microphones for input to create some cool audiovisual effects :star2:, but giving out no promises here :smile:

Sharing an awkward video of the lights in action. The party mode as you see does not engage on the first click - find the issue in the provided Arduino code :wink:
I do have some ideas, but feel free to share yours on how to improve the code for Arduino?

Have fun!

{% youtube Gim43Ld9Kww %}