Smart Alarm Clock/Light

Purpose

Design an alarm clock that attempts to gently wake the user with light prior to the abrasive noise that is a fail safe should the user not wake up. Also functions as a regular light during other times of the day and removes blue light in the evening in order to help the user naturally ease into sleep.

Components

  • mbed Chip
  • Text LCD
  • Push Buttons
  • Speaker with Driver Transistor
  • Shiftbrite RGB LED

Function

Alarm can be set using the push buttons. Push button one is used to add one hour to the alarm set time, push button two is used to add one minute, and push button three is used to turn the alarm off if it is sounding or toggle the light on/off if it is not.

Smart Alarm

#include "mbed.h"
#include "TextLCD.h"
#include "PinDetect.h"
#include "rtos.h"

Mutex stdio_mutex;
PinDetect pb1 (p20);
PinDetect pb2 (p19);
PinDetect pb3 (p18);
Serial pc(USBTX, USBRX);
TextLCD lcd(p22, p23, p24, p25, p26, p27); // create a global lcd object
DigitalOut latch(p15);
DigitalOut enable(p16);
PwmOut speaker (p21);
//Cycles through different colors on RGB LED
SPI spi(p11, p12, p13);
//Use SPI hardware to write color values to LED driver chip
float currseconds;
float currminutes;
float currhours;
float currtime = 28450;
bool pm = 0;
bool alarmpm;
bool lightswitch=1;    
float alarmtime = 28800;
float alarmhours;
float alarmminutes;
bool alarming = 0;
int alarmstate = 0;

//Declare the LCD and set up SPI communication
void RGB_LED(int red, int green, int blue) {
    unsigned int low_color=0;
    unsigned int high_color=0;
    high_color=(blue<<4)|((red&0x3C0)>>6);
    low_color=(((red&0x3F)<<10)|(green));
    spi.write(high_color);
    spi.write(low_color);
    latch=1;
    latch=0;
}


//Set up hour increment push button
void pb1_hit_callback (void){
    alarmtime+=3600;
}
//Set up minute increment push button    
void pb2_hit_callback (void){
    alarmtime+=60;
}

//Set up pushbutton to disable the alarm when ringing or toggle the light on/off when not    
void pb3_hit_callback (void){
    if (alarming == 1){
        speaker = 0.0;
        alarming =0;
        alarmstate = 1;
        }
    else lightswitch = !lightswitch;
    
}

//Thread running to check if the alarm should trigger
void alarm_trigger(void const *args) {
    alarmhours = floor(alarmtime/3600);
    alarmminutes = floor(fmod((alarmtime/60),60));
    while(1){
        if((alarmtime-currtime) <= 300 && (alarmtime-currtime) > 100){
            int red=50;
            int green=0;
            int blue=0;
            spi.format(16,0);
            spi.frequency(500000);
            enable=0;
            latch=0;
            alarmstate = 0;
            //Hard coded 5 minute light warm up prior to alarm ringing
            for (red = 0;red<50;red++){
                RGB_LED(red,green,blue);
                wait(2);
            }
            for (green = 0; green<50; green+=1) {
                RGB_LED( red, green, blue);
                wait(2);
            }
            for (blue = 0; blue<50;blue+=1){
                 RGB_LED(red,green,blue);
                 wait(2);
            }
        }
            
        if(alarmminutes == currminutes && alarmhours == currhours && alarmstate == 0){
                 alarming = 1;
        }
                
        
    }
}

//Thread running to determine the color of light dependant on time of day. no blue light after 7 pm and between alarm
void lights(void const *args) {
      spi.format(16,0);
      spi.frequency(500000);
      enable=0;
      latch=0;    
      int state=2;
      while(1){
           if((alarmtime-currtime) > 300 || (alarmtime-currtime) <=0){
               if (lightswitch == 1&& state !=1){
                   if(((currtime < alarmtime)||(currtime >= 68400)) && state != 1){
                       RGB_LED(50,24,0);
                       state = 1;}
                   else if ((currtime > alarmtime && currtime < 68400) && state !=2){
                       RGB_LED(50,50,50);
                       state = 2;}   
                }
               else if (lightswitch == 0 && state != 0){
                     stdio_mutex.lock();
                     RGB_LED(0,0,0);
                     state = 0;
                     stdio_mutex.unlock();
              }
           }
            
        Thread::wait(100); 
      }
}

//Triggers the speaker when the alarm is triggered
void alarm(void const *args) {
    while(1){
           if(alarming == 1){
                    
                    speaker.period(1.0/300);
                    stdio_mutex.lock();
                    speaker = .5;
                    stdio_mutex.unlock();
                    wait(.5);
                    stdio_mutex.lock();
                    speaker=0.0;
                    stdio_mutex.unlock();
                    wait(.5);
                }
    }
}
           
//Main thread. Time management, breaks down second counter to hours and minutes and prints to LCD    
int main() {
    wait(.2);
    Thread t2(alarm_trigger);
    Thread t3(lights);
    Thread t4(alarm);
    // Setup Interrupt callback functions for a pb hit
    pb1.attach_deasserted(&pb1_hit_callback);
    pb2.attach_deasserted(&pb2_hit_callback);
    pb3.attach_deasserted(&pb3_hit_callback);
    // Start sampling pb inputs using interrupts
    pb1.setSampleFrequency();
    pb2.setSampleFrequency();
    pb3.setSampleFrequency();
    // pushbuttons now setup and running


    speaker.period(1.0/300.0);
    pc.printf("Running");
    
    while (1){
        if (currtime > 86400) currtime = 0;
        currtime ++;
        if (currtime > 43200) pm = true;
        else pm = false;
        currhours = floor(currtime/3600);
        currseconds = floor(fmod(currtime,60));
        currminutes = floor(fmod((currtime/60),60));
        if (alarmtime >= 86400) alarmtime = alarmtime-86400;
        if (alarmtime >= 43200) alarmpm = true;
        else alarmpm = false;
        alarmhours = floor(alarmtime/3600);
        alarmminutes = floor(fmod((alarmtime/60),60));
        if (pm == false){
            if (currhours==0) currhours = 12;
            if (alarmpm == false){
                if (alarmhours==0) alarmhours = 12;
                lcd.cls();
                lcd.printf("%02.0f:%02.0f:%02.0f AM\n%02.0f:%02.0f AM", currhours,currminutes,currseconds,alarmhours,alarmminutes);
            }
            if (alarmpm == true){
                alarmhours = alarmhours - 12;
                if (alarmhours == 0) alarmhours = 12;
                lcd.cls();
                lcd.printf("%02.0f:%02.0f:%02.0f AM\n%02.0f:%02.0f PM", currhours,currminutes,currseconds,alarmhours,alarmminutes);
            }
        
        }
        if (pm == true){
            currhours = currhours - 12;
            if (currhours == 0) currhours = 12;
            if (alarmpm == false){
                if (alarmhours==0) alarmhours = 12;
                lcd.cls();
                lcd.printf("%02.0f:%02.0f:%02.0f PM\n%02.0f:0%2.0f AM", currhours,currminutes,currseconds,alarmhours,alarmminutes);
            }
            if (alarmpm == true){
                alarmhours = alarmhours - 12;
                if (alarmhours == 0) alarmhours = 12;
                lcd.cls();
                lcd.printf("%02.0f:%02.0f:%02.0f PM\n%02.0f:%02.0f PM", currhours,currminutes,currseconds,alarmhours,alarmminutes);
            }
        }


        wait(1);
        }
    
    
}


Please log in to post comments.