Arduino Night Light and Sunrise Alarm Project

James Bruce 06-01-2014

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 Use These Apps to Help You Sleep Better [Android & iOS] After a hectic day, the best thing you can do is to get a beneficial amount of sleep. There are always new studies appearing that prove how important sleep really is to a person, improving... Read More that detect when best to wake you by body movements Can An App Really Help You Sleep Better? I've always been a bit of a sleep experimenter, having for much of my life kept a meticulous dream diary and studied as much as I could about sleeping in the process. There are a... Read More , 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 Build Your Own Dynamic Ambient Lighting For A Media Center If you watch a lot of movies on your PC or media center, I'm sure you've faced the lighting dilemma; do you completely turn off all lights? Do you keep them on full blast? Or... Read More 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 Home Automation Guide With Raspberry Pi and Arduino The home automation market is flooded with expensive consumer systems, incompatible with one another and costly to install. If you have a Raspberry Pi and an Arduino, you can basically achieve the same thing at... Read More .

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.



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){

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:");
     //during ramp up, write the current value of minutes X brightness increment
     if(currentVal < 255){
     else if(currentMinutes - minutesUntilSunrise < 40){
       // once we're at full brightness, keep the lights on for 10 minutes longer
        //after that, we're nuking them back to off state

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!

Whatsapp Pinterest

Enjoyed this article? Stay informed by joining our newsletter!

Enter your Email

Leave a Reply

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

  1. Stephanie
    April 2, 2018 at 1:45 pm

    I am totally new to arduino and programming, but i want to build the sunrise alarm clock for a project at university. I connected the arduino with my laptop (but with nothing else, because first I wanted to check if the code is able to be uploaded) so I tried to upload the codes, but I got an error message for this line:

    currentMillis = millis() - previousMillis; // this keeps our currentMillis the same each day

    it says that "'previousMillis' was not declared in this scope" could somebody help me with this problem? It would be great if I could make the sunrise alarm clock by following this tutorial ! :)

    • James Bruce
      April 2, 2018 at 1:56 pm

      Hi Stephanie, it sounds like you've copied only a portion of the code from the article - you need to grab the full version from here:

      You're getting that error because the bit of code where we create a variable called previousMillis isn't in the short bit of code you have, so it doesn't know what it is.

  2. Koen G.
    March 21, 2015 at 9:45 pm

    I got a similar leak problem with my led strip and fixed it by placing some large resistors (mega ohms) parallel to the rgb channels.

  3. Dave
    February 15, 2015 at 11:29 pm

    It doesn't look like the black side of your 12v power supply is connected to anything. Is that how it is supposed to be?

    • James Bruce
      February 16, 2015 at 9:50 am

      Nope, that's a mistake, connect all the grounds. Good catch, totally intentional! ;)

    • Dave
      February 16, 2015 at 2:14 pm

      Even the arduino ground? I burned out 2 of them

    • James Bruce
      February 16, 2015 at 2:26 pm

      Grounds should always be connected, yes. I'm not sure how you could burn one out unless you accidentally connected a +ve terminal to them, causing a short.

  4. Heine
    February 3, 2014 at 9:08 pm


    actually I'm currently working on something similar. I'm using IRL3705N Mosfets which are working quite fine to control the LEDs. Also working are IRLB8721 Mosfets.

    The Motion Sensor is an interesting idea. I will keep this in mind.

    • James B
      February 4, 2014 at 9:18 am

      Fantastic, thanks Heine, I'll order a bunch of them ;)

  5. Sergio
    January 10, 2014 at 10:44 am

    I usually use irlml2502 mosfets, but they are tiny and difficult to solder/work with. I just did a quick ebay search and checked, and it looks as if STP75N3LLH6 are logic level and aren't too expensive. Great project btw.

  6. Sergio
    January 6, 2014 at 8:41 pm

    I think the mosfets u used aren't logic level mosfetts. That may be the problem with the leak.

    • James B
      January 10, 2014 at 10:23 am

      Thank you Sergio, that makes sense. Any idea what the equivalent logic level mosfets would be?