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); } } }