Hearing Impaired Alarm Clock Source Code (Arduino)

Below is the Arduino source code for the hearing impaired alarm clock described in detail on this post. The code was originally split into a number of different tabs for the sake of readability. There is a break in the code boxes at the end of each tab.

// Setup the LCD
#include <SoftwareSerial.h>
#define txPin 3
// since the LCD does not send data back to the Arduino,
// we should only define the txPin
SoftwareSerial LCD = SoftwareSerial(0, txPin);

// Declare Variables
// I/O variables
int inPin = 2;  // North Button (Menu/enter)
int inPin2 = 4; // West Button (Back)
int inPin3 = 6; // South Button (Snooze/Enter)
int inPin4 = 8; // East Button (FWD)
int alarmPin = 12; // output pin to trigger relay
boolean light_active = false; // value of 1 indicates relay (light) is on
int mode = 2; // 1:clock, 2:alarm active, 3:alarm sounding, 4:alarm snoozing
int flash_period = 1000;  // period to flash light while sounding alarm

// Alarm variables
unsigned long snooze_time = 300000; // time in miliseconds to snooze
unsigned long t_rewake;  // time to rewake after snoozing
unsigned long t1; // last time that light was turned on
unsigned long t2; // current time

// variables for telling time
unsigned long previous_millis_value = 0; // holds value between function calls
unsigned long current_millis_value;
unsigned int m;
unsigned int hours;
unsigned int minutes;
unsigned int seconds = 55;

// variables for setting time/alarms
int new_hour=0;
int new_min=0;
int alarm_hr = 0;  // hour to set off the alarm
int alarm_min = 1; // minute to set off the alarm

void setup()
{
  // initialize LCD as serial port
  pinMode(txPin, OUTPUT);
  LCD.begin(9600);
  Serial.begin(9600);
  backlightOn();
  clearLCD();

  // Pins for white buttons
  pinMode(inPin, INPUT);
  pinMode(inPin2, INPUT);
  pinMode(inPin3, INPUT);
  pinMode(inPin4, INPUT);

  // pin to trigger relay
  pinMode(alarmPin, OUTPUT);
}

void loop()
{  

  time();          // call function that tells time

  //*
  Serial.print(hours);
  Serial.print(':');
  Serial.print(minutes);
  Serial.print(':');
  Serial.println(seconds);
  //*/

    // Mode == 2?
  if(mode == 2){
    modeIsTwo();  // call function to print alarm time and test for alarm
  }

  // Mode <= 2 ?
  if(mode <=2){
    mode_LT_2(); // set menu, toggle alarm, toggle light
  }

  // Mode >= 3 ?
  if(mode >=3){
    mode_GT_3(); // cancel alarm. snooze, flash light
  }

  delay(100);
}
void toggle_alarm(){  // toggle the alarm state
  // if on turn off
  if(mode == 2){
    mode = 1; // clock only
    selectLineTwo();
    LCD.println("Alarm Off");
    Serial.println("Alarm Off");
    delay(3000);
    clearLCD();
  }

  // if off turn on
  else
  {
    mode = 2;  // alarm active
    selectLineTwo();
    LCD.println("Alarm ON");
    Serial.println("Alarm On");
    delay(3000);
    clearLCD();
  }
}

void flash_light(int period){ //check if enough time has passed to toggle the light
  Serial.println("Flashing");
  if (millis() >= (t1 + period) ){
    toggle_light();
    t1 = millis();
  }
}

void light_on(){  // turn on the relay (ie: light)
  digitalWrite(alarmPin,HIGH);
  light_active = true;
}

void light_off(){  // turn off the relay (ie: light)
  digitalWrite(alarmPin,LOW);
  light_active = false;
}

void toggle_light(){  // toggle the status of the relay (light)
  if(light_active){
    light_off();
  }
  else{
    light_on();
  }
}
void selectLineOne(){  //puts the cursor at line 0 char 0.
   LCD.print(0xFE, BYTE);   //command flag
   LCD.print(128, BYTE);    //position
}
void selectLineTwo(){  //puts the cursor at line 0 char 0.
   LCD.print(0xFE, BYTE);   //command flag
   LCD.print(192, BYTE);    //position
}
void goTo(int position) { //position = line 1: 0-15, line 2: 16-31, 31+ defaults back to 0
if (position<16){ LCD.print(0xFE, BYTE);   //command flag
              LCD.print((position+128), BYTE);    //position
}else if (position<32){LCD.print(0xFE, BYTE);   //command flag
              LCD.print((position+48+128), BYTE);    //position
} else { goTo(0); }
}

void clearLCD(){
   LCD.print(0xFE, BYTE);   //command flag
   LCD.print(0x01, BYTE);   //clear command.
}
void backlightOn(){  //turns on the backlight
    LCD.print(0x7C, BYTE);   //command flag for backlight stuff
    LCD.print(157, BYTE);    //light level.
}
void backlightOff(){  //turns off the backlight
    LCD.print(0x7C, BYTE);   //command flag for backlight stuff
    LCD.print(128, BYTE);     //light level for off.
}

void no_cursor(){ // turns off the cursor DOES NOT WORK
    LCD.print(0xFE, BYTE);   //command flag
    LCD.print(0x0C, BYTE);   //turn cursor off
}

void serCommand(){   //a general function to call the command flag for issuing all other commands
  LCD.print(0xFE, BYTE);
}
int time()
{
  unsigned int display_hours; // converted value of 24 HR time into tradional time

  // Calculate Time based on eleapsed time since last time calculation
  current_millis_value = millis();
  m += current_millis_value - previous_millis_value;
  seconds += m / 1000;
  m = m % 1000;
  minutes += seconds / 60;
  seconds = seconds % 60;
  hours += minutes / 60;
  minutes = minutes % 60;
  hours = hours % 24; // variable for time keeping
  display_hours = hours % 12;  // variable for displaying time
  if(display_hours == 0){  // make 12 show up instead of zero
    display_hours = 12;
  }
  previous_millis_value = current_millis_value;

  // Display time in 12 Hr format on LCD
  goTo(16);                         // first position, second line on LCD
  LCD.print(display_hours);
  LCD.print(':');
  LCD.print(minutes);
  //* uncomment to add seconds to clock
  LCD.print(':');
  LCD.print(seconds);
  //*/

  // print AM or PM after time
  AMPM(hours);
}

void AMPM(int t){
  // Note to self: 12PM == noon, 12Am == midnight
  if( t >= 12 ){ //
    LCD.println(" PM");
  }
  else
  {
    LCD.println(" AM");
  }
}
void adjust_light(int pin1, int pin2){
  int light = 0;
  int var;
  do
  {
    delay(100);
    if (debounce(pin1,30)){
        clearLCD();
        selectLineOne();
        LCD.print("Adjust Backlight");
        selectLineTwo();
        light = ++light;
        if(light > 30){
          light = 0;
        }
        LCD.print(light);
        var = light + 128;
        LCD.print(0x7C, BYTE);   //command flag for backlight stuff
        LCD.print(var, BYTE);
    }
  }while (!debounce(pin2,30));

}
// debounce digital pin input
boolean debounce(int pinnum, int bounce_time){
  int x = 0; // counter
  int val=0; // holds state op pin
  int result; // output
  do{

    x=++x;
    val = digitalRead(pinnum);
    delay(1);
  }
  while (x < bounce_time + 1 && val == 1 );

  if (x >= bounce_time){
    result = true;
  }
  else{
    result = false;
  }

  return result;
}
void modeIsTwo(){
 Serial.println("modeIsTwo");
  // Display alarm setpoint
  alarm_set_point();

  // Is it time to sound alarm?
  if(alarm_hr == hours && alarm_min == minutes && seconds <= 7){
    mode = 3;
    t1 = millis();
  } 

}

// FUNCTION: display the alarm setpoint
void alarm_set_point(){
  int display_alarm_hours;
  display_alarm_hours = alarm_hr % 12;  // variable for displaying time
  if(display_alarm_hours == 0){  // make 12 show up instead of zero
    display_alarm_hours = 12;
  }
  goTo(6);
  LCD.print(display_alarm_hours);
  LCD.print(":");
  LCD.print(alarm_min);
  AMPM(alarm_hr); // print AM or PM after time
}
void mode_GT_3(){
  Serial.println("mode_GT_3");

  // Button 2 and 4: Stop sounding alarm
  if(!debounce(inPin,20) && debounce(inPin2,20) && !debounce(inPin3,20) && debounce(inPin4,20)){
    mode = 2;
    Serial.println("mode_GT_3:mode = 2, light off");
    clearLCD();
    goTo(16);                         // first position, second line on LCD
    LCD.print("Alarm Reset");
    delay(3000);
    clearLCD();
    light_off();
  }

  // Button 3: Snooze
  if(!debounce(inPin,20) && !debounce(inPin2,20) && debounce(inPin3,20) && !debounce(inPin4,20)){
    mode = 4;
    t_rewake = millis() + snooze_time; // rewake time in milliseconds
    light_off();
  }  

  // Mode == 4?
  if(mode == 4){
    Serial.println("mode is 4");
    if(millis() >= t_rewake){
      mode = 3;
    }
  }

  // Mode == 3?
  if(mode == 3){
    Serial.println("mode is 3");
    flash_light(flash_period);
  }
}
void mode_LT_2(){
Serial.println("mode_LT_2");
  // Button 1
  if(debounce(inPin,20) && !debounce(inPin2,20) && !debounce(inPin3,20) && !debounce(inPin4,20)){
    menu(inPin, inPin2, inPin4);
  }

  // Button 2 and 4
  if(!debounce(inPin,20) && debounce(inPin2,20) && !debounce(inPin3,20) && debounce(inPin4,20)){
    Serial.println("mode_LT_2:toggle alarm");
  toggle_alarm();
  }

  // Button 3
  if(!debounce(inPin,20) && !debounce(inPin2,20) && debounce(inPin3,20) && !debounce(inPin4,20)){
  toggle_light();
  delay(1000);
  }

}
void menu(int enterPin, int leftPin, int rightPin) { //initiates menu
  // Print Commands to LCD concerning seting the time
  Serial.println("begining menu()");
  clearLCD();
  selectLineOne();
  LCD.println("Menu");
  delay(100);
  selectLineTwo();
  LCD.print("<:SetTime Next:>");

  // Wait for response from user
  Serial.println("Set Time?");
  do
  {
    if(debounce(leftPin, 30) && !debounce(enterPin, 30) && !debounce(rightPin, 30)){
      set_time(enterPin, leftPin, rightPin);
      break;
    }
  }
  while(!debounce(rightPin,30));

  // Print commands concerning setting alarm
  clearLCD();
  selectLineOne();
  LCD.println("Set Alarm");
  delay(100);
  selectLineTwo();
  LCD.print("<:Alarm Next:>");

  // Wait for response from user
  Serial.println("Set Alarm?");
  do
  {
    if(debounce(leftPin, 30) && !debounce(enterPin, 30) && !debounce(rightPin, 30)){
      set_alarm(enterPin, leftPin, rightPin);
      break;
    }
  }
  while(!debounce(rightPin,30));

  // Print commands concerning arming the alarm
  clearLCD();
  selectLineOne();
  LCD.println("Alarm On?");
  delay(100);
  selectLineTwo();
  LCD.print("<:Arm Next:>");

  // Wait for response from user
  do
  {
    if(debounce(leftPin, 30) && !debounce(enterPin, 30) && !debounce(rightPin, 30)){
      mode = 2;
      break;
    }
  }
  while(!debounce(rightPin,30));

  // Print commands concerning setting the backlight
  clearLCD();
  selectLineOne();
  LCD.println("Backlight");
  delay(100);
  selectLineTwo();
  LCD.print("<:Bright Next:>");

  // Wait for response from user
  do
  {
    if(debounce(leftPin, 30) && !debounce(enterPin, 30) && !debounce(rightPin, 30)){
      adjust_light(leftPin, rightPin);
      break;
    }
  }
  while(!debounce(rightPin,30));
  clearLCD();
}

void set_time(int enterPin, int leftPin, int rightPin) { // general puprose function for setting time (used in time and aloarm functions)
  Serial.println("Begin set_time()");
  int val = 0;
  int var;

  clearLCD();
  selectLineOne();
  LCD.println("Set Time");
  delay(100);
  selectLineTwo();
  LCD.print("<:-hr  +hr:>,");

  input_time(enterPin, leftPin, rightPin, hours, minutes);

  hours = new_hour;
  minutes = new_min;
  current_millis_value = millis();
  clearLCD();
}

void input_time(int enterPin, int leftPin, int rightPin, int sp_hour, int sp_min){// handle setting hours and minutes
  Serial.println("Begin input_time()");
  new_hour = sp_hour;
  new_min = sp_min;
  do  //Set hour
  {
    delay(100);

    // Increase hour by one when button rightPin is pushed
    if(!debounce(leftPin, 30) && !debounce(enterPin, 30) && debounce(rightPin, 30)){
      clearLCD();
      selectLineOne();
      LCD.print("Set Hour:");
      selectLineTwo();
      new_hour = ++new_hour;
      if(new_hour > 24){
        new_hour = 0;
      }
      LCD.print(new_hour);
    }

    // decrease hour by one when button leftPin is pushed
    if(debounce(leftPin, 30) && !debounce(enterPin, 30) && !debounce(rightPin, 30)){
      clearLCD();
      selectLineOne();
      LCD.print("Set Hour:");
      selectLineTwo();
      new_hour = --new_hour;
      if(new_hour <= 0){
        new_hour = 24;
      }
      LCD.print(new_hour);
    }
  }
  while (!debounce(enterPin,30));

  clearLCD();
  selectLineOne();
  LCD.print("Set Minute:");
  selectLineTwo();
  LCD.print("<:-min  +min:>,");
  delay(1000);

  do  //Set minute
  {
    delay(100);
    // increase minute by one
    if(!debounce(leftPin, 30) && !debounce(enterPin, 30) && debounce(rightPin, 30)){
      clearLCD();
      selectLineOne();
      LCD.print("Set Minute:");
      selectLineTwo();
      new_min = ++new_min;
      if(new_min >= 60){
        new_min = 0;
      }
      LCD.print(new_min);
    }

    // reduce min by one
    if(debounce(leftPin, 30) && !debounce(enterPin, 30) && !debounce(rightPin, 30)){
      clearLCD();
      selectLineOne();
      LCD.print("Set Minute:");
      selectLineTwo();
      new_min = --new_min;
      if(new_min <= 0){
        new_min = 59;
      }
      LCD.print(new_min);
    }
  }
  while (!debounce(enterPin,30));
}

void set_alarm(int enterPin, int leftPin, int rightPin){ // set the time for the alarm to go off
  Serial.println("Begin set_alarm()");
  clearLCD();
  selectLineOne();
  LCD.print("Set Alarm:");
  selectLineTwo();
  LCD.print("<:-hr  +hr:>,");
  delay(100);

  input_time(enterPin, leftPin, rightPin, alarm_hr, alarm_min);

  alarm_hr = new_hour;
  alarm_min = new_min;
  clearLCD();
}
Advertisements

About Ryan

Ryan is currently a National Research Council Postdoctoral Research Fellow at the Air Force Research Laboratory. His research area includes Prognostic Health Management of Electronics. For more information please visit: www.rdlowe.com
This entry was posted in Project and tagged , , . Bookmark the permalink.

2 Responses to Hearing Impaired Alarm Clock Source Code (Arduino)

  1. Pingback: Open Source Hearing Impaired Alarm Clock | Visual Engineering

  2. Pingback: Open Source Hearing Impaired Alarm Clock using Arduino -Arduino for Projects

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s