‘Tiny Wake-Up Light Is Hugely Bright

Let’s face it — waking up is rough no matter what time of year it is. But the darkness of fall and winter makes it so much worse. In the past, [Maarten] has used music with increasing volume, but depending on the setup, it can be dodgy if you want to hear a different song each day and don’t have all your files volume-leveled.

Wake Up Bright is the latest in a line of wake-up widgets [Maarten] has made to help rouse them in the morning. Their write-up covers all ideas they’ve had on the subject over the years, as well as the electronics, firmware, debugging, and all the upgrades made after using it for awhile.

The inner workings of an AVR-based artificial sunrise.Slowly brightening an LED doesn’t have to be difficult or expensive. [Maarten] originally used an Atmel 90S2313 AVR and later upgraded to an ATtiny 2313, which was easy because the two are pin-compatible. The 2313 outputs PWM, which duty-cycles the LED to create a nice fade-in of white light that is way more gentle than that classic 1980s alarm clock buzz-beep.

Over time, this project went from one IKEA enclosure to another. We really like the newer one, which looks like it was designed for people to hack into a wake-up light.

Our eyes perceive brightness increases logarithmically, but PWM is linear. We can get around this by multiplying the PWM value by some factor every so often, but the problem is that this AVR never learned its multiplication tables. So how, then? [Maarten]’s answer is byte shifting using a 16-bit register — one byte for PWM, and the other as a scratch pad to do logarithmic math. [Maarten] multiplies the 16-bit register by 1/256 every couple of seconds, which results in a logarithmic increase of brightness. It’s calculated for a 15-minute sunrise, which required some experimentation to get right.

Whereas [Maarten] started with a 3 W RGB LED, the current version has three 10 W LEDs and uses a power supply from an old monitor. Daylight Saving Time is coming to an end in the US, and it’s gonna get worse quickly. Lucky for you, this project is completely open source down to the firmware.

You think that 1980s alarm clock buzz-beep is bad? How about some repeated slaps to the face to wake up?

26 thoughts on “‘Tiny Wake-Up Light Is Hugely Bright

  1. I have bough wake-up light alarm clock some time ago but that time it only offered FM radio or sound and I also wanted some sound of increasing volume. For a long time I used the clock only because of the sun simulation and coupled it with sound from my smartphone which was something like “sunrise with birds” and I did the increasing volume in Audacity.

    I am still thinking whether it would be possible to use combination of RGB LED, maybe with some “common” warm white ones to build a wall light with both sunrise and sunset simulation – enough powerful to work like direct summer sun shining in my bed even in winter…

    But especially the color changing from dark red to orange, yellow and finally warm white could be a tricky task…

      1. OK, not necessarily such a realistic simulation :-) The LED light might lack the thermal component of the real sunlight but here I think the psychological effect is more important and with appropriate color it might be enough although the light is “cold”. Similarly I found out that some LED candle imitations are able to provide you that “warm” feeling although there is no heat produced.

        1. Exactly. Remember several experiences from holiday where we had window to the East and the morning sun going through the window was sure but a pleasant way of waking up – although I’m not early bird but rather a night owl :-) Even a simulated sunrise through a window could help you get up early in the winter.

      1. Wonderfully smooth. (on youtube)
        But the colour looks like sunrise might be during wildfire smoke? I’ve never seen a sunrise with so much red. Where does sunrise have those colours?

  2. > [Maarten] multiplies the 16-bit register by 1/256 every couple of seconds

    The factor is 1 1/256 or 1.00390625 or 0.39% exponential growth (not logarithmic but a power function)

    A logarithmic function starts rising rapidly and then slows down towards some value, whereas a power function starts off increasing slowly and then picks up the pace up to infinity. The human eye’s response to brightness is logarithmic – a little goes a long way, but adding more has less and less effect; in order to make the brightness appear to increase linearly, the LED must follow the inverse function, which is exponentiation.

    Of course if you wanted to make a sunrise lamp, you wouldn’t do what the eye does but what the sun does, which is more like a clipped sine function:


    In the early morning, sunlight is increasing more or less linearly, so you don’t have to use a power function to simulate it.

    1. Thanks Dude for pointing that out. I have corrected the log/exp mistake in the article.

      Doing what the sun does makes even more sense. It never occurred to me to look into that, but it might make a nice firmware upgrade some day. Instead of calculating, I might as well dump the whole “sun-curve” into a lookup table.

      1. More exactly, the code is calculating a kind of “compound interest” on the value, and it is indeed an exponential function, not a power function as I originally claimed. (a^x instead of x^a)

  3. I’m here to say (write) that the lamp should maybe be heavier with blue light.
    Just as blue LEDs can make it difficult to fall asleep, the SAD lamps (Seasonal Affected Depression?) are heavier in the blue range.
    Just as the Sun may change from deep red to white as it is rising, the sky changes to bright blue.

    1. I wish I could find it but you’re quite right on the blue light point the consensus seems to be that blue light is the most stimulating and provides the best wake-up, green light is second best and white light is third. The scientific wild ass guess on why this is true is because early morning sky is quite blue, the green would be a leafy canopy and white is just sunlight.

  4. This is a project I find fascinating because it shows me that different latitudes/longitudes really affect one’s sleeping habits, and what’s a desired solution at one location isn’t what’s needed at another.
    For me, I have the complete opposite problem of needing light in the mornings.
    The confluence of being in the subtropics at an extreme easterly location in my timezone AND not having Daylight Saving at any time means the sun comes reeeeally early, even in mid-winter, and just way too early from mid Spring to mid Autumn.

    So I have thick heavy light-proof blackout bedroom curtains, and keep a lot of doors closed to keep the light down as well as a metal window sunshade on the outside.
    And yet still it’s well bright enough I think I need to block around the edges of the curtains perhaps by sewing magnets into them.
    Light in the evenings? Now that’s something I could do with more of!

  5. Times have changed. 30 years ago, did something like this with a couple of bulbs and a plug in timer, set to iluminate the room a couple of minutes before the alarm goes off. Tricky as the old mechanical timers (the ones with pins for on and off) were not easy to set to the minute. Worked though.

  6. In the past, [Maarten] has used music with increasing volume, but depending on the setup, it can be dodgy if you want to hear a different song each day and don’t have all your files volume-leveled.

    stuartl@vk4msl-pi3:~ $ crontab -l
    0 5 * * * ( /usr/bin/amixer -c 0 -- sset Headphone -40dB; /usr/bin/amixer sset 'Headphone',0 unmute )>/dev/null 2>&1
    10 5 * * * ( /usr/bin/amixer -c 0 -- sset Headphone -30dB; /usr/bin/amixer sset 'Headphone',0 unmute )>/dev/null 2>&1
    20 5 * * * ( /usr/bin/amixer -c 0 -- sset Headphone -20dB; /usr/bin/amixer sset 'Headphone',0 unmute )>/dev/null 2>&1
    30 5 * * * ( /usr/bin/amixer -c 0 -- sset Headphone -10dB; /usr/bin/amixer sset 'Headphone',0 unmute )>/dev/null 2>&1
    40 5 * * * ( /usr/bin/amixer -c 0 -- sset Headphone -6dB; /usr/bin/amixer sset 'Headphone',0 unmute )>/dev/null 2>&1
    50 5 * * * ( /usr/bin/amixer -c 0 -- sset Headphone -3dB; /usr/bin/amixer sset 'Headphone',0 unmute )>/dev/null 2>&1
    0 6 * * * ( /usr/bin/amixer -c 0 -- sset Headphone 0dB; /usr/bin/amixer sset 'Headphone',0 unmute )>/dev/null 2>&1
    10 6 * * * ( /usr/bin/amixer -c 0 -- sset Headphone +4dB; /usr/bin/amixer sset 'Headphone',0 unmute )>/dev/null 2>&1
    0 19 * * * ( /usr/bin/amixer -c 0 -- sset Headphone +4dB )>/dev/null 2>&1
    10 19 * * * ( /usr/bin/amixer -c 0 -- sset Headphone 0dB )>/dev/null 2>&1
    20 19 * * * ( /usr/bin/amixer -c 0 -- sset Headphone -3dB )>/dev/null 2>&1
    30 19 * * * ( /usr/bin/amixer -c 0 -- sset Headphone -6dB )>/dev/null 2>&1
    40 19 * * * ( /usr/bin/amixer -c 0 -- sset Headphone -10dB )>/dev/null 2>&1
    50 19 * * * ( /usr/bin/amixer -c 0 -- sset Headphone -20dB )>/dev/null 2>&1
    0 20 * * * ( /usr/bin/amixer -c 0 -- sset Headphone -30dB )>/dev/null 2>&1
    10 20 * * * ( /usr/bin/amixer -c 0 -- sset Headphone -40dB )>/dev/null 2>&1
    20 20 * * * ( /usr/bin/amixer sset 'Headphone',0 mute )>/dev/null 2>&1

    ^ That plus qt-dab tuned to a local station seems to meet that requirement.

    1. That can be scripted.

      Instead of scheduling every loudness increase directly in crontab, how about making a script that does the fade-in for you?

      some years ago I made something similar. Some of the programs are a bit outdated, but the idea is still valid. And if you replace aumix with amixer it should be good to go.

      On the bottom of the article is a link to download the script.

  7. Did this with a PIC 12C508, cheap digital alarn clock and recycled white LEDs from a broken lamp back in the day.
    The big problem as I later found out, was that the micro had an annoying flaw causing it to get unpredictable at low battery voltage and unfortunately there was no way to fix it due to using up nearly all the program memory testing various fixes so left it well alone rather than breaking it more.
    An LDO alarm would have made sense.
    Rewriting my sucky code also used in the LED star to account for bit loss in the shift register also worked.

    1. What do you mean by using up the program memory? Couldn’t you have just removed the tests that didn’t work?

      (I don’t see anything in the datasheet about incrementally-usable OTP program memory, which is the impression I got from your comment. I’ve never heard of a microcontroller with such a thing, and I’d be surprised if any has it, because I don’t think it would be a popular feature.)

Leave a Reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.