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.
A close up look shows a chip (black part on the left) and three LED’s, the middle one being red.
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).
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.
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.
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
- 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).