Introduction: Arduino Powered Sunrise Alarm Clock With Neopixels

I'm not a fan of getting up. I'm also often very tired in the mornings (and usually grumpy. But I digress.) I was doing some reading about how to get better sleep when I came across a guy who did some sleep experiments. Some were pretty wacky, but I liked the idea he mentioned about getting up at the same time every day, sort of like a mechanism to condition your body to get up more easily.

I had also read various things about blue light, most prominently in the whole screens keeping children awake in the evening thing, but also in a few otherplaces.

Having seen the sun come up a time or two, the blue light before the sun rises can be pretty spectacular and so I figured I could try and do something like that to help me wake up naturally rather than with the massive jolt that my current alarm clock induces with its, frankly, terrifying sound.

I saw you could buy sunrise alarm clocks, but where's the fun in that?

I'd also been reading about Adafruit's Neopixels and I was itching for a reason to try some out.
Objectives:

  • See if any of this stuff about blue light makes it easier to get up.
  • Understand more about Neopixels
  • Have fun

Step 1: Design

To my mind, the design needs to encompass three things:

  1. What is it going to look like?
  2. How is it going to work on the inside
  3. How should it look and feel from a user perspective

The physical appearance

The physical appearance of the thing is going to be pretty important. It needs to be functional, but also it has to sit in my bedroom on my bedside table (and perhaps most importantly my wife needs to approve of it) so it needs to be robust enough to handle sleepy fingers, being knocked over, hopefully to last a while and not look like a nasty electronics project with wire everywhere!

It seemed obvious to include a bunch of LEDs laid out on the front of the box. This would allow a variety of patterns and effects and hopefully some additional functionality. I considered adding a dedicated set of 7 segment LEDs like my current clock radio alarm, but I couldn't think of a layout where the two would nicely blend. I had a minimalist look in mind. I thought about circles (to mimic an analogue clock) but in the end settled on a grid arrangement.

I looked seriously at both the 144 LEDs per metre and 60 LEDs per metre strips and quite quickly settled on the 60. The spacing looked good for what I wanted to achieve as the sunrise panel and I realised that if I arranged them as five rows of eight then I could just squeak in four characters using a 3x5 font. There's also 60 seconds in a minute, which opened up some more possibilities.

I should also add that I wanted to build this at a reasonable price for an experiment which might turn out to be a disaster - e.g. it wakes my wife and not me. The 60 per metre was the most reasonable of the options.

The user interface needed to be buttons and/or switches. (Although check the last step for some other thoughts.)

The picture shows my rough idea - albeit I wasn't certain on number or position of buttons and switches. I knew I wanted the power lead to come out of the lower right hand side - because that's how it'll sit on my bedside table.

Electronics

An Arduino as a microprocessor was an easy decision. They are quick to use and straightforward - and I had a little bit of experience with them. I investigated using or not using a real time clock (RTC) module - which keeps the time even when the power is off - offloading that responsibility. It was a little extra cost, but a lot easier to program. It also avoided the need to build a printed circuit board (PCB) which would be great if I was making 500, but not for one.

The other major factor was power. Each Neopixel needs, at maximum brightness, 60mA. Calculating that 60 Neopixels x 60mA = 3.6A + plus the power for the Arduino and the RTC module - implies a pretty hefty power supply. This was the worst case, and Adafruit says that you should figure on an average of 1/3 of that load.

The picture shows a rough schematic of how I figured the parts would come together.

Software

I didn't spend a lot of time thinking about how the software would work up front. I had vague thoughts of different clock modes e.g. the time, showing seconds passing by, some sort of analogue face. I knew I'd need to be able to adjust the settings. And of course, the alarm mode - I envisaged that it would start slowly turning blue LEDs on, building to a crescendo of light when it was time to get up.

The picture shows a slightly post-rationalised version of how I thought it would work.

Step 2: What You Will Need

Supplies

You will need:

  1. A box. Or 'something to put everything in.' I pondered making a wooden box, or using a photo frame but in the end I found a plastic box at Ikea that had a good face for the LEDs, plenty of depth for the electronics and a great price. Cost £2.50
  2. LEDs. The sunrise element demanded blue, but I wanted to go bigger and better, so I needed RGB LEDs and the easiest way of doing that seemed to be Adafruit's Neopixels. I got mine from Proto-Pic. Cost £22.22
  3. Protection for the Neopixels. You also need to get a 1000 uF capacitor and a 470 Ohm resistor to protect the LEDs from too much voltage/current. I bought the capacitor from Proto-Pic too, but I had a spare resistor like this one in my bits box. Cost £0.43
  4. An Arduino. I feel a little bad for not buying genuine Genuinos, but I cheaped out and bought a five pack of Arduino Pro Minis from a UK seller on eBay. I bought the 5V version to make my life easier. Alternative from Proto-Pic. Cost £2.59 per unit (assuming I use the other 4 in the pack for something else.)
  5. RTC module. Not 100% strictly necessary, but it made the programming a lot easier. I bought an RTC module based on a DS3231 from eBay again. Alternative from Proto-Pic. Cost £3.19
  6. Buttons. I already had some tactile switches a bit like this one. They seemed the easy way to do it, as the tall actuator could poke through the thickness of the box and could be pressed directly without the need for an exterior button. EstimatedCost £1.59
  7. 5v Power Supply. I spotted a 240V to triple USB adaptor at Ikea the other day and figured that would make a good source of a 5v power supply. It's rated at 3.4A max, which is just over the limit of what 60 Neopixels on full blast plus the Arduino and RTC require. But I figured I'd chance it, and so far it works fine. I used a spare figure 8 mains power cord and cut off the figure 8 part. Cost £7.00
  8. Wire. Buying an Arduino board and an RTC module, plus the Neopixels made building a circuit board redundant. I also knew I'd need to wire up the strips of Neopixels. I had some wire in my supplies a bit like this. Estimated Cost £3.19

Total cost for me was: £34.74

PS Just for the record, I have no affiliation with Proto-Pic or Ikea - but they both seem nice.

Tools

You'll also need:

  • Pen, pencil, ruler, tape - for marking up
  • Drill or dremel - to make holes for the LEDs, buttons and power cable
  • Hot glue gun - to 'attach' the components to the box
  • Soldering iron - to wire up the components
  • Hammer and a chisel - to crack open the Ikea power adaptor

Skills

It's probably fair to say at this stage that this is not intended as a complete guide for a total beginner. This is an intermediate level Instructable. I'm going to assume you already know how to do certain things (or you can look for them here on Instructables or elsewhere first.) I'd suggest you need to be able to:

  • Use simple power tools - particularly a drill
  • Solder wire to circuit boards and the resistor and capacitor mentioned above
  • Load a program onto an Arduino

Important final requirements

This project involves sharp things, hot things, bad smells that can make you sick and mains electricity. I'd suggest a grown up or responsible person assists, but I'm (supposedly) both of those things and I burned myself (twice, once with the hot glue and once with the soldering iron) and electrocuted myself with 240V.

So:

  • Be very careful with the soldering iron - it gets very hot
  • Use the soldering iron in a well ventilated space - the fumes are bad for you
  • Watch out with the hot glue - it's not called 'hot' glue for nothing
  • Sharp things usually cut you faster than your workpiece - so go steady
  • Most importantly: make sure you understand where the live parts of the mains circuit are and turn it off when handling those elements

Step 3: Building the Display

Cutting the holes for the LEDs

The strip of LEDs came in a one metre length with 60 Neopixels. I didn't want to cut them up into 60 individual elements (I'd probably still be wiring them up), and so the horizontal spacing was already set at 17mm. The vertical spacing was limited by the width of the strips, I looked at a few different spacings to suit my box and settled on 20mm. A compromise between using the space, ease of putting them in and trying to keep the display for the 3x5 font tight. I marked out the lines with a ruler and pencil and used a punch to mark the centres.

I wasn't certain how the box would cut, so I used a small diameter drillbit (2mm) in a Dremel to start the hole off and then went back over them with a full-size drill and a 5mm bit. My experience was that the material cut very easily and well. A slow speed on the drill was best for getting the cleanest cuts.

As a side note, I did part of this work with my Dad. It was fun to do some project work together, and I learnt a few little tricks too. Thanks Dad!

My advice would be to take your time, this is one of the most visible elements of the project and not all of my holes were on the marks. I also backed my lid up with a scrap of wood and clamped it down. I'm not too sure if it really helped, but I only needed a little clean up with a blade after.

Cutting the LED strip and gluing it in place

I cut the Neopixel strip on the indicated marks. I did remember to measure twice and cut once.

I had no idea what would be the best glue to attach the strips and also whether to keep the protective sheathing on or not. In the end I plumped for masses of hot glue and keep the strip on. I don't know if this was the best method or not, but it seems to be strong enough for this application where there are little or no forces on it after construction is complete.

Each Neopixel is wired to the next one in the same sequence. It's important to watch the arrows on the strips as the signal travels in one direction and sets the ordering for how they are addressed in the software.You need to decide at this point whether to lay them the strips out all left to right and have the wires cross in zig zag pattern or alternate directions and just tie the ends together. I had decided to lay them out in a consistent direction as it makes the maths in the software much easier.

I decided not to try and put glue between the strip and the box, for fear of misalignment or gaps. I decided to just gloop masses down the sides and over the top. If it didn't work, I'd peel it off and try again. I struggled to line the LEDs up with the holes and keep it steady and apply the glue. Two pairs of hands made quite a difference at this stage - thanks again Dad.

There was a bit of movement at the ends of the strips, so I went back and added more glue.

Wiring it up

The Neopixel strips are wired to +5V, ground and signal.

I wired up the first strip to some long loose leads and then it was then a tedious business of cut, strip, solder, repeat. I suggest you cut the wire a little long. The first ones I tried were tight and it might make wire management easier but it was much harder to solder.

I'll mention the final step in the display now, although I actually did it later in the build process. When I knew everything worked, I smothered each end in more hot glue for protection. The hot glue is an insulator so it doesn't interfere with the electronics. I don't suggest you do it until you've tested everything works.

Step 4: Power for the Clock

Safety

If I'm nervous about anything to do with this Instructable, it's this part. The most sensible thing for you to do is to ignore this section and buy a ready made 5v power supply which can supply 3-4A and use that instead (here's the closest I can see on Proto-Pic.) Seriously, mains voltage is dangerous.

I assumed when I spotted this possibility that loads of people would have done this already. Either no-one has because it's spectacularly dangerous, no-one has written about it or my Internet search skills are not good enough. The only thing I did find was an article on the quality of the insides of the thing, which made me feel better. If you know this is a crazy thing to do, please let me know.

Still with me? Ok, take it steady and remember to turn it off whenever you have to touch it. I zapped myself just nudging it over a bit when I was testing something else and I wasn't thinking about power. My arm was tingling for quite some time.

Extracting the guts of the Koppla

Place the Koppla on a hard surface with the plug away from you (I have a suspicion other countries may have the plug in a different spot) and the USB ports on the left end. You're aiming to cut/splt near the big heat sink that'll provide some protection if you get over enthusiastic. (I initially went for the end right hand end - and needed to do some repair work!)

Option 1: use a small cutting wheel on your dremel to open up a space to get a screwdriver in and then lever the case apart.

Option 2: hit that spot with a chisel and hammer and it should pop apart.

Once you have it open it eases out of the plastic relatively easily and then you can snip it off the pins and strip the wires and connect them to your power cable. I used a terminal block to make it a little easier, then wrapped it with electrical tape.

Wiring up the power

I didn't know whether I should ignore or use the USB circuitry. I figured it couldn't hurt so I soldered two pairs of connections onto the relevant pins on the underside of the board. I picked two as the Koppla says it is limited to 2.4A per socket and 3.4A overall. If you have two connections in parallel, voltage stays at +5V but you can deliver all 3.4A.

Once I'd tested it all (and been shocked by being careless), I hot glued it, circuit board side down, to the base of the box.

Step 5: Electronics

Buttons

I drilled three holes in the top of the box. I soldered up long leads to either side of the tactile switches, poked them through and liberally applied hot glue to the back. I used a cable tie to try and help anchor the load and spread the contact point, but I'm 99% certain it didn't actual help at all. One side of the button was wired into Gnd and the other to the Arduino.

Breadboard

I did breadboard the elements to test the theory, I failed to take a picture of it though, sorry. It showed that the display was working and allowed me to do a number of tests before finally wiring it up.

Wiring up

I've included a wiring diagram to show you how I connected everything up. You can also see some close-ups of the elements and an overall shot. As you can see, top quality soldering and tidy wiring was not the priority. I probably should have spent more time on this stage but there was plenty of space and it wasn't sufficiently complicated that it became a problem. If I did it again, I'd prefer to to a tidier job and perhaps hot glue more things down, but I'm very out of practice and I was pleased it worked. Fiddling with it after didn't seem the best of plans!

Step 6: Coding

I'm not too sure how much detail you want to see or hear from me on the coding. I'll cover an overview of the program structure, detail of the state machine and control flow logic, the algorithm I used to gradually increase the intensity of the 'sunrise' and the technique devised to display a character on the display. I'll also post the entire code so you can just take it and run - download each .ino file and stick it in a folder called "src_01_a" in the Arduino directory in your Documents area. I've tried to document the code itself, but I'm no different to any other programmer in this respect, so it's a bit sporadic (at best!)

Program structure

The code was getting pretty long, so I used the tab functionality of the Arduino IDE to split the different elements of the code into different areas. They were:

  • the main declarations and control structures;
  • the alarm sequence;
  • the different functions to change elements of the settings/configurations;
  • the main display functions to control the 'time' display;
  • the setup functions called once on startup; and
  • a bunch of utility functions called from a number of places.

In the end, the sketch used over 50% of the program and dynamic memory space. So sizeable, but manageable.

State machine and control flow

The control flow is handled through the use of a state machine variable which switches the active function based on the currentState variable. Each operating function is responsible for monitoring whether the alarm should start, any relevant buttons, the minimum and maximum temperature and altering the control flow by altering the state machine variable - including remembering the previousState.

The most common control function is repeated a number of times (I probably should have proceduralised it somehow) and is summarised below:

    if (monitorButtons()) { // which returns true if a button was pressed
       // decide which button and perform the relevant action or change the state then
       return;
    }
    if (checkAlarmStartTime()) {      // check the time and see if the alarm should start
       previousState = currentState;  // i.e. record the current state as we'll return to it once the alarm cycle is over
       currentState = ST_ALARM_ACTIVE;
       return;
    }
    updateMinMaxTemp(); // update min and max

    This set of routines is called almost continually with no use of the delay() function which could comprise both the responsiveness to the buttons and the chances of missing an event.

    Sunrise intensity

    My initial premise was that the actual sunrise produces light of varying colour in a non-linear progression over about an hour. I searched for confirmation of that, but failed again.

    I figured I'd model it over a 30 minute time period. I'm trying to get up at 6:30 every morning, but 6:00 wouldn't be too bad. I also realise that with 1-255 of range in the Blue element of each of the Neopixels x 60 Neopixels = 15,300 units that I needed to turn on in 1,800 seconds to get to maximum power!

    At first I figured I'd use some differential calculus to calculate the area under the curve of an x squared progression, but then my head fell off and I figured I'd just wing it with something approximate.

    Here's the key setup code which could be tweaked to change things around:

      const byte increase[6] = {10, 15, 30, 40, 80, 131};
      const int increaseTotal = 300;
      const byte increaseDivisions = 50;
      const unsigned long timeDelayStepsAlarmActive = 6000;

      Then in the main body:

      for (int timer = 0; timer < increaseTotal; timer++) {
        int currentspeed = timer / increaseDivisions;
          int brightnessinc = increase[currentspeed];
          while (brightnessinc > 0) {
              brightnessinc = getbrighter(currentPosAlarmActive, brightnessinc);
              if (brightnessinc > 0) currentPosAlarmActive++;
          }
         strip.show();
         // then the rest of the control structure monitoring progress, buttons etc. and wait timeDelayStepsAlarmActive

      You'll see that the for loop (timer) goes around increaseTotal (or 300) times - which is the number of times the total set of Neopixels change in the time period. Multiply it by timeDelayStepsActive (6 seconds - or 6,000 mS - the gap between changes) and you'll get to 1,800 seconds (or 1,800,000 mS.)

      The currentspeed is the timer divided by the number of divisions in the increase[] array - which is used to set how much more of the 15,300 units we get each time around (brightnessinc).

      Then while we need to add more brightness (because we might need to add it to more than one Neopixel) we use the helper function getbrighter() to add more brightness to the currentPosAlarmActive - the current Neopixel being made brighter.

      You can look up the getbrighter() function yourself, but it basically pushes the relevant Neopixel as much of brightnessinc brighter as it can and returns any left over brightness required so that we can overflow it to the next Neopixel.

      So for the first 50 loops (increaseDivisions), we add 10 units of brightness (increase[0]) and then for the next 50 loops by 15 (increase[1]) and so on. I calculated the numbers in increase[] using a spreadsheet to make sure that it got to 15,300.

      Character display

      The numbers and letters are displayed using a simple premise. The font is a 3x5 font developed by Robey Pointer on an MIT license. I encoded each row of the font as 100 for the first pixel, 10 for the second pixel and 1 for the last. It's not the most efficient use of memory space, but it is easy to spot your mistakes.

      Here's part of the definition of the font

      const byte tinyFont[19][5] = {
         { 11, 101, 101, 101, 110 },   // 0
         { 10, 110, 10, 10, 10 },      // 1
          ...

      Looking at the first two lines of the '0' character, we can see on row 1, that the column 1 is off - hence no 100, column 2 is on - hence 10 and column 3 is on - hence 1 and a total of 11 (0x100, 1x10, 1x1). Row 2 is 1x100, 0x10, 1x1) = 101.

      In the function displayDigitRow() we set the Neopixels, at position firstpixel, firstpixel + 1 & firstpixel + 2, to on (to a value of color) or off depending on these values - an excerpt is shown below.

      case 11:<br>
        strip.setPixelColor(firstpixel, off);
        strip.setPixelColor(firstpixel + 1, color);
        strip.setPixelColor(firstpixel + 2, color);
        ... // first off, second on, third on
      
      case 101:
         strip.setPixelColor(firstpixel, color);
         strip.setPixelColor(firstpixel + 1, off);
         strip.setPixelColor(firstpixel + 2, color);
         ... // on, off, on

      This is the point at which it hopefully becomes obvious as to why the display was physically constructed with the Neopixels running in a consistent order (L-R).

      Step 7: Conclusions and Wrap Up

      Does it work?

      Short answer: Yes, it has woken me naturally more often than not.

      Long answer: I've been using it for a few weeks now and it's been fascinating to see how I've woken. I have a sneaking suspicion that the 30 minute cycle I decided on is too long. I estimate I've woken within the first 10 minutes most of the time it's woken me. The key question is how it will work over the long term and I guess time will tell. It's the middle of summer and I'm curious to know how it'll help (if at all) during the winter with longer nights.

      What could I do better/improve?

      I could tweak the code to improve things:

      • The obvious is the alarm cycle and the use of all blue lights. I could experiment with different timings. It'd be nice to make the lights come on in a pattern which is more relevant to an actual sunrise.
      • There's some clear opportunities for optimisation in the code, although that's not an issue at the moment.
      • I've wondered about some alternative clock modes, maybe a more analogue type. Or one which intersperses the temperature with the time.
      • The minimum and maximum temperature is lost on power loss, but the EEPROM in the Arduino or the RTC could be used to store those values.
      • Through the day, in 99% of days, the clock is not used, but it's using power all the time. I'd like to understand a little bit more about low power modes and how I could use less power.

      Additional functionality through extra hardware:

      • I'm not convinced the temperature is a proper reflection on the actual temperature in the room. I've a sneaking suspicion it's warmed by the power module and insulated by the plastic box. Perhaps I could add an external temperature sensor.
      • I've wondered about adding, or replacing the Arduino with, an ESP8266. It can be programmed the same, but could connect to my WiFi and use an NTP server to sync the time. In theory, I could even use it to serve web pages so the device could be controlled (and the temperature monitored) via my smart phone. Probably harder than it sounds due to the requirement for 3.3V for the ESP8266 and 5V for the Neopixels.

      My first Instructable

      This is my first Instructable. It feels good to give something back to the community. I'm keen to know if this is interesting, have I got the level of detail right, am I likely to set my house on fire because I've done something stupid, how you'd improve on this or any other feedback. Let me know!