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); } } }
November 12, 2009 at 11:53 pm
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
November 13, 2009 at 3:39 pm
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.
November 14, 2009 at 8:47 pm
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?
November 15, 2009 at 1:07 am
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.