Circadia - sunrise lamp

Concept - waking up on a beach

I love sleeping.

More to the point, usually, I really don't love waking up.  

I drag myself around and it usually takes until I arrive at work before I am really what you might call awake.

Alarm clocks are annoying.  Clock radios are better but depend on what's on the radio that day. Winter is worse than summer due to the lack of daylight filtering through the windows. 

So I thought: why not try to experiment with light and sound in order to design a customized wake-up call. The idea of a sunrise lamp isn't particularly new (1890) but I was excited to create my own platform for experimentation.

The basic idea is simple.  Recreate a sunset with light and sound during those short winter days when the real deal is hours away.  I guess this could be even more useful to people who have to get up really early.
About half an hour before the wake up time the lamp will start to go through it's color cycle, starting from deep orange and ending up at a warm, bright white.  All the while generating a soundscape that also increases in intensity.  Birds, waves, wind, depending on the current theme.  I'm still experimenting with the optimal duration of this fade, currently around 40 minutes.

In fact, I find it is so much fun to build these 'themes' that I can't seem to stop coming up with new ideas.  It's incredible fun to wonder what it would be like to wake up on a tropical beach, in the rain forest, African savanna, etc. and then being able to try it out.

Makes it quite a bit easier for me to get out of bed every morning (with a silly grin on my face).  It's really surprisingly effective and hard to describe.  Rather than being resentful that it is already time to get up,  I am now more inclined to be eager to get going.  If someone had told me that this actually works I would have put a sunrise lamp in my bedroom years ago. 

Lately, when not using it as an alarm clock, I have found other fun things for it to do, too.  For example using it as a party boombox with built in visualizer, playing Tetris or pretending to be a warp core (see examples below).

Hardware - the nuts and bolts

Even though the building blocks are fairly straight forward, it turned out that each part had some sort of a surprise in stock.
The hardware consists of a simple Linux system (Raspberry Pi) that controls a powerful RGB light source as well as a set of speakers (because, why not, right?). 

It also has a display to show the time and a few buttons for basic user interaction.
Everything is squeezed into an enclosure that is not too offensive on the eye while taking up little floor space, standing in the corner of my bedroom.

Here's a complete list of the bits and bobs


The body - fitting it all in made of the largest diameter PVC pipe I could find scouting the plumbing shops in my area. It is quite heavy, probably pressure rated with a wall thickness of 8mm and an overall diameter of 160mm. 
Judging by the amount of grime and dust it had accrued I imagine it must have been lying in that shop for quite a while before I came along. Luckily they agreed to sell me a 2 meter off-cut for a very reasonable price.

The lamp stands 187cm tall and is made of 3 sections.

The top section is comprised of the clock and the top speaker.  A 3D printed conical reflector is my attempt of an omni-directional speaker design.  The clock is technically a fourth section since all the segments, including the clock, plug into the previous one like Lego blocks.  It can be removed separately.

The midsection is basically a wooden column (MDF) that the acrylic diffuser wraps around 3/4 or the way.  I had no idea where to get an acrylic tube of just the right diameter, or any, so I bought a sheet instead and heat-molded it into the right shape. The rest of the space is used up by 16 RGB LED strips, each 18 LEDs long. 

The bottom section houses a mid-woofer, most of the electronics and the three switched power supplies.  Aluminium legs make sure it stands steady on soft carpet.

Read more about the body work and the process of shaping the acrylic on the details page.   more details...


The clock - persistence of vision a bit of a science experiment. I needed a display to tell the time but from a practical standpoint, the idea of fitting any kind of flat or square display into a cylindrical shape bothered me. 

At any rate, I've always wanted to try out a POV based display and in this case it has many features that fit the sunrise lamp perfectly.  It is cylindrical, can be seen from all directions and does all this with only 7 LEDs. 

Computationally it is simple enough to be driven by a low-powered microcontroller (ATmega168). 
However, there is a hitch.  How to power a circuit that is spinning at high rpms, where cables are not an option. 
Also, in order to be useful as a display there has to be a way to communicate with it, at least by sending instructions one-way. 

People have come up with clever solutions for this.  From using multiple ball-bearings as sliding contacts to stereo jacks. Since my display would be operating continuously for a long period of time I was worried that these kind of techniques may have too much wear to last very long. 
Also, since the lamp is standing in my bedroom it has to be as silent as possible. 

I finally chose a motor from a hard drive that has a fluid bearing at it's core.  It is built to run at high speeds reliably for long periods of time.  And it is doing so very quietly.  

Power is transferred via dedicated magnets placed around the circumference that induce the required current in coils on the spinning circuit board itself.  Basically like a small electric generator.  

For the communication I scavenged an IR receiver from one of those tiny remote controlled helicopters.  It turned out to be easy to use and is impressively sensitive. 

There is another board involved when it comes to handling the IR transmissions and capacitive touch buttons but on the front end the communication is simply done by sending commands out over the Raspberry's serial port.
More about the electronics and mechanics, tests and failures on another details page.  more details...

LEDs - generating light

Controlling the color of the light over time is one of the main objectives.

As I mentioned before the lamp part is made of 288 RGB LEDs.  They are individually addressable with a color depth of 24 bits,  8 bit per color. 

These trusty WS2812B kind of smart LEDs come in a variety of shapes (Adafruit calls them Neopixels).  
I bought mine in 5 meter rolls of low density strips (30 LEDs per meter). 

Altogether they amount to a total power draw of about 80W, when switched fully on which is plenty bright. This also means that they produce quite a bit of heat and air vents in the design are important.   These LEDs have been quite popular among DIY enthusiasts because they are incredibly easy to use, require almost no external parts and can be controlled with a single wire. 

Due to this popularity there are software libraries available for many micro controllers and dev boards. I am controlling my pixels from the Raspberry in Python with this excellent library rpi_ws281x

LEDs have a fairly non-linear color response (actually, it's our eyes that are at fault) and this is especially apparent in the low intensity range. To produce smooth and true gradients I had to apply gamma correction to my graphics before they are sent to the screen. And each color needs a slightly different curve.

Another surprising thing I noticed was an obvious quantization effect. Especially when slowly fading to black, I could clearly see jumps in brightness in the darker regions.
I attributed this to the high contrast ratio of the LEDs for which 255 brightness levels may have been a bit on the low side. (This is true, however, it turned out that my sloppy coding massively compounded the effect. I'll get to that)

To improve on this I added dithering as a final step of my color conversion.
I figured a method called Ordered Dithering would be good enough and be temporally stable as well as simple to implement and fast.  It's what Windows applied to low color displays back in the days.
However,...I recently noticed that the Pygame surface I used as my drawing canvas was created by default on the Raspberry Pi with a color depth of 16 bit, not 24!  Which means I only really ever got 5 (red), 6 (green) and 5 (blue) bits to see. (#facepalm)  Suffice to say, it made a big difference when I finally switched it to a 24 bit, true color canvas.
I left the dithering code in and it still does make a visual difference in the low color range.  So, not a total waste of effort in the end :)

Audio - soundscapes

Evil Ground Loops

From early on during testing I noticed that I could hear activity related to things like network traffic or cpu usage as faint buzzing through the speakers. This got even worse when cycling the LEDs through color animations. Even though I had put quite a bit of thought into the wiring, 3 separate power supplies don't make this easier, in the end the only thing that completely eliminated this unwanted noise was to insert a ground loop isolator (transformer) between the sound card and the amplifier.
Just as important as the light, if not more so is the audio.
It is what shapes the experience and makes the difference between a beach atmosphere and a jungle theme. 

I really wanted to avoid the plastic can sound of a cheap radio clock and picked the audio components carefully.  Not being an audiophile, I had to do a bit of research on speaker design (pretty complicated and scary stuff) and am quite happy with the result.
The high to mid range is brilliantly clear (great for bird song) and even the bass is surprisingly effective, given the small driver, low volume and absence of a port.

The woofer in the bottom is a sealed design, no logical place for a port, with a volume of about 5 liters. 

When I was sourcing the parts locally,  I could only find this 4 inch, 8 Ohm mid-woofer that would fit into the tube, even though I would have preferred a 4 Ohm variant (and a larger driver of course). 

The speaker in the top uses a 4 inch, 4 Ohm, 2-way driver meant for car stereos. It is embedded in a 4 liter sealed 'box' and is beaming into a conical hat that redirects the sound equally in all directions (shame my lamp is sitting in a corner). 

Due to the different impedance of the two drivers I end up having to tune the volume of the two channels separately. The bass is running at a volume of 85% while the mid/high channel is only at about 35%. Not ideal, but workable. 

The sound is also produced and mixed by the Raspberry Pi, however, cannot be output via the on-board 3.5mm sound jack. Unfortunately, the hardware powering the jack (PWM) is already allocated to generate the signals to communicate with the LEDs.  So I plugged a cheap sound card dongle into a free USB slot which works great.

Software - what makes it tick

The software running the lamp is written entirely in Python.

As far as my experimentation goes I wanted to hit the ground running and Python is excellent for rapid prototyping.
When it comes to sound mixing and graphics processing, Pygame is a breeze to use. 
The fact that almost everything you need is already preinstalled on the Raspberry Pi was my main decision to use it for this project.  Load some wav file, play them back.  Load images and draw on them or with them.  Send the image buffer to the LEDs.  Simple prototypes of ideas can be coded and tested quickly in an afternoon (eg. Tetris).

A script called is continuously running and when the time comes to, well, sound the alarm, it randomly loads one of the available themes.

Themes are held in folders that contain all the resources, .wav/.ogg sound files as well as a theme.json file that describes what is supposed to happen and when.
The theme is described as a collection of modules that do certain things periodically, say play a sound continuously or randomly every now and then or update the color gradient of the LEDs based on the current time.

It can be quite tedious to write json configuration files manually, especially with larger themes.  So I started writing an editor in Python using Tk.  Initially, I didn't want to bother with something as unwieldy as Qt because it was just going to be a simple UI to edit my themes. Well, it got a little out of hand.

When you are editing gradients you need to see them.  It's nicer to pick on control points to edit the track envelope than to edit a spreadsheet.
A banner picture will help to inspire the right mood, etc, etc. ;)

The editor can also connect to a port on the lamp via wifi.  This is very useful since the LEDs are in no way color calibrated (neither is my monitor), and it is super helpful to be able to see what the colors you are editing look like on the actual hardware.

With the editor I can throw together a new theme very quickly. Once I have saved it, I just copy the whole folder to the lamp and it will pick up the new theme in the morning.  (Yes, it is important to test the theme on the lamp before you get woken up by a soundscape that is way to loud and you start out your day grumpy as hell).

By the way, an added bonus of using Python is the fact that it is cross-platform. The lamp scripts are written in a way so I can run them on the Raspberry Pi as well as on my PC.  This makes it easy and convenient to add new features or debug a problem.

I've been working on the lamp, on and off, for the last 2 years (with very long breaks inbetween), so there is a lot to tell.  But I don't want to get too long winded here.  More info can be found on the details pages, if you're interested.

Maybe try waking up with a sunrise lamp of your own design.

Let me know if you have a cool idea for a new theme.  Until then  zzzZZZzzzzZZZ


Update: Now you can make your own Circadia Sunrise Lamp!

Get the source code and themes here:  Downloads

Still got questions or suggestions, let us know:  Forum


Theme collection


Other projects you might like

Etch tank    DE0-Nano | analog video    MinimaBL