Project showcase
Remote Controlled Alarm Clock

Remote Controlled Alarm Clock © GPL3+

An alarm clock with no physical buttons, just a remote control.

  • 762 views
  • 0 comments
  • 4 respects

Components and supplies

Necessary tools and machines

09507 01
Soldering iron (generic)
66y6421 40
Solder Flux, Soldering

Apps and online services

About this project

To increase access to education I made a simple, easy to flollow arduino project for newcomers that will allow them to learn more about programming. Using the arduino microcontroller's internal timer and Infared sensors, this remote control alarm clock, is fully functioning from across the room.

There are two parts to this project, the elctronics/arduino part and the wooden enclosure. The wooden enclosure is designed to be made using a laser printer, in this case it is not accessible to many people, but the instructions and files are there.

This tutorial will walk you through some of the design obstacles I encountered while making this in order to help you understand how to program for arduino better.

The first issue encountered is how do we count time. Normally a RTC component will do the job, but I wanted to keep the build price down, so we will use the millis() and micros() functions built into the arduino. These functions will give you the milliseconds and microseconds that have passed since the arduino has started running. So we take that value and store it in a variable of great size, an unsigned long (a long stores 16 bits of binary data, and since this one is unsigned it does not use the Most Significant Bit [MSB] to store whether or not the value is negative.) to measure the change between loops of the arduino. This function needs to be called every so often to maintain the most accuracy. From there if statements keep track of what times to increment and when. Then we store the currentTime variable in a variable called previousTime to check for change later with. Figuring out how to code things without their components is a great way to save money, but is not always possible or worth it.

This is the first time you'll notice the use of the Serial Console. This will enable us to see whether or not the clock is running behind the scenes as our display does not show seconds. When we do display we will be using the library for the display's built in function to display time. It is important that we import this library properly and declare the object for the display with the right name for the version that contains the printTime() function. Using libraries is a great way to save time and energy while coding and your arduino comes with many of them already.

When using an IR remote you have to figure out your remote's values. The included IR Test program will output your IR remotes valid cases when you press on the buttons. Ignore the 0xFFFFFFFF case, that is most likley an error. Try each button multiple times and record what buttons mean which values.

A string is used when taking in the time to allow for easy manipulation of its contents.

The last issue I faced was when adding the alarm. Passive Buzzers and IR Sensors have the same timer on most arduinos and cannot be run together. So manipulation of the ir library was needed. Go to IRRemoteInt.h and edit the timer to be 1.IFYOUAREJUSTSKIMMINGTHROUGHTOGETTOTHECODETHISISIMPORTANT.

The enclosure will be added at a later date.

Code

IR TestArduino
#include <IRremote.h>

const int RECV_PIN = 7;
IRrecv irrecv(RECV_PIN);
decode_results results;

void setup(){
  Serial.begin(9600);
  irrecv.enableIRIn();
  irrecv.blink13(true);
}

void loop(){
  if (irrecv.decode(&results)){
        Serial.println(results.value, HEX);
        irrecv.resume();
  }
}
IRremote.zipArduino
IRremote library, you will need to edit the clock values, depending on your use of buzzer.
No preview (download only).
Pitches LibraryArduino
Not 100% neccesary, but its here if you need it.
No preview (download only).
Main CodeArduino
/*
Alarm Clock

By Carson Gamble




*/
#include <pitches.h>

#include <IRremote.h>
#include <IRremoteInt.h>

//#include <SevenSegmentExtended.h>
#include <SevenSegmentFun.h>
//#include <SevenSegmentTM1637.h>

#include "SevenSegmentTM1637.h"
#include "SevenSegmentExtended.h"

unsigned long currentTime;
unsigned long previousTime = 0;
int mill = 0;
byte sec = 0;
int minute = 0;
int hour = 0;
int alarmHour = 100;
int alarmMinute = 100;
boolean alarming = false;
int alarmed = 0;
int noteDuration=-1;
boolean fastMode = false;
int melody[] = {
  2637, 2637, 0, 2637,
  0, 2093, 2637, 0,
  3136, 0, 0,  0,
  1568, 0, 0, 0,

  2093, 0, 0, 1568,
  0, 0, 1319, 0,
  0, 1760, 0, 1976,
  0, 1865, 1760, 0,

  1568, 2637, 3136,
  3520, 0, 2794, 3136,
  0, 2637, 0, 2093,
  2349, 1976, 0, 0,

  2093, 0, 0, 1568,
  0, 0, 1319, 0,
  0, 1760, 0, 1976,
  0, 1865, 1760, 0,

  1568, 2637, 3136,
  3520, 0, 2794, 3136,
  0, 2637, 0, 2093,
  2349, 1976, 0, 0
};
int tempo[] = {
  12, 12, 12, 12,
  12, 12, 12, 12,
  12, 12, 12, 12,
  12, 12, 12, 12,

  12, 12, 12, 12,
  12, 12, 12, 12,
  12, 12, 12, 12,
  12, 12, 12, 12,

  9, 9, 9,
  12, 12, 12, 12,
  12, 12, 12, 12,
  12, 12, 12, 12,

  12, 12, 12, 12,
  12, 12, 12, 12,
  12, 12, 12, 12,
  12, 12, 12, 12,

  9, 9, 9,
  12, 12, 12, 12,
  12, 12, 12, 12,
  12, 12, 12, 12,
}; 
const byte PIN_BUZZ = 2;
const byte PIN_IR = 3;
IRrecv irrecv(PIN_IR);     // create instance of 'irrecv'
decode_results results;      // create instance of 'decode_results' the ir assistant
const byte PIN_CLK = 5;   // define CLK pin (any digital pin)
const byte PIN_DIO = 6;   // define DIO pin (any digital pin)
SevenSegmentExtended    display(PIN_CLK, PIN_DIO);


void setup() {
  // put your setup code here, to run once:
  irrecv.enableIRIn(); // Start the receiver
  Serial.begin(9600);
  display.begin();            // initializes the display
  display.setBacklight(40);  // set the brightness to 100 %
  delay(1000);                // wait 1000 ms
}


void loop() {c
  // put your main code here, to run repeatedly:
  noteDuration=-1;
  checkTime();
  display.printTime(hour, minute, false);
  
  if (irrecv.decode(&results)) // have we received an IR signal?
  {

    translateIR(); 
    irrecv.resume(); // receive the next value
  }
  if((hour == alarmHour) && (minute == alarmMinute)&&(sec < 2)){
    alarming = true;
  }
  alarmFunction();
  
}
void checkTime() { //This function updates the time based on the arduino keeping track of how long its been since the program has started. The unsigned long keeps track of milliseconds and goes bad after ~50 days)
  currentTime = millis(); 
  mill += currentTime - previousTime;
  if (mill >= 1000) {
      sec++;
      mill = mill % 1000;
  }
  if(fastMode){
    if(sec>=6){
      minute++;
      sec = sec%6;
    }
  }else if (sec >= 60) {
    minute++;
    sec = sec % 60;
  }
  if (minute >= 60) {
    hour++;
    minute = minute % 60;
  }
  if (hour >= 24) {
    hour = hour % 24;
    // sec = -6;
  }
  previousTime = currentTime;
  Serial.print(hour);
  Serial.print(" : ");
  Serial.print(minute);
  Serial.print(" : ");
  Serial.println(sec);
  
}

void alarmFunction(){ //Dictates Alarm Logic and alarm noise and delay for clock
  if(alarming){
    //display.blink();
    //this is just how the mario theme could be played based on a tutorial I found, other song arrays may not work with this method.
    noteDuration = 1000 /tempo[alarmed];
    tone(PIN_BUZZ, melody[alarmed], noteDuration);
    alarmed++;
    if(alarmed>77){
      alarmed=0;
    }
  }else{
    alarming = false;
    alarmed = 0;
  }
  if(noteDuration==-1){//this is the main delay for the loop
    delay(100);
  }else{
    delay(noteDuration*1.30);
  }
}

//generic retriving time function
//returns a string with the time needed, in 4 character order
//0 is a required input
String changeTime(){
  delay(500);
  irrecv.resume(); // receive the next value
  String newTime = "----"; 
  for(int i = 0; i<4; i++){
    byte temp;
    if (irrecv.decode(&results)) // have we received an IR signal?
    {
      switch(results.value)
      {
        case 0xFF9867: newTime.setCharAt(i, '0'); temp = 0; break;
        case 0xFFA25D: newTime.setCharAt(i, '1'); temp = 1; break; 
        case 0xFF629D: newTime.setCharAt(i, '2'); temp = 2; break;
        case 0xFFE21D: newTime.setCharAt(i, '3'); temp = 3; break;  
        case 0xFF22DD: newTime.setCharAt(i, '4'); temp = 4; break;  
        case 0xFF02FD: newTime.setCharAt(i, '5'); temp = 5; break; 
        case 0xFFC23D: newTime.setCharAt(i, '6'); temp = 6; break;  
        case 0xFFE01F: newTime.setCharAt(i, '7'); temp = 7; break;
        case 0xFFA857: newTime.setCharAt(i, '8'); temp = 8; break; 
        case 0xFF906F: newTime.setCharAt(i, '9'); temp = 9; break;
      } 
      irrecv.resume(); // receive the next value
    }
    
    if(newTime.charAt(i)=='-'){
      i--;
    }
    //A Time Check can be placed here to see if valid times are being input.
    delay(100);
    Serial.println(newTime);
    display.print(newTime);
    checkTime();
    
  }
  
  return newTime;
}

void translateIR() // takes action based on IR code received

// describing Remote IR codes 

{
  // switch statement takes in input, case decyphers it
  switch(results.value)

  {
  
  case 0xFF4AB5: Serial.println("DOWN");    break;
  
  case 0xFF18E7: Serial.println("UP");    break;
  case 0xFF10EF: Serial.println("LEFT"); fastMode = !fastMode; display.blink(); break;
  case 0xFF5AA5: Serial.println("RIGHT"); break;
  case 0xFF38C7:{ Serial.println("OK/Alarm Off"); alarming = false; break;}
  
  case 0xFF6897: /*Serial.println("Asterisk/SetAlarm"); break; */{ //This starts the alarm sequence
    String newAlarmTime= changeTime(); //retrives string from keypad
    alarmHour = (newAlarmTime.substring(0,2)).toInt();
    alarmMinute = (newAlarmTime.substring(2)).toInt();
  break;}
  case 0xFFB04F: {Serial.println("Pound/SetTime"); 
    String newTime = changeTime();
    hour = (newTime.substring(0,2)).toInt();
    minute = (newTime.substring(2)).toInt();
    sec = 0;
  break;}
  case 0xFF9867: Serial.println("0");    break;
  case 0xFFA25D: Serial.println("1");    break;
  case 0xFF629D: Serial.println("2");    break;
  case 0xFFE21D: Serial.println("3");    break;
  case 0xFF22DD: Serial.println("4");    break;
  case 0xFF02FD: Serial.println("5");    break;
  case 0xFFC23D: Serial.println("6");    break;
  case 0xFFE01F: Serial.println("7");    break;
  case 0xFFA857: Serial.println("8");    break;
  case 0xFF906F: Serial.println("9");    break;
  //case 0xFFFFFFFF: Serial.println(" REPEAT");break;  
 

  default: 
    Serial.println("Error" + results.value);

  }// End Case

  delay(500); // Do not get immediate repeat (Basically Debouncing)


}
//END translateIR
The Seven Segment Display Library I Used
Worked excellent for me, cannot guarantee it supports all setups.

Schematics

Project Fritz
Diagram for reference on how to hook things up to arduino
project_clock_fritz_wdgF9mpxNu.fzz

Comments

Similar projects you might like

Remote Controlled Pet Feeder

Project tutorial by Amal Mathew

  • 4,584 views
  • 1 comment
  • 29 respects

Remote Controlled Lights

Project showcase by jsheng

  • 1,071 views
  • 0 comments
  • 7 respects

How to Make a Remote Controlled Robotic Hand with Arduino

Project showcase by Gabry295

  • 39,018 views
  • 5 comments
  • 125 respects

Complete Digital Clock Including Alarm and Motion Sensor

Project in progress by LAGSILVA

  • 15,828 views
  • 19 comments
  • 58 respects

IR Remote Controlled Power Switch for Rapsberry Pi 3

Project tutorial by Vilém Kužel

  • 1,085 views
  • 1 comment
  • 5 respects

Sensal - All Senses Alarm Clock

Project in progress by Leonid Piliptsevich

  • 8,796 views
  • 2 comments
  • 28 respects
Add projectSign up / Login