Project tutorial

Wake Me Up! © GPL3+

Can light wake you up in the morning?

  • 5,032 views
  • 7 comments
  • 31 respects

Components and supplies

About this project

Winter is coming, nights become longer than days, and it’s a nightmare for me to wake up at 6am into a dark and cold room. What if there was a way to create artificial “sunrise” to make the room feel much warmer and pleasant?

This is an easy task, I am going to create a smart light bulb that fits into my current ceiling lamp. It will simulate a sunrise by slowly light up the room. If it works I am going to connect it with my phone to make it a proper alarm clock.

Lightbulb

To create a smart lightbulb you first need a "dumb" bulb because of its socket that is screwed into lamp and provides power supply. I smashed it with a hammer. This delight procedure removed the glass from the aluminum socket and after soldering wires to socket and pin at the bottom, the base of the smart lightbulb was ready.

Next, you need a support for all the electronics. I used a perf board and cut it to fit an Arduino Nano microcontroller, 5V power supply, and all the electronics components.

High voltage circuit

Safety warning: You are working with voltages greater than 50V. Contact with high voltage may result in severe injury or death.

Since I am using a regular light bulb which is powered from AC mains voltage I cannot directly use microcontroller to control the power going to the light bulb. I need a TRIAC. This little device acts as a relay that can switch on and off pretty quickly. The microcontroller will power on and off the triac in order to alter the AC sine wave, thus dimming or brightening the light.

However, AC voltage is controlled differently than DC voltage. AC sine wave needs to be cut in precise manners and so triac have to be turned on and off in precise moments to achieve that (see image below). In other words, microcontroller needs to know when the sine wave of mains voltage crosses zero to cut each of the half waves to the same size. Otherwise, the light would be flickering.

To detect zero crossing of mains voltage there is a 4N35 (U1) optocoupler with a transistor which turns on when sine wave crosses zero. The microcontroller will see that as a high signal on its input pin. Optocoupler has another function, it is to isolate the low voltage from the mains voltage circuit.

Second optocoupler - MOC3063 (U2) - with a triac on output is used to isolate microcontroller from high voltage triac (Q2). Make sure you are not using optocoupler with zero-cross feature because it only switches on when sine wave crosses zero.

Low voltage circuit

As a microcontroller, I am using Arduino Nano. Its main purpose is to control triac and to start turning on the light when the set time comes. To provide real-time clock there is DS3231 accurate real time clock module which also preserves time when power is lost.

To provider 5V for chips, I am using cheap 5V 700mA step-down power supply connected to mains voltage from bulb socket. Nice and handy solution!

Code

The program is pretty simple. When the lamp is powered up by the switch it will light up the room an slowly dim it into the night as a verification that electronics still work. During the night it checks the real-time clock stored in the DS3231 module and finally at 6 am the room is slowly light up to full "daylight" until the lamp is powered off by the switch.

Check out the code attached below I think its self-explanatory. If it's not I am a bad developer!

What's next?

Now I will experiment for a few days or weeks and if it can wake me up in the morning I will evolve this project into something more smarter and less crude!

Good night!

Code

lightalarm.inoArduino
A smart light bulb that lights up when its time to get out of your bed.
/*
A smart light bulb that lights up when its time to get out of your bed.

How it works:
1) when power is turned on, the light is switched on as a check that it works
2) it will slowly dim until turned off completelly
3) at 6 am in the morning light will slowly turn on until switched off at the evening
4) light will not turn on when room is not dark anymore (photocell)

How to use:
- turn on the light when going to bed and it will light up the room when you wake up in the morning, turn off light when leaving room to turn it off.
- the time will be preserved due to the DS3231 module

@author Jiri Praus (https://twitter.com/jipraus)

AC Light control inspired by http://arduinotehniq.blogspot.com/2014/10/ac-light-dimmer-with-arduino.html
*/

#include <TimerOne.h> // avaiable from http://www.arduino.cc/playground/Code/
#include "RTClib.h"

#define TRIAC_PIN 2
#define ZERO_CROSS_PIN 3
#define LIGHT_SENSOR_PIN A6

#define FREQUENCY_STEP 75 // This is the delay-per-brightness step in microseconds for 50Hz (change the value in 65 for 60Hz)
#define CHANGE_DIM_LEVEL_EVERY 1 // change dim level every N seconds, slowness of brightining/dimming

#define MAX_DIM_LEVEL 128 // off
#define MIN_DIM_LEVEL 0 // on
#define DARK_THRESHOLD 300 // resistance of photocell when it is consider dark outside

// triac control variables
volatile byte triacCounter = 0; // triac control timer
volatile boolean zeroCrossed = false; // AC phase zero-crossed flag

// dim control
byte dimLevel = MIN_DIM_LEVEL; // on power on, the light is on and will dim slowly as a check
boolean lightOn = false;

// alarm clock
RTC_DS3231 rtc;

void setup() {
  Serial.begin(115200);

  digitalWrite(TRIAC_PIN, LOW);
  pinMode(TRIAC_PIN, OUTPUT);
  pinMode(ZERO_CROSS_PIN, INPUT);
  pinMode(LIGHT_SENSOR_PIN, INPUT);

  // init real time clock
  if (!rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while(1);
  }
  if (rtc.lostPower()) {
    Serial.println("RTC lost power, lets set the time!");
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // following line sets the RTC to the date & time this sketch was compiled
  }

  // initialize interrupts and timers for triac control
  noInterrupts();
  attachInterrupt(digitalPinToInterrupt(ZERO_CROSS_PIN), zeroCrossDetected, RISING); // Attach an Interupt to Pin 2 (interupt 0) for Zero Cross Detection
  interrupts();

  Timer1.initialize(FREQUENCY_STEP);
  Timer1.attachInterrupt(triacTimerInterrupt, FREQUENCY_STEP);
}

void loop() {
  delay(CHANGE_DIM_LEVEL_EVERY * 1000);
  checkAlarmClock();
  adjustDimLevel();

  debugPrint();
}

void zeroCrossDetected() {
  zeroCrossed = true; // set the boolean to true to tell our dimming function that a zero cross has occured
  triacCounter = 0; // start counting when triac should be opened
  digitalWrite(TRIAC_PIN, LOW); // turn off light
}

void triacTimerInterrupt() {
  if (dimLevel >= MAX_DIM_LEVEL) { // permanently off
    digitalWrite(TRIAC_PIN, LOW);
  }
  else if (dimLevel <= MIN_DIM_LEVEL) { // permanently on
    digitalWrite(TRIAC_PIN, HIGH);
  }
  else if (zeroCrossed) {
    if (triacCounter >= dimLevel) {
      digitalWrite(TRIAC_PIN, HIGH); // open triac
      zeroCrossed = false; // reset zero cross detection until next half vawe
    } 
    else {
      triacCounter ++;  // increment time step counter
    }
  }
}

void adjustDimLevel() {
  if (lightOn && dimLevel > MIN_DIM_LEVEL) {
    dimLevel--;
  }
  else if (!lightOn && dimLevel < MAX_DIM_LEVEL) {
    dimLevel++;
  }
}

void checkAlarmClock() {
  if (!lightOn && isRoomDark()) { // do not waste energy when room is already light up
    DateTime now = rtc.now();
    if (now.hour() == 6 && now.minute() == 0) {
      lightOn = true; // start alarm clock at 6am
    }
  }
}

boolean isRoomDark() {
  return analogRead(LIGHT_SENSOR_PIN) < DARK_THRESHOLD;
}

void debugPrint() {
  Serial.print("lightOn=");
  Serial.println(lightOn);
  
  Serial.print("dimLevel=");
  Serial.println(dimLevel);
  
  DateTime now = rtc.now();
  Serial.print("datetime=");
  Serial.print(now.year(), DEC);
  Serial.print('/');
  Serial.print(now.month(), DEC);
  Serial.print('/');
  Serial.print(now.day(), DEC);
  Serial.print(" ");
  Serial.print(now.hour(), DEC);
  Serial.print(':');
  Serial.print(now.minute(), DEC);
  Serial.print(':');
  Serial.println(now.second(), DEC);

  Serial.print("lightLevel=");
  Serial.println(analogRead(LIGHT_SENSOR_PIN));
}

Schematics

Schematics of high voltage circuit
Highvoltage vkgjauqgyc
Schematics of low voltage circuit
Lowvoltage 3v6liedicd

Comments

Similar projects you might like

Animated RGB Wall Clock

Project tutorial by TheTNR

  • 9,067 views
  • 6 comments
  • 36 respects

RFID Desk Lamp

Project tutorial by Kutluhan Aktar

  • 1,231 views
  • 0 comments
  • 3 respects

Adjusting Clock on 128×64 Monochrome Display (ST7920)

Project tutorial by FLORICA Tudor-Nicusor

  • 1,517 views
  • 0 comments
  • 10 respects

Home Automation system using Raspberry Pi

Project tutorial by Christian Kratky

  • 127,562 views
  • 34 comments
  • 404 respects

Arduino Compatible Nano NeoPixel Controller

Project tutorial by Team Whimsy Makerspace

  • 14,534 views
  • 1 comment
  • 17 respects

Arduino - PV MPPT Solar Charger

Project tutorial by Abhi Verma

  • 13,392 views
  • 4 comments
  • 23 respects
Add projectSign up / Login