Home ARDUINO Build Alarm Clock, Motion Detector with Arduino LCD Shield

Build Alarm Clock, Motion Detector with Arduino LCD Shield

A project that fits perfectly into the interior of your DIY corner, room, garage or office in which you collect robots and all sorts of geek automated projects on the Arduino LCD Shield.

At the exit of the project, you will get the following features within one module:

  • Clock!
  • Displays the date and time on the LCD screen;
  • Built-in time counter (in order to record the time spent on one project);
  • Alarm clock (to remind you that you have set up and it’s time to arrange yourself a warm-up);
  • Motion tracking (saves battery power by turning off the LCD screen when you are not around);
  • Perfectly fit into your interior Arduino-developer!

Required materials for this project

  • Arduino Uno ( View on Amazon )
  • LCD Keypad Shield (LCD shield with buttons) for Arduino (View on Amazon)
  • Real-Time Clock (RTC) DS1307 (View on Amazon)
  • Lockable box (can be found in the radio store or ordered from the Chinese);
  • Buzzer (Piezo Buzzer);
  • PIR (Passive Infrared Motion Sensor); (View on Amazon)
  • Jack 2.1 mm;
  • Adapter for 9 V 5.5 mm / 2.1 mm battery;
  • Battery 9 V.

Arduino LCD Shield Arduino LCD Shield Arduino LCD Shield Arduino LCD Shield

Building a real-time clock module

Arduino LCD Shield

Power Connector

In order to avoid problems with connecting the Arduino, a 2.1 mm jack is used, to which the contacts are soldered. A hole is made in the box, the jack is set on glue. Now connecting the Arduino is no problem.

Arduino LCD Shield

The 9 V battery (crown) is simply installed on the back of the box.

Arduino LCD Shield

If you noticed, there is another hole in the box. This was the first unsuccessful attempt. Jack in this hole did not fit.

Connecting Hardware


I highly recommend buying multi-colored conductors of the type of wires. They are inexpensive, and the assembly process is very easy. We connect the conductors to the real-time clock module, PIR motion sensor, buzzer, in order to further connect them to the LCD shield.

Arduino LCD Shield

Merge with LCD Shield

There are 5 rows of contacts on the LCD shield that correspond to pins 1-5 on the Arduino board. There is a contact for 5v, GND and signal. These contacts were used to connect. For the exchange of data with a real-time clock, sensor and buzzer, analog pins on the Arduino were used. Naturally, the sensor and the real-time clock are connected to power and ground.

Arduino LCD Shield Build Alarm Clock, Motion Detector with Arduino LCD Shield

Build Alarm Clock, Motion Detector with Arduino LCD Shield

Box installation

The next step is the packaging of our miracle in a separate box. First put in the box the cables that are pulled from the LCD shield.

Arduino is fastened with a screw to the bottom right of the box. One screw is basically enough to hold the board. In addition, in this particular case, the ribs in the box are located just in the place where the hole for the second and third screws is provided on the board.

After that we install our LCD shield on the Arduino. Cables go around the board on the right side (see the photo below).

Real-time clock module is perfectly installed in the lower left corner of the box. For mounting, too, used one screw. This installation allows you to connect a 2.1 mm jack to the Arduino.

The motion sensor (PIR) is installed so that it can be easily and quickly removed, as it prevents the USB cable from being connected to the Arduino.

 

Arduino LCD Shield Arduino LCD Shield Build Alarm Clock, Motion Detector with Arduino LCD Shield Build Alarm Clock, Motion Detector with Arduino LCD Shield Build Alarm Clock, Motion Detector with Arduino LCD Shield

Working on project

As indicated in the first part of the article, in addition to displaying the time and date, we need to implement a timer and an alarm clock.

On the LCD screen, there are 5 programmable buttons. They are used to set different modes of operation of the clock. The buzzer runs every time you press a button. When the alarm goes off, the buzzer beeps several times.

Sketch for Arduino

  • The program was based on a sketch from Adafruit, which was developed for the real-time clock module. This sketch uses their own RTClib library. This sketch can be found on GitHub.
  • After that, a piece of code from the DFRobot sketch for LCD shield has been added (including the option to control buttons). This sketch can be downloaded here.
  • Find the source code from the end of this article.

The photos below show the different modes of operation of our watches with LCD shield.

Photos of different modes of operation

Build Alarm Clock, Motion Detector with Arduino LCD Shield Build Alarm Clock, Motion Detector with Arduino LCD Shield Build Alarm Clock, Motion Detector with Arduino LCD Shield Build Alarm Clock, Motion Detector with Arduino LCD Shield Build Alarm Clock, Motion Detector with Arduino LCD Shield Build Alarm Clock, Motion Detector with Arduino LCD Shield Build Alarm Clock, Motion Detector with Arduino LCD Shield Build Alarm Clock, Motion Detector with Arduino LCD Shield Build Alarm Clock, Motion Detector with Arduino LCD Shield

Button functions

On the LCD shield, the buttons are signed (see the photo). The first five of the six available buttons (buttons) were programmed as follows:

Arduino LCD Shield

Button # 1 (labeled SELECT) is the Menu button. This button is responsible for displaying a list of available functions (timer, alarm setting).

Button # 2 (signed LEFT) – Select button. Used to select a function. Note: also used for incrementing by 10 when hours, minutes, etc. are selected.

Buttons # 3 and 4 (signed UP and DOWN) – buttons Increment and Decrement (increment and decrement). Used to reduce and increase the hours and minutes when setting the timer or alarm. They are also used to switch between AM and PM times of day.

Button # 5 (signed by RIGHT) – GO! Used to accept the selected value (for example, the configured minutes or hours).

Button # 6 (marked RST) – Reset, which reboots our Arduino.

Source Code

#include <Wire.h>

#include <RTClib.h>

#include <LiquidCrystal.h>

 

RTC_DS1307 RTC;

DateTime now;

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

 

// 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;

#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; 

}

You may also like to read our other Projects

How to Build a Project Using LDR sensors and Arduino UNO

How to Drive PIR Motion sensor With Arduino UNO and Buzzer

Leave your comments, questions and share your personal experience below. In the discussion often new ideas and projects are born!