Tom’s HAT – Wakeup Light Alarm

How many of us have dreaded that alarm clock at ridiculous-o’clock in the morning interrupting our beautiful slumber in the land of nod? Beep-beep beep-beep… Some alarms will keep on going endlessly. Beep-beep beep-beep… Others will progressively get louder until you are forced to be awake, irritated that such a simple and inanimate, yet incredibly annoying object ruins your morning.  

There are studies (like this one) that heavily suggest that waking up to light is actually much better for your mental well-being and a better start to your morning than waking up to sound. Sure, a sounding alarm does the trick, but biologically speaking, your is still in “sleep mode” when you wake up. This is why you might try to get more sleep by hitting that “Snooze” button many (many!) times before accepting that you’re awake. In fact, these wakeup lights have shown to also successfully treat season affective disorders in people. 

It comes of no surprise then that the alarm clock industry has taken to simulating sunrises through artificial light. There are many wake-up light alarm clocks sold all across the internet that range from £20 ($25) to £150 ($190).   

But why buy one, when you can make your own IoT-based wakeup light using home automation hardware?  

Home Automation Server 

As part of my home automation projects, I need a central location to act as my “data HQ”. For this, you can choose many different types of boards, computers, or cloud-based resources, but I chose to use a Raspberry Pi 3 Model B simply for convenience and lots of online community support. I followed this tutorial that walks through setting up your Raspberry Pi as a web server with NodeJS (if you prefer other languages, I’m sure there are tutorials for them too!).  

With NodeJS, I simply utilise Express and the system’s REST protocol to write out my API. Code like the below are the building blocks towards creating your own API REST handlers.  

// Calling http://[IP ADDRESS]:[PORT]/testRequest will result in a 3-variable JSON response. 
app.get('/testRequest', function(request, response) { 
    console.log('Success!'); 
    response.status(200).send({ 
        var1: 123,  
        var2: 'Somevar',  
        var3: '123somevar' 
    }); 
}); 

I’m not going to explain how the code works, as there are many tutorials available that will do a better job than me. In fact, I actually need to read/watch those tutorials myself…  

On the RPi, I store all the configuration data, settings, and data collection that may be required for all my IoT-based devices that will connect to it. For this project, I’m storing the alarm clock’s alarm time and alarm days. That way, when the alarm is requested, I can not only send back the current time (based on the RPi), but also the alarm time and day! 

I have my RPi connected via an ethernet cable to my router, which should prevent any WiFi communication drops, and also reduces the power consumed by the RPi. Is this RPi model a bit of an over-kill? Probably, but as my home automation projects expand, I’ll have a lot more going on (like some data analysis and presentation, machine learning, other funky stuff) other than just an API. 

Wakeup Lights 

The actual wakeup lights are made up of 3 parts:  

– A strip of simple red, green, and blue LEDs (not RGB LEDs, they’re different!) 
– The electronics 
– A custom case  

The strip of LEDs was a gift from my partner when I got super excited about lights changing colour easily (it’s the simple things). I have a few of these strips, so I’ll be making either more wakeup lights or find another purpose for them.  

The main driver for this setup is from a NodeMCU. I chose this over a simple Arduino as this has a built-in WiFi module, allowing me to directly connect to a router without additional hardware. I can also program it from the Arduino IDE, thus fully utilising my Arduino programming knowledge. I had to make a very basic wiring board just to easily connect the NodeMCU pins to the LED string pins. For this, I just used some Veroboard, some wires, and some headers. The LED strip is driven by PWM signals for the red, green, and blue LEDs, so, fortunately, no other electrical design is required! 

The case was very simple to design. It’s just a box with a lid. I tried to be clever and have a latch or screws to keep the lid closes, but that was more effort than it was worth. Once it was 3D-printed, I simply covered one side with ductape (which acted as my hinge) and keep it closed with a small elastic band. It’s not a masterpiece, it just needs to work.  

Software 

This was my first project using a NodeMCU, so there were a few library files I created that I knew I was going to reuse in future projects. For example, handling network connections’ states via a blinking LED. Otherwise, everything is custom for this project.  

Fundamentally, the RPi and the NodeMCU are two servers talking to each other, where both request data from each other. The idea is that I would only need to talk to the RPi to send, view, and update configurations. The NodeMCU would just act independently. The basic software flow is shown in the image below:  

In the image above, the devices are connected to a central router (red arrows). The user at the computer would then be able to access and communicate with both the RPi and the NodeMCU (blue arrows), although the latter is not required and can be used for basic diagnostics. 

The two communicate via REST calls to each other. This allows both devices to respond to the other with “I’ve received your message” responses. I’ve thought about using other faster data-transmission methods such as MQTT, which is used in home automation projects, but methods like MQTT are designed for devices that are always connected, and where the bandwidth is a concern. The NodeMCU only needs to be connected at most (in very rare cases) a few times a day, and there isn’t very much data to transfer. So while MQTT would be an option, it would be an overkill for this project. 

Some of the libraries use String variables (which in embedded programming is a nightmare!) to pass data around. This causes instability in the RAM, and fragments the memory like nothing else! There are some useful pages online about minimising the RAM consumption within Arduino projects when manipulating String variables. My absolute goldmine was this Instructible by James Moxham. This little collection came in very handy when determining the right response to an incoming REST call.  

I created a simple HTML display (it’s not fancy at all) to configure the alarm, but because the system uses REST calls, a mobile app could be made for a better (and modern) user interface.  

Conclusion 

Overall, this home automation project works very well! It’s powered by a mains supply and never skips a time to shine those LEDs. It is always reliable (as long as the RPi server doesn’t conk out), and in the last few weeks of using it, the lights have never come on at inopportune times. It also turns out they can be used for reading as well, which is a bonus!

To improve on it, I would add a USB interface that allows me to configure and diagnose the NodeMCU via a USB connection. I would also add the ability to have multiple alarms, rather than just the one. Of course, anyone who fancies building it themselves can add whatever to it! The full source code (for the wakeup lights) can be found on my Github.  

Thanks for reading and if you are interested, check my previous article on how to build your own telematics box to track your car’s movements.

Leave a Reply