Arduino Night Light and Sunrise Alarm Project

Humans are naturally programmed to wake up with the sunrise; sadly modern life is dictated by an arbitrary clock, often forcing us to wake up when there is no natural light. Today, we’ll be making a sunrise alarm clock, which will gently and slowly wake you without resorting to an offensive noise-making machine.

If making a sunrise alarm clock is a little too much for you, check out these iPhone and Android apps that detect when best to wake you by body movements, ensuring you’re not pulled away from that awesome dream but instead, wake up feeling bright and refreshed – they really do work.

Project Outline

The main part of the project will be some 5 metre LED strip light laid around the bed. We’ll power these with an external 12 volt supply, switched using some MOSFET N transistors. The setup for this part will be identical to the dynamic lighting system I built before.

Timing will be an issue – since this is a prototype, I’ll be setting the Arduino to count down from whenever it is reset. In theory, we should only lose a second or two each day, but ideally we would include an “real time clock” chip to do this more reliably. The sunrise alarm will start 30 minutes before wake-up time, and slowly increase output level until it’s at 100% brightness – this should be enough to wake us up, though it’s a good idea to keep using your regular alarm clock until your body is used to it.

I’ll also be incorporating a night light into this project, which detects movement and activates a discreet low level light under the bed with a 3 minute time out, separate to the LED lights as those would cause both my wife and I to wake up. The under-bed lighting will be a commercial mains unit, so I’ll hack a relay inside a plug socket to turn that on and off. If you’re not comfortable working with 110-240v AC mains power under any circumstances (and that’s generally a good rule to have), then wire up a 433 MHz wireless transmitter with switching sockets, as outlined on the Raspberry Pi Arduino home automation project.

Parts List and Schematic

  • Arduino
  • Set of RGB LED strip lights
  • 12 volt power supply
  • 3 x MOSFET N transistors (I use type STP16NF06FP)
  • Relay and power socket, or wireless controlled sockets and suitable transmitter
  • Your choice of night light (regular mains powered with plug is fine)
  • PIR movement sensor (HC-SR501), or an SC-04 sonar (not as effective)
  • Light sensor
  • Project code – but do read on to make sure you understand how to customise everything.

Here’s the complete schematic.

Ads by Google


Wiring Up a Relay

Note: Skip this section if you want to use the RGB lights as a night light as well – this is specifically for switching on a separate mains powered light. 

For switching mains power, your relay will need to rated for voltage – 110V or 240V AC depending on where you live – and more than the total amperage you will be switching. The one I’ve used from this sensor pack (disclaimer: that’s my shop) is 250VAC / 10A, so we should be safe. Relays have a com port, usually in the center, which should be connected to the live wire coming into the plug; then connect the socket live terminal to the NO (normally open). I shouldn’t have to tell you not to do this wile it’s plugged into an outlet, or you’re going to die. If you’re afraid of messing with mains power, use wireless switched sockets instead.


The earth and neutral cables should go straight to the socket and will not touch the relay. You may not have an earth line in the US. It’s your responsibility to know the colour coding of wires in your local area – if you couldn’t otherwise wire up a regular socket in your home or rewire a plug, don’t try embedding a relay into one!

To test, wire the relay signal pin to 12, then run a simple blink program modified to work on pin 12, not 13 as is default. Your socket should turn on and off every few seconds. The reason why I’m not using pin 13 is because during the upload process, the onboard LED fires in quick succession to indicate serial activity, which would cause the relay to activate too.

Getting Timing Right

Timing and clock functions are difficult without access to a network connection or dedicated Realtime Clock (these include their own batteries to keep the clock going even when the main Arduino has no power). To keep costs low, I’m going to cheat. I’ll be hardcoding a start time for the Arduino to begin it’s countdown; timings will therefore be relative to this start time. Each 24 hours, the clock will reset. The clock function code below makes sure the global variables currentMillis and currentMinutes are correct each day. The Arduino shouldn’t lose more than a few seconds every 45 days; however, this hard-coded style of timing is quite limited in that a power cut or accidental reset will break everything, so this is certainly one area that could be improved upon. If timing does get out of sync, simply reset the Arduino at your set starting time.

The code should be easy to understand.

void clock(){     if(millis() >= previousMillis+86400000){        // a full day has elapsed, reset the clock;        previousMillis +=86400000;     }     currentMillis = millis() - previousMillis; // this keeps our currentMillis the same each day     currentMinutes = (currentMillis/1000)/60;  }  

Night Light Function

I’ve separate the main loops into distinct functions so it’s easier to read and remove or adjust. The nightLight() function only operates between the hours of when the Arduino was reset (I’m assuming you’ll probably do this on or around bedtime, when it’s dark), and until the sunrise alarm is due to begin. I had initially tried to use a light-dependent resistor, but they’re not very sensitive to blue light (which happens to be the colour I’m using for the night light), and difficult to calibrate right. Using the clock makes more sense, anyway. We’ll use the global currentMinutes variable, which gets reset each day.

The PIR sensor can be be a little quirky if you’ve never used one before, though wiring it up isn’t difficult – you’ll find VCC, GND, and OUT clearly labelled on the back. There are two variable resistors thee too; the one labelled RX determines range (up to about 7m), and another labelled TX determines delay. The delay is 5 seconds at it’s lowest setting (fully anti-clockwise), and means that any momentary movement will trigger at least 5 seconds of “on” state from the sensor. However, it also determines the delay between active states – so if 5 seconds elapses and no movement is detected, the sensor will send a low signal for at least 5 seconds even if there is movement during that period. If you have the delay set really high at around 30 seconds, it can seem like the sensor is broken.


If you’re sleeping alone and don’t mind using the same RGB strip lights for both the sunrise alarm and night light, you should be able to adjust the code easily enough.

void nightlight(){      // Only work between the hours of reset -> sunrise.     if(currentMinutes < minutesUntilSunrise){      if(digitalRead(trigger) == 1){        nightLightTimeOff = millis()+nightLightTimeOut; // activate, or extend the time until turning off the light        Serial.println("Activating nightlight");      }    }     //Turn light on if needed    if(millis() < nightLightTimeOff){      digitalWrite(nightLight,HIGH);    }    else{      digitalWrite(nightLight,LOW);    }  }  

Sunrise Alarm

For simplicity, I’ll use the RGB colour value 255,255,0 for a deep yellow sunrise – this way the increment on both colour channels will be the same. If you find it’s waking you up too early, consider starting with a deep red and fading toward yellow or white. The ramp up I’ve used in just linear – you may want to investigate using a more natural curve for brightness values.

The function is simple – it works out how much the light should be incremented by each second such it’s at full brightness after a 30 minute period; then multiplies that by however many seconds it’s currently into the sunrise. If it’s already at full brightness, it stays on for further 10 minutes to make sure you’re up (and if you’re still not up, you should probably have a backup alarm in place).

void sunrisealarm(){     //each second during the 30 minite period should increase the colour value by:    float increment = (float) 255/(30*60);      //red 255 , green 255 gives us full brightness yellow      if(currentMinutes >= minutesUntilSunrise){       //sunrise begins!        float currentVal = (float)((currentMillis/1000) - (minutesUntilSunrise*60)) * increment;       Serial.print("Current value for sunrise:");       Serial.println(currentVal);       //during ramp up, write the current value of minutes X brightness increment       if(currentVal < 255){         analogWrite(RED,currentVal);         analogWrite(GREEN,currentVal);       }       else if(currentMinutes - minutesUntilSunrise < 40){         // once we're at full brightness, keep the lights on for 10 minutes longer         analogWrite(RED,255);         analogWrite(GREEN,255);       }       else{          //after that, we're nuking them back to off state          analogWrite(RED,0);          analogWrite(GREEN,0);        }    }  }  

Pitfalls and Future Upgrades

I’ve been using this for the past few weeks now and it’s really helping to wake up feeling more refreshed and at a decent time; the nightlight works really well too. It’s not perfect though, so here’s a few things that need work and lessons learnt during construction.


While making this project, I encountered lots of issues of dealing with large numbers, so if you plan on modifying the code please bear this in mind. In C language, the typing of your variables is very important – a number is not always just a number. For instance, unsigned long variables should be used to store super large numbers like we deal with when talking about milliseconds, but even a number as small as 60,000 cannot be stored as a regular integer (an unsigned int would have been acceptable for up to 68,000). The point is, read up on your variable types when using big numbers, and if you’re finding odd bugs, it’s probably because one of your variables doesn’t have enough bits!

I’ve also found an issue with very low brightness voltage leaks – leading to the tiniest amount of light being emitted even when a digitalWrite(RED,0) signal is emitted – I don’t think it’s hardware problem with the strips since they work fine with the official controllers. If anyone can solve this problem, pictured below, I would be most grateful. I’ve tried pull down resistors, and limiting the output voltage from the Arduino pins. I may need to add a simple power switching circuit to only supply voltage to the LED strip when actually needed; or it could be faulty MOSFETs.


For future work, I’m hoping to add in an IR receiver and duplicate some of the features of the original controller – at least the ability to change colours as a general use light, as right now this project turns the strip into a dedicated night light. I may even add an automatic 30 minute timeout function.

Have you tried this, made improvements, or got any other ideas? Let me know in the comments!

Leave a Reply

Your email address will not be published. Required fields are marked *