RGB Bias Lighting with Arduino (Part 1)

Introduction

Bias Lighting is a light around your display that helps you perceive contrast and reduces eye stress. It also just looks just plain cool, and create a kind of relaxed vibe.

There is a lot of theory on optimising bias lighting, but really any light will help quite a bit. So why not see if we can do anything inventive with the bias lighting colour.

The Idea

Lets use a bias lighting that changes colour, and experiment with:

  • Altering the colour to  correspond with the time of a day
  • Blink light to warn you that you have a meeting soon
  • Having the colour change match the movement of the sun
  • Changing the colour to green (or whatever) when its your “bed time”
  • Using a colour change scheme set to work with your circadian rhythm

 

Materials

What you will need:

  • Some WS2811 LED strips (approx 30cm per monitor)
  • An arduino
  • Some 3 core wire
  • About an hour free time
  • Electrical tape

 

Results

 

 

WS2811 RGB Strips

WS2811 strips can be acquired via Ali Express at a reasonable price, they are a strip of RGB LED’s that are individually addressable (set any LED to any colour).

Pros’

  • Each chip has an active data repeater that forwards the data signal. Provided the 5v power to the strip is strong, the data signal is propagated to as many chips as you like.
  • Very good value
  • Strong bright lights
  • Fast data channel
  • Only requires one GPIO pin.

Cons’

  • PWM control used for arbitrary colours is not super fast. Use of 7 colours that involve any LED being either full on or gull off produces results that work better for moving items / camera.
  • Poor build quality occasionally causes minor issues
  • Some visual artefacts from “fast moving pixels”.  (that can look very cool if used correctly).

The strips look like what you see below. They can be cut to length, and have a soldered connection every 30cm or so.  The arrows indicate the direction the data signal is propagated in, your controller (eg an arduino) must be connected to the left most (first) arrow. However the voltage to run the strip can be applied anywhere.

WS2811_strip

A close up look shows a chip (black part on the left) and three LED’s, the middle one being red.

WS2811_single2

 

Arduino Setup

For effective bias lighting, stick an adhesive LED strip to the back of your monitor, about 5cm from the top. The arduino can be mounted with stick on velcro to what have you. If necessary, connect up multiple sections of LED strips (one for each monitor) using a good 3 core wire.

The LED strip’s data line is connected to a single arduino GPIO pin configured as an output.  Its important to note the strip has an arrow on it, this arrow shows the direction the data will travel. Your data cable must be connected to the first  LED in the strip (not the last).

For my three monitors I was able to power the strip directly from my arduino, using only USB power. Though your mileage may vary.

Setup via USB Power

If you can get away with it wire up the strips shown in the top diagram. Be aware that your PC or USB hub will be responsible for providing power to a large set of lights.

Consider some issues with this:

  • There will remain a significant current draw on the PC even while its in sleep mode (or running of batteries).  Be aware not all PC power supplies sleep well , they may turn their fans off even though you are drawing enough current to necessitate a low amount of active cooling.
  • Your arduinos regulator will may get hot.
  • Your USB port may well not be up to task.

For these reasons I would advise:

  • Connection via a powered USB hub. 
  • Use of a USB Doctor Device to check your current draw is sensible (eg 350mA or below, the 500mA max in the USB spec does not always pan out well)
  • Configuring the brightness of the LED output (programmatically) to reduce current draw.
  • Don’t connect the Arduous power jack to a DC wall adapter (see note on ground loops later in this article).

 

rgb_leds_usb

 

If your Arduino fails to start, or the strip displays a gaudy set of flashing bright colours, you will need to use external power to run the strip. The cutt-off regarding how long your strip can be, before problems appear varies greatly between different production runs (of the RGB strip, not the arduino).

Setup via External 5V power supply

To use an external power supply  to power the strip is not difficult (see image below). But it leaves us with the annoying issue of ground loops (see ground loop section later in this article).

To use external 5V power:

  • Connect the 5V ground to both the arduinos ground and the LED strips ground.
  • Set-up a 7V(ish) power for the arduinos DC Jack, and use a cheap buck DC-DC power supply (eg LM2596 module) to drop that voltage down to 5V, which is connected to the LED strips power supply.
  • Resist the urge to just get a 5V power supply and connect it to both the arduous 5V pin and the LED strip, unless you have a good regulated 5V supply.

rgb_leds_dc_jack

A little more safety to this circuit

The soldering of wiring to the LED strip is often problematic, and the area is often moved / stressed / bent.  This can cause the electrical connection to come loose, short or form an intermittent contact.

We may want to protect the first LED package in the strip from damage caused by too much current passing though the data line (I suggest using a 330 ohm resistor).  It’s also not a bad idea to provide a 1000uF decoupling capacitor (use an electrolytic capacitor and watch the polarity). Without this you risk a wiring issue, or power connection issue, damaging the first LED unit on the strip.

In practice, you may never have a problem without these extra components, and the damage is often repaired easily by removing the first pixel and re-soldering. So the decision is yours, a ‘best practice’ version of the above circuits is shown below.

 

rgb_leds_better

 

Watchout for ground loops

If you need more power than just the USB connection you will have to give some thought to protecting your computer from ground loops.

The possibility of a ground loop exists when your arduino is connected to the PC via a USB cable and both the arduino (or connected circuitry) and the PC are mains connected in some way (even via a plug pack).

Possible solutions include:

  • USB isolator (eg: this one)
  • Powering the PC from battery (eg laptop)
  • Powering the arduino from battery (eg 6v SLA)
  • Powering the arduino and circuitry from a plug-pack and using a wireless connection to communicate to the arduino
  • Don’t connect the usb cable
    • Use a network enabled board (the network ports are very well isolated). The etherten is great for this.
    • Use wifi via a $5 esp8266 (for example this one)
    • Use an infra red serial connection (2400 baud)
  • Just live with a potential ground loop
    • Plug everything into the same wall socket and keep your fingers crossed.

 

Basic arduino code to test out the LED Strip

Now we have to check our electrical project functions as predicted. For this article, and part 2, I will be using the FastSPI_LED2 library from  fastled.io.

This demo code will create the effect shown in the video at the top of this article. If all you wanted was cool looking bias lighting, your’e done!

#include "FastSPI_LED2.h"

//----------------------------------------------------------------------------------------
//
// LED stip driver for smooth HUE trnsitions radiating from the middle of the LED strip.
//
//----------------------------------------------------------------------------------------

//Alter this to suit your setup
#define NUM_LEDS 91
#define PIN_LED 4

//This is where the individual pixel for ever LED is stored.
//use LEDS.show(); to sync the strip with the data in this array.
struct CRGB leds[NUM_LEDS];

void setup() 
{
	  // sanity check delay - allows reprogramming if accidently blowing power w/leds
   	delay(2000);

   	//to prevent too high  a power draw use 25% brightness
   	LEDS.setBrightness(64);

    //setup the LED controller
    LEDS.addLeds<WS2811, PIN_LED, RGB>(leds, NUM_LEDS);
}


void loop()
{ 
  byte hueMiddle=0;
  byte hueEdge=0;
  byte hueStep = 48;
  int maxHue = 255; //NB: hue may not be in the range 0-255, if we use a differnt hsv2rgb function.
  bool sync = false;
  
  while(true)
  {
    //pause a second
    delay(1000);

    //push the hue of the middle part of the bias light forward
    for(int s=0; s< hueStep; s++)
    {
        hueMiddle++;
        if(hueMiddle >= maxHue)
        {
          sync = true;
          break;
        }
        updateStrip(hueMiddle, hueEdge);
    }

    //have the edge of the bias light catch up to the hue in the middle
    for(int s=0; s< hueStep; s++)
    {
        hueEdge++;
        if(hueEdge >= maxHue)
        {
          sync = true;
          break;
        }
       updateStrip(hueMiddle, hueEdge);
    }

    // Reached the end of the hue cycle, wrap to the begining.
    // We do it this way because if the hueMiddle wraps around, but the
    // hueEdge remains before the end, then a full rainbow is creted
    // when updateStrip smooths the pixels over the strip
    if(sync)
    {
       hueMiddle = 0;
       hueEdge = 0;
       sync = false;
    } 
  }
}


// This method creates a smooth transition of pixels, from one hue in the middle
// to another hue at the edge.
//
//note: Could be faster with symetry away from middle.
//note: Could be faster with integer math.
//note: Because of the long delay, this does not need to be fast.
void updateStrip(byte hueMiddle, byte hueEdge)
{
    float mid = NUM_LEDS/2;
    int hueDiff =  hueEdge - hueMiddle;
    for(int i = 0; i < NUM_LEDS; i++) 
    {
        //get the hue for the pixel
        CRGB pixel;
        float h = abs(i-mid)/mid; //0 at mid, 1 at edge
        h *= hueDiff; //0 at mid, hueDiff at edge
        h += hueMiddle; //hueMiddle at mid, hueEdge at edge

        //set the pixel
        hsv2rgb_spectrum(CHSV((byte)round(h), 255, 255), pixel);
        leds[i] = pixel;
    }
    delay(150);
    LEDS.show();
}

 

What’s next?

In a follow-up article (part-2) we will cover syncing your arduino to the computers clock, choosing good colours for different times of the day and using your location to calculate where the sun is (in case you want to tune your your lighting to the time of the day).

 

Keep Reading

PreviousNext