Saturday, May 16, 2015

Wakeup Light Alarm

I met a friend recently who mentioned that she was annoyed with her alarm, which used sounds and clicked whenever it was about to wake her up.  She awoke to the click rather than to the gentle sounds of the alarm.  They sell alarms which gently use light as an alarm, but they are expensive.  With a couple items sitting around, I made a prototype of a lighting alarm.

To set the time and the alarm, you use 10K pots which are attached to the analog inputs of the microprocessor, which is a Sparkfun 3v3 Arduino Pro Mini (atmega328 running at 8MHz).

The alarm is triggered when the time and the alarm are the same.  This leads to a progressively increasing intensity of an Adafruit Neopixels LED strip, which also shifts colors from RGB  245,99,144 (pink), to RGB  255,254,60 (yellow).   The alarm duration can be adjusted with a third potentiometer from a minimum of one minute to a maximum of about 8 minutes.  

I used an OLED from sparkfun for the display.  The OLED runs at 3v3, which is why I used the pro-mini board.   It is an outstanding little device with incredible resolution given its small size.   I wired it up using the SPI interface exactly according to the directions on the sparkfun tutorial website.  

I used a switching 5V power supply with 8A capacity to drive both the microprocessor and the board.  Interestingly, the power supply initially failed to turn on the LEDs.  They worked fine with the 5V pins from an ATX computer power supply, and also from 3AA batteries.  At first I figured that the power from the supply I had bought was too puny, but I tried another 5V supply and it also failed.  After a little research, I realized that the logic supply to the Neopixels was being driven at 3v3 from the Arduino Pro Mini, while the LEDs are being driven at 5V.  If the power supply is nice and stiff, the 3v3 voltage rests in "no-man's land" in terms of logic... it is not high enough to be "1".  The solution in my case was to install a 3A capacity diode (IN5401, datasheet) in series with the power supply, to drop the 5V down to 4.3V.  This fixed that problem, although the diode does run a bit hot in testing.  I also installed a 1000 uF capacitor across the 5V supply to protect the Neopixels from damaging startup current surges.

All of the components were mounted on a custom PCB board.

The potentiometers used were 3310Y-001-103L 10k.  I love them cause you can super glue lego pins on the top easily.  The pots have lego gears as knobs and the center position is marked with white out.

Finally, the LED strip was mounted onto a styrofoam cone.  Paper clips were used to temporarily secure it into the styrofoam, and then epoxy was added to permanently secure the paper clips.  The cone was epoxyed onto a piece of basswood onto which were mounted the PCB board and the power supply.

The coding (available here on Github) was somewhat rote, although figuring out how to give a reasonable range of speeds to adjust the clock and the alarm took some time.  In addition, I tried to make the lighting resemble a sunrise.   It's a reasonable attempt, but nowhere as good as the nature's version.

The algorithm used for the lighting is to pick an initial color and a final color, and linearly interpolate the colors between.  This is easy to do using a formula such as: currentColor = initialColor + currentStep/TotalSteps* (FinalColor - InitialColor).  For example, the raw interpolated colors are shown in the graph below, overlayed with the corresponding colors.
In addition, I wanted the intensity of light to increase, starting from gentle lighting up to very strong lighting.  I used a quadratic function to increase the intensity slowly at the beginning and then at an increasing rate.  The function used is intensity = 0.04 * currentStep^2.  This results in 100% intensity at 50 steps (which is how many are currently set in the program).  The quadratic coefficient could be tweaked so that it was parametric with the number of steps, but I didn't bother for a prototype.

To get the actual color, the raw RGB values are scaled by the intensity value for the current step.  The graph below shows the scaled RGB values and colors.  I think the colors are misleading cause they are subtractive rather than additive as is generated light.

Downloadable Eagle Files and Excel Spreadsheet for color calculations can be downloaded here:

Approximate costs:
Sparkfun Pro-Mini Arduino:  $10
OLED:  $18
Newcastle Power Supply:  $15
NeoPixel LED Strip:  $12 (half of full strip used)
Basswood and Styrofoam:  $8
TOTAL:  $63