Arduino Kitchen Timer

Arduino Kitchen Timer is made of 4-digit 7-segment LED, and 12-key keypad, 8-bit shift register 74HC164, and some resistors, decoupling capacitor, and Piezo speaker for the sound output.

* Do not imagine I am using this timer in my kitchen because I don’t. :) It’s just the name of device…

Feature:
Kitchen Timer. Maximum duration is 99 minutes and 99 sec. Beep when it’s done.

Parts:
1 x Keypad 12 Button
1 x 7-Segment Yellow 4 Digit LED
1 x 74AC164
8 x 470 ohm Resistor (LED)
* 220 ohm may work but it’s a little bit brighter. I used 470 ohm resistor array.
3 x 4.7K ohm Resistor (Keypad pullup resistors)
1 x Piezo Speaker taken out from old PC.

Pin Assignment:
Digital 02-05 Common Cathode of LED
Digital 06-12 Keypad Scanning
Digital 13 Piezo Speaker Output
Analog 0 74AC164 Data
Analog 1 74AC164 Clock
Analog 3-5 Not Used.

Video and Semantic in eagle format will be added soon.
Porting to Arduino Kitchen Timer Shield is on the way, but I will replace the keypad with just three or four buttons.

 
#include   <GenKeypad.h> //My keypad library
#include   <MsTimer2.h> //download this library at http://www.arduino.cc/playground/Main/MsTimer2

#define SHIFT_DATA 15     // 74AC164 data pin
#define SHIFT_CLOCK  14   // clock pin
#define SPEAKER_PIN 13

int NumPins[4] = {2, 3, 4, 5};
int SS = 0;
int MM = 0;
int start = 0;
char input[4] = {0, 0, 0, 0};
int inputIndex = 0;
int length = 15; // the number of notes
char notes[] = "ccccccccccccccc";
int beats[] = { 3, 1, 1, 3, 1, 1, 3, 1, 1, 3, 1, 1, 3, 1, 1 };

int tempo = 300;
int beeping = 0;

/**
   Keypad 
 **/
GenKeypad keypad;

//Key Input Callback Functions 
  
void keyUP(char key)  
{  
  //Serial.print("keyUP: ");  
  //Serial.println(key);  
}  

int atoi(char c)
{
  if (c == 0)
    return 0;
  else
    return (c - '0');
}

void keyDOWN(char key)  
{           
  Serial.print("keyDOWN: ");  
  Serial.println(key);  
    
  if (key == '#' && start == 0)
  {
    //Convert input chars into MM:SS
    MM = atoi(input[0]) * 10 + atoi(input[1]);
    SS = atoi(input[2]) * 10 + atoi(input[3]);
    
    if (MM + SS > 0)
      start = 1;
    return;
  }
  else if (key == '#' && start == 1)
  {
    start = 0;
    return;
  }

  if (key == '*')    
  {
    if (beeping == 0)
    {
      for (int i = 0; i < 4; i++)
        input[i] = 0;
    }
          
    inputIndex = 0;
    start = 0;
    beeping = 0;
    digitalWrite(SPEAKER_PIN, LOW);
  }
  else
  {  
    shiftDigit(input);
    input[3] = key;      
    
    inputIndex++;
    inputIndex %= 4;  
  }
}  

void shiftDigit(char input[4])
{
  input[0] = input[1];
  input[1] = input[2];
  input[2] = input[3];
}

void keyPRESSING(char key)  
{  
  //Serial.print("keyPressed: ");  
  //Serial.println(key);  
}

void setup(void) 
{
  Serial.begin(9600);
  
  //Digital pins parameter order matters!!
  keypad.setRowPins(11, 6, 7, 9);  //These pins are used as OUTPUT pins.
  keypad.setColPins(10, 12, 8);    //These pins are used as INPUT pins.  
  keypad.setFunction(GenKeypad::EVENT_KEY_UP,       keyUP); 
  keypad.setFunction(GenKeypad::EVENT_KEY_DOWN,     keyDOWN); 
  keypad.setFunction(GenKeypad::EVENT_KEY_PRESSING, keyPRESSING);
  
  pinMode(SPEAKER_PIN, OUTPUT);
  
  pinMode(SHIFT_DATA, OUTPUT);
  pinMode(SHIFT_CLOCK, OUTPUT);
  
  pinMode(NumPins[0], OUTPUT);
  pinMode(NumPins[1], OUTPUT);
  pinMode(NumPins[2], OUTPUT);
  pinMode(NumPins[3], OUTPUT);
  
  digitalWrite(NumPins[0], HIGH);
  digitalWrite(NumPins[1], HIGH);
  digitalWrite(NumPins[2], HIGH);
  digitalWrite(NumPins[3], HIGH);
  
  // writing default values (from the datasheet)
  
  MsTimer2::set(1000, secPulse);
  MsTimer2::start();
}

int digitSS = 0;
int digitMM = 0;
int digit = 0;

  byte font[10] = {
	//abcdefg.
    0b11111100,
    0b01100000,
    0b11011010,
    0b11110010,
    0b01100110,
    0b10110110,
    0b10111110,
    0b11100100,
    0b11111110,
    0b11100110
  };
  
byte c2font(char c)
{
  const byte blank = 0b00000000;
  
  if (c == 0)
    return blank;
  else  
    return font[c-'0'];
}


void setChars(char input[4], int delaymsec)
{
  digitalWrite(NumPins[0], LOW);
  shiftOut(SHIFT_DATA, SHIFT_CLOCK, LSBFIRST, c2font(input[3])); 
  delay(delaymsec);
  digitalWrite(NumPins[0], HIGH);

  digitalWrite(NumPins[1], LOW);
  shiftOut(SHIFT_DATA, SHIFT_CLOCK, LSBFIRST, c2font(input[2])); 
  delay(delaymsec);
  digitalWrite(NumPins[1], HIGH);


  digitalWrite(NumPins[2], LOW);
  shiftOut(SHIFT_DATA, SHIFT_CLOCK, LSBFIRST, c2font(input[1])); 
  delay(delaymsec);
  digitalWrite(NumPins[2], HIGH);

  digitalWrite(NumPins[3], LOW);
  shiftOut(SHIFT_DATA, SHIFT_CLOCK, LSBFIRST, c2font(input[0])); 
  delay(delaymsec);
  digitalWrite(NumPins[3], HIGH);
  
  delay(delaymsec);
}

void beep()
{
  if (start)
  {
    digitalWrite(SPEAKER_PIN, HIGH);
    beeping = 1;  
    start = 0;
  }
  else
    digitalWrite(SPEAKER_PIN, LOW);
}

void secPulse()
{
  if (start)
  {
    SS--;  
    if (SS == 0 && MM == 0)
    {
      beep();
      start = 0;
      return;
    }
    
    if (SS == -1 && MM > 0)
    {
      MM--;
      SS = 59;
    }

  }
}
void playTone(int tone, int duration) {
  for (long i = 0; i < duration * 1000L; i += tone * 2) 
  {          
    digitalWrite(SPEAKER_PIN, HIGH);
    delayMicroseconds(tone);
    digitalWrite(SPEAKER_PIN, LOW);
    delayMicroseconds(tone);
  }
}

void playNote(char note, int duration) {
  char names[] = { 'c', 'd', 'e', 'f', 'g', 'a', 'b', 'C', 'F', 'G'};
  int tones[] = { 1915, 1700, 1519, 1432, 1275, 1136, 1014, 473, 478};
  
  // play the tone corresponding to the note name
  for (int i = 0; i < 10; i++) {
    if (names[i] == note) 
    {
      playTone(tones[i], duration);
    }
  }
}

char * clearLeadingZero(char input[4])
{
  if (input[0] == '0')
  {
    input[0] = 0;    
    if (input[1] == '0')    
    {
      input[1] = 0;
      if (input[2] == '0')    
        input[2] = 0;
    }
  }
  
  return input;
}

void processLCD()
{
  static char chs[4] = {'0', '0', '0', '0'};
 
  if (start)
  {
    chs[3] = SS%10 + '0';
    chs[2] = SS/10 + '0';
    chs[1] = MM%10 + '0';
    chs[0] = MM/10 + '0';
    
    setChars(clearLeadingZero(chs), 2);
  }
  else
  {   
    setChars(input, 2);
  }  
}

void loop()
{  
  int someKeyDown = keypad.scanKeys(0);
  keypad.handlePostEvents(someKeyDown);      
 
  processLCD();
  
  if (beeping = 1)
  {
     beeping++;
     beeping %=3;
     
     for (int i = 0; i < length; i++) 
     {
       someKeyDown = keypad.scanKeys(0);
       keypad.handlePostEvents(someKeyDown);      

       processLCD();
       if (beeping != 0)
         playNote(notes[i], beats[i] * tempo/2);
    
       // pause between notes
       delay(tempo / 2); 
     } 
  } 
}

Advertisements

11 Responses to “Arduino Kitchen Timer”

  1. Matt Johnson Says:

    Hey, I’m looking to do a similar project like, with the addition of a needle on a servo to countdown the time. I am having a ton of problems with this project however, and I think you can help.

    How exactly did you wire the keypad so the arduino can accurately recognize all the keys?

    PLEASE HELP

    • genki Says:

      Hello Matt,

      How far did you go with the keypad?
      I don’t have the same setup anymore, but did you use the pull-up resistors?
      I used three 4.7K ohm Resistors for the columns wires.

      Good luck.

      • Matt Johnson Says:

        Thanks, the pull-up resistors make it work perfectly. Except now I want to optimize my pin usage. I am looking into reading the keypad with an 8-bit shift register. Do you know if/how this is possible?

      • genki Says:

        Shift register may work but you make sure you get the one that can do serial input and output. You may have to deal with some timing issue on key scanning. If I were you, I will use one more Atmega chip to do the job instead of using shift register.

  2. Abosebkk Says:

    Hi , I get a bunch of errors while trying to compile the code in arduino ide 0022. They are:
    GenKeypad.cpp 4 : error : prototype for ‘void Genkeypad::call(int,char)’ does not match any in class ‘Genkeypad’
    Genkeypad.h: 41: error :Candidate is :void Genkeypad :: call(char,char)
    Genkeypad.cpp : In member function ‘void Genkeypad: : setFunction(char, void(*)(char))’;

    • genki Says:

      Does the sample in the library works? If not, it’s just something to do with arduino IDE’s version.

  3. geckko Says:

    hello sir, i’m trying to make a kitchen timer using your schematic if possible, can you please post the schematic diagram diargram please.

    very much appreciated thank you

    • genki Says:

      Hi gecko,
      Unfortunately, I don’t have any schematic. I have never had any diagram either. I listed out all the parts, so it wouldn’t be too hard to build the same one. Good luck.

  4. Choque Says:

    What about the Shield port and the eagle schematic? :)

  5. Queenie Says:

    Hello. is the whole source code for the Arduino? Please reply. :'(
    I dont have any idea with the code/ pls help me.


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

%d bloggers like this: