Some new stuff
  1. Arduino Park Control
  2. Arduino USB2serial programming the bare bone
  3. Arduino Projects Videos added
  4. Arduino Xbee projects
  5. Arduino dB Meter 
  6. Trying to get the IOIO going. 
  7. IOIO is going....bluetooth
  8. Attiny 2313 bluetooth bee RC car
  9. Compass and temperature added
  10. AVR programmer
  11. USB2Serial and Ethernet POE
  12. Arduino LPG Sensor
  13. Program the Arduino Mini 05
  14. Lipo Rider Pro in action
  15. EZ Robot Builder kit arrived 10 Nov 2012
  16. Arduino VA Meter!
  17. 05 Nov 2012 Project Sentry Gun.
  18. Attiny85 PIR Sensor 10 Dec 2012 
  19. 0-30VDC3A and 2-28VDC10A bench PSU's
  20. 19 Dec 2012 Arduino Voltmeter LCD
  21. 29 Dec 2012 Arduino Tachometer&Speedometer LCD
  22. 03 Jan 2013 Arduino AC Phase Control. 
  23. 18 Jan 2013 Arduino Distance Meter
  24. 22 Jan 2013 Arduino Digital Clock and Date
  25. 31 Jan 2013 Arduino Digital Clock and Date 8x2 LCD
  26. Feb 2013 LCD and Backpack
  27. Feb 2013 7 Segment Serial Clock Sparkfun. Distance Sensor with "newping" library
  28. Feb 2013 Lelo Remote
  29. 01/03/2013 Arduino Adafruit 7 Seg Digital Clock with RTC and backpack 
  30. Arduino Frequency Meter 26/03/2013
  31. Another RC  Car controlled by Arduino 06/04/2013
  32. My quadcopter project update 25 April 2013
  33. My Aqua Quad Copter Flying 26 April 2013enlightened
  34. Another monster RC truck;strong one! 11July2013cool
  35. X-Frame Quad Copter 31 July 2013cool
  36. Arduino GSM Sheild added.28/8/2013
  37. 1.8inch TFT screen 13/09/2013cool
  38. 04/11/2014 added PID Soldering Iron Control
  39. Added bluetooth servo control 04/11/2014
  40. ESP8266 first try.16/03/2015
  41. Arduino Uno Quadcopter 19 May 2015
  42. IOT WemosD1 Amp Meter

 

 


Search    

02/02/2013

Arduino LCD Clock with Alarm and Timer

References:

Code here:

http://www.instructables.com/id/Motion-Sensitive-LCD-Real-Time-ClockAlarmTimer/step7/Programming-the-Clock-Updated-7302012/

What did I learn from this alarm clock?

Firstly that I still cant code 

Secondly the analogue inputs instead of digital input use, therefore the const int pirPin = 16 in his code.

Thirdly that you get no and nc PIR sensors.(Which I should have known

This was pointed out to me by Peter van der Walt (H4H), thanks Peter.

If you are using the wrong PIR sensor, the backlight won't switch off after 30 cycles.

And fourthly it is the first time that I see the buttons on the DFRobot LCD Keypad Shield in action. 

This clock works excellent and well done to the author!

A video can be seen HERE .Just scroll down until you see the heading of this particular clock.

#include <Wire.h>
#include <RTClib.h>
#include "Wire.h"
#include "LiquidCrystal.h"

// A4 = SDA,A5 = SCL
LiquidCrystal lcd(0);
RTC_DS1307 RTC;
DateTime now;
// define variables
int lcd_key = 0;
int adc_key_in = 0;
int lastDay = 0;
int lastMonth = 0;
int lastYear = 0;
int lastHour = 0;
int lastMinute = 0;
int movementTimer = 0;
int menuOptions = 3;
int menuOption = 0;
int alarmHours = 0;
int alarmMinutes = 0;
bool alarmPM = 0;
bool alarmSet = 0;
bool backLightOn = 1;
// 8/1/2012 Fixed default day and hour settings on set date/time
bool resetClock = false;

// define constants
const int backLight = 10; 
const int pirPin = 16;//A2
#define btnRIGHT  0
#define btnUP     1
#define btnDOWN   2
#define btnLEFT   3
#define btnSELECT 4
#define btnNONE   5
#define beeper A1
#define shortBeep 100
#define longBeep  500

void setup () {
  Serial.begin(57600);
  pinMode(backLight, OUTPUT);
  digitalWrite(backLight, LOW); // turn backlight off  
  pinMode(beeper, OUTPUT);
  digitalWrite(beeper, LOW);  
  pinMode(pirPin, INPUT);  
  Wire.begin();
  RTC.begin();

  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    //RTC.adjust(DateTime(__DATE__, __TIME__));
  }
}

void loop () {
  now = RTC.now();
  digitalClockDisplay( ); // update clock
  movementTimer++;
  if (movementTimer > 30) //turn off backlight after 30 cycles
  {
    digitalWrite(backLight, LOW); // turn backlight off
    movementTimer = 0;
  }
  for (int i = 0; i < 10000; i++)
  {
    button_loop(); //check for button pushed
    int val = digitalRead(pirPin); //read motion sensor
    if (val == HIGH)
    {
      //sense movement?
      digitalWrite(backLight, HIGH); // turn backlight on
      movementTimer = 0;
    }
  }
}

void printDigits(byte digits)
{
  // utility function for digital clock display: prints preceding colon and leading 0
  lcd.print(":");
  if(digits < 10)
    lcd.print('0');
  lcd.print(digits,DEC);
}

void digitalClockDisplay()
{
  bool clockPM = 0;
  // 8/1/2012 Fixed default day and hour settings on set date/time
  if (now.day() != lastDay || resetClock == true)
  {
    lcd.begin(16,2);
    lcd.setCursor(3,0);

    if(now.month() < 10)
      lcd.print('0');
    lcd.print(now.month(), DEC);
    lcd.print("/");

    if(now.day() < 10)
      lcd.print('0');
    lcd.print(now.day(), DEC);
    lcd.print("/");

    int thisYear = now.year();
    lcd.print(thisYear, DEC);
  }
  // 8/1/2012 Fixed default day and hour settings on set date/time
  if (now.minute() != lastMinute || resetClock == true)
  {
    if(now.hour() < 10)
      lcd.setCursor(5,1);
    lcd.setCursor(4,1);

    // 7/29/2012 Fixed noon showing as 12am
    //    if(now.hour() > 12)
    if(now.hour() > 11)
    {
      // 8/19/2013 Fixed noon showing as 0:00pm
      if (now.hour() == 12)
      {
        lcd.print(now.hour(), DEC);
      }
      else{
        lcd.print(now.hour()-12, DEC);
      }
      printDigits(now.minute());
      clockPM = true;
      // 7/29/2012 Fixed displaying PMM; added space after "PM"
      lcd.print(" PM "); 
      // 7/29/2012 Added alarm set indicator
      if (alarmSet)
        lcd.print("*");
    }
    else
    {
      lcd.print(now.hour(), DEC);
      printDigits(now.minute());
      clockPM = false;      
      lcd.print(" AM ");
      // 7/29/2012 Added alarm set indicator
      if (alarmSet)
        lcd.print("*");      
    }
  }

  // 8/1/2012 Fixed default day and hour settings on set date/time
  resetClock = false;

  lastDay = now.day();
  lastMonth = now.month();
  lastYear = now.year();
  lastHour = now.hour();
  lastMinute = now.minute();

  //check for alarm
  if (alarmSet)
  {
    // 8/1/2012 Fixed alarm set PM
    if (alarmHours == lastHour && alarmMinutes == lastMinute)
    {
      //sound alarm
      setOffAlarm();
    } 
  }
}

void button_loop()
{
  int button = read_LCD_buttons();
  if (button == btnSELECT)
  {
    timedBeep(shortBeep,1); 
    selectMenu();
  }
}

void selectMenu()
{
  int button = 0; 
  menuOption = 1;
  lcdClear();
  lcd.print("Minute Timer");  

  while (menuOption <= menuOptions)
  {
    button = read_LCD_buttons();
    if (button == btnSELECT)
    {
      timedBeep(shortBeep,1);   
      menuOption++;

      if (menuOption == 2)
      {
        lcdClear();
        // 7/29/2012 Added clearAlarm feature
        lcd.print("Set/Clear Alarm");            
      }
      if (menuOption == 3)
      {
        lcdClear();
        lcd.print("Set Date/Time");            
      }
    } 

    if (button == btnLEFT)
    {
      if (menuOption == 1)
      {
        timedBeep(shortBeep,1);
        minuteTimer();
        return;
      }
      if (menuOption == 2)
      {
        timedBeep(shortBeep,1);
        // 7/29/2012 Added clearAlarm feature
        //check for existing alarm
        if (alarmSet)
        {
          clearAlarm();
        }
        else
        {
          setAlarm();
        }
        return;
      }
      if (menuOption == 3)
      {
        timedBeep(shortBeep,1);
        // 7/29/2012 Added setDateTime feature
        setDateTime();
        return;
      } 
    }
  }
}  

// 7/29/2012 Added clearAlarm feature
void clearAlarm()
{
  int button = 0;
  bool clearIt = true;
  char *ampm = "AM";

  lcdClear();
  lcd.print("Alarm Set For");
  lcd.setCursor(0,1);
  lcd.print(alarmHours);   
  lcd.print(":");
  lcd.print(alarmMinutes);
  lcd.print(" ");
  if (alarmPM == 1)
    ampm = "PM";
  lcd.print(ampm);
  delay(2000);
  lcdClear();
  lcd.print("Clear Alarm?");
  lcd.setCursor(0,1);
  lcd.print("Yes");  

  while (button != btnSELECT)
  {
    button = read_LCD_buttons();
    if (button == btnUP)
    {
      timedBeep(shortBeep,1);
      clearIt = !clearIt;
    }
    if (button == btnDOWN)
    {
      timedBeep(shortBeep,1);
      clearIt = !clearIt;
    }
    if (button == btnRIGHT)
    {
      timedBeep(shortBeep,1);
      alarmSet = !clearIt;
      if (clearIt)
      {
        lcdClear();
        timedBeep(shortBeep,2);
        lcd.print("Alarm Cleared!");
        delay(2000);
      }
      return; 
    }
    lcd.setCursor(0,1);
    if (clearIt)
    {
      lcd.print("Yes"); 
    }
    else{
      lcd.print("No ");
    }
  }   
}

void minuteTimer()
{
  // 8/1/2012 Pass maxCount to getTimerMinutes
  int timerMinutes = getTimerMinutes("Set Minutes", 0, 60);
  if (timerMinutes > 0)
  {
    timedCountDown(timerMinutes*60, "Minute Timer");
  }
  else
  {
    timerCancelled("Timer");       
  }
  return;
}

void setAlarm()
{
  int button = 0;
  char *ampm = "AM";
  // 8/1/2012 Pass maxCount to getTimerMinutes
  alarmHours = getTimerMinutes("Set Alarm Hour", alarmHours, 12);  
  // 7/29/2012 Validate alarm hours > 0 and < 13
  if (alarmHours > 0 && alarmHours < 13)
  {
    // 8/1/2012 Pass maxCount to getTimerMinutes
    alarmMinutes = getTimerMinutes("Set Minutes", alarmMinutes, 59);
    // 7/29/2012 Fixed allow alarm minutes to be 0
    //if (alarmMinutes > 0)
    if (alarmMinutes < 60)
    {
      lcdClear();
      lcd.print("Toggle AM/PM");
      lcd.setCursor(0,1);
      //display alarm time
      lcd.print(alarmHours);       
      lcd.print(":");
      if (alarmMinutes < 10)
        lcd.print("0");
      lcd.print(alarmMinutes);
      lcd.setCursor(6,1);
      lcd.print(ampm);
      //get AM/PM
      button = 6;
      while (button != btnSELECT && button != btnRIGHT)
      {
        button = read_LCD_buttons();
        if (button == btnUP || button == btnDOWN)
        {
          timedBeep(shortBeep,1);
          if (ampm == "AM")
          {
            ampm = "PM";
          }
          else
          {
            ampm = "AM";
          }
          lcd.setCursor(6,1);
          lcd.print(ampm);  
        }
      }

      if (button == btnRIGHT)
      {
        timedBeep(shortBeep,1);
        alarmSet = true; 
        // 8/1/2012 Fixed alarm set PM
        if (ampm == "PM") alarmHours += 12;        
        lcd.setCursor(0,0);
        lcd.print("Alarm Set for");
        delay(1000);
        return;       
      }
      else
      {
        timerCancelled("Alarm");
        return;  
      }   
    }
    else
    {
      timerCancelled("Alarm");     
    }    
  }     
  else
  {
    timerCancelled("Alarm");       
  }
}

// 7/29/2012 Added setDateTime feature
void setDateTime()
{
  int button = 0;
  char *ampm = "AM";

  //get month
  // 8/1/2012 Pass maxCount to getTimerMinutes
  int setMonth = getTimerMinutes("Set Month", lastMonth, 12);
  if (setMonth > 0 && setMonth < 13)
  {
    //get day
    // 8/1/2012 Fixed default day and hour settings on set date/time
    // 8/1/2012 Pass maxCount to getTimerMinutes
    int setDay = getTimerMinutes("Set Day", lastDay, 31);
    if (setDay > 0 && setDay < 32)
    {
      //get year
      // 8/1/2012 Pass maxCount to getTimerMinutes
      int setYear = getTimerMinutes("Set Year", lastYear, 2999);
      if (setYear > 2000 && setYear < 3000)
      {
        //get hour
        int thisHour = lastHour;
        // 8/1/2012 Fixed default day and hour settings on set date/time
        if (thisHour > 12) 
        {
          thisHour -= 12;
          ampm = "PM";
        }
        // 8/1/2012 Pass maxCount to getTimerMinutes
        int setHour = getTimerMinutes("Set Hour", thisHour, 12);
        if (setHour > 0 && setHour < 13)
        {
          //get minutes
          // 8/1/2012 Fixed default day and hour settings on set date/time
          // 8/1/2012 Pass maxCount to getTimerMinutes
          int setMinute = getTimerMinutes("Set Minute", lastMinute, 59);
          if (setMinute < 60)
          {
            //get ampm
            lcdClear();
            lcd.print("Toggle AM/PM");
            lcd.setCursor(0,1);
            //display alarm time
            lcd.print(setHour);       
            lcd.print(":");
            if (setMinute < 10)
              lcd.print("0");
            lcd.print(setMinute);
            lcd.setCursor(6,1);
            lcd.print(ampm);
            //get AM/PM
            button = 6;
            while (button != btnSELECT && button != btnRIGHT)
            {
              button = read_LCD_buttons();
              if (button == btnUP || button == btnDOWN)
              {
                timedBeep(shortBeep,1);
                if (ampm == "AM")
                {
                  ampm = "PM";
                }
                else
                {
                  ampm = "AM";
                }
                lcd.setCursor(6,1);
                lcd.print(ampm);         
              }
            }
            if (button == btnRIGHT)
            {
              timedBeep(shortBeep,1);
              if (ampm == "PM")
                setHour = setHour + 12;
              RTC.adjust(DateTime(setYear,setMonth,setDay,setHour,setMinute));

              lcd.setCursor(0,0);
              // 8/1/2012 Fixed default day and hour settings on set date/time
              lcd.print("Saving...     ");
              delay(1000);
              return;       
            }
            else
            {
              timerCancelled("");
              return;  
            }  
          }
          else
          {
            timerCancelled("");     
          }    
        }     
        else
        {
          timerCancelled("");       
        }
      }
      else
      {
        timerCancelled("");     
      }    
    }     
    else
    {
      timerCancelled("");       
    }
  }
  else
  {
    timerCancelled("");       
  }

}

// read the buttons
int read_LCD_buttons()
{
  adc_key_in = analogRead(0);      // read the value from the sensor
  // my buttons when read are centered at these valies: 0, 144, 329, 504, 741
  // we add approx 50 to those values and check to see if we are close
  if (adc_key_in > 1000) return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result
  if (adc_key_in < 50)   return btnRIGHT; 
  if (adc_key_in < 195)  return btnUP;
  if (adc_key_in < 380)  return btnDOWN;
  if (adc_key_in < 555)  return btnLEFT;
  if (adc_key_in < 790)  return btnSELECT;  
  return btnNONE;  // when all others fail, return this...

}

void timedCountDown(int secondCount, char countLabel[])
{
  long seconds = 0;
  long minutes = 0; 

  lcdClear();
  lcd.print(countLabel);
  for (int i = secondCount; i >= 0; i--)
  {
    seconds = i;
    minutes = i / 60;
    if (minutes > 0)
    {
      seconds = seconds - (minutes * 60);  
    }     

    if (minutes > 0)
    {
      lcd.setCursor(0,1);
      lcd.print(minutes);
      lcd.print(" min ");
    }
    else
    {
      lcd.setCursor(0,1);
    }
    if (seconds < 10) lcd.print("0");
    lcd.print(seconds);
    lcd.print(" sec remaining");
    if (seconds > 0) delay(1000); 
    if (read_LCD_buttons() == btnSELECT) //cancel
    {
      timerCancelled("Timer");
      i = 0;
      return;
    }
  }
  lcd.setCursor(6,1);
  timedBeep(longBeep,3);
}

// 8/1/2012 Pass maxCount to getTimerMinutes
int getTimerMinutes(char timerText[], int startNum, int maxCount)
{
  int minutes = startNum;
  int button = 0;
  lcdClear();
  lcd.print(timerText);
  lcd.setCursor(0,1);
  lcd.print(minutes);   

  while (button != btnSELECT)
  {
    button = read_LCD_buttons();
    Serial.println(button);
    // 8/1/2012 Pass maxCount to getTimerMinutes
    if (button == btnLEFT)
    {
      if ((minutes + 10) <= maxCount)
      {
        timedBeep(shortBeep,1);
        minutes = minutes + 10;
      }
      else
      {
        timedBeep(shortBeep,2); 
      }
    }
    // 8/1/2012 Pass maxCount to getTimerMinutes
    if (button == btnUP)
    {
      if (minutes < maxCount)
      {
        timedBeep(shortBeep,1);
        minutes++;
      }
      else
      {
        timedBeep(shortBeep,2); 
      }
    }
    if (button == btnDOWN)
    {
      if (minutes > 0)
      {
        timedBeep(shortBeep,1);
        minutes--;
      }
      else
      {
        timedBeep(shortBeep,2); 
      }   
    } 
    if (button == btnRIGHT)
    {
      timedBeep(shortBeep,1);
      return minutes; 
    }
    lcd.setCursor(0,1);
    lcd.print(minutes); 
    lcd.print("   ");
  }
  return 0;
}

void timedBeep(int beepTime, int beepCount)
{
  for (int i = 0; i < beepCount; i ++)
  {
    digitalWrite(beeper, HIGH);
    delay(beepTime);
    digitalWrite(beeper, LOW);
    delay(beepTime);
  }
}

void lcdClear(){
  // 8/1/2012 Fixed default day and hour settings on set date/time
  //lastDay = 0;
  //lastMinute = 0;
  resetClock = true;
  lcd.clear();
  lcd.begin(16,2);
  lcd.setCursor(0,0); 
}

void timerCancelled(char message[])
{
  lcdClear();
  lcd.print(message);
  lcd.print(" Cancelled");
  timedBeep(shortBeep,3);    
}

void setOffAlarm()
{
  int button = 0;
  int i = 0;
  Serial.println(i);
  digitalWrite(backLight, HIGH); // turn backlight on
  while (button != btnSELECT)
  {
    button = read_LCD_buttons();
    lcdClear();
    i++;
    if (i > 50)
    {
      lcdClear();
      lcd.print("Alert Alert");
      lcd.setCursor(0,1);
      lcd.print("     Alert Alert");      
      i = 0;
      timedBeep(shortBeep,3);
    }

  }     
  timerCancelled("Alarm"); 
  alarmSet = false;  
}

 

 

 

Back Back to top