Uses an Adafruit 3x4 Keypad // Pin allocation for keypad COLUMNS #define Col1 4 // pin for Col 1 #define Col2 2 // pin for Col 2 #define Col3 6 // pin for Col 3 #define Col4 9 // pin for Col 4 (only present on 4x4 keypad) // Pin allocation for keypad ROWS #define Row1 3 // pin for Row 1 #define Row2 8 // pin for Row 2 #define Row3 7 // pin for Row 3 #define Row4 5 // pin for Row 4 // pin allocations for tone outputs #define tone1Pin 12 // pin for tone 1 #define tone2Pin 13 // pin for tone 2 #define NoKey 0xff // no key pressed const byte columns[] = {Col1, Col2, Col3}; // list of all columns const byte rows[] = {Row1, Row2, Row3, Row4}; // list of all rows const byte NumCols = sizeof(columns) / sizeof(byte); // calculate number of columns const byte NumRows = sizeof(rows) / sizeof(byte); // calculate number of rows byte LastKey = NoKey; // last key pressed int DTMF[][2] = { {697, 1209}, // frequencies for key 1 {770, 1209}, // frequencies for key 4 {852, 1209}, // frequencies for key 7 {941, 1209}, // frequencies for key * {697, 1336}, // frequencies for key 2 {770, 1336}, // frequencies for key 5 {852, 1336}, // frequencies for key 8 {941, 1336}, // frequencies for key 0 {697, 1477}, // frequencies for key 3 {770, 1477}, // frequencies for key 6 {852, 1477}, // frequencies for key 9 {941, 1477}, // frequencies for key # {697, 1633}, // frequencies for key A {770, 1633}, // frequencies for key B {852, 1633}, // frequencies for key C {941, 1633}, // frequencies for key D }; int ReadKeyPad() { byte result = NoKey; // no key pressed for (int c = 0; c < NumCols; c++) digitalWrite(columns[c], HIGH); // set all columns HIGH for (int c = 0; c < NumCols; c++) { // scan each column digitalWrite(columns[c], LOW); // set column LOW for (int r = 0; r < NumRows; r++) { // scan each row for LOW on any row if (digitalRead(rows[r]) == LOW) { delay(50); // in case of bounce if (digitalRead(rows[r]) == LOW) return c * 4 + r; } } digitalWrite(columns[c], HIGH); } return result; } void setup() { // initialise row readers for (int i = 0; i < NumRows; i++) pinMode(rows[i], INPUT_PULLUP); // Set row drivers to INPUT // initialise column drivers for (int i = 0; i < NumCols; i++) { pinMode(columns[i], OUTPUT); // Set column drivers to OUTPUT digitalWrite(columns[i], HIGH); } pinMode(tone1Pin, OUTPUT); // Output for Tone 1 pinMode(tone2Pin, OUTPUT); // Output for Tone 2 Serial.begin(9600); // Set serial port speed } void loop() { byte key = ReadKeyPad(); // read any key being pressed if (key != LastKey) // key has changed switch (key) { case NoKey: break; // nothing to do default: // play tones Serial.print("Pressed "); Serial.println(key); // Debug only playDTMF(key, 200); // changes tone length break; } LastKey = key; // remember last key pressed } void playDTMF(byte digit, unsigned long duration) { // Play the DTMF digit for duration millisecs unsigned long tone1delay = (500000 / DTMF[digit][0]) - 10; // calculate delay (in microseconds) for tone 1 (half of the period of one cycle). 10 is a fudge factor to raise the frequency due to sluggish timing. unsigned long tone2delay = (500000 / DTMF[digit][1]) - 10; // calculate delay (in microseconds) for tone 2 (half of the period of one cycle). 10 is a fudge factor to raise the frequency due to sluggish timing. unsigned long tone1timer = micros(); unsigned long tone2timer = micros(); unsigned long timer = millis(); // for timing duration of a single tone while (millis() - timer < duration) { if (micros() - tone1timer > tone1delay) { tone1timer = micros(); // reset the timer if (digitalRead(tone1Pin) == HIGH) digitalWrite(tone1Pin, LOW); else digitalWrite(tone1Pin, HIGH); // toggle tone output } if (micros() - tone2timer > tone2delay) { tone2timer = micros(); // reset the timer if (digitalRead(tone2Pin) == HIGH) digitalWrite(tone2Pin, LOW); else digitalWrite(tone2Pin, HIGH); // toggle tone output } } digitalWrite(tone1Pin, LOW); digitalWrite(tone2Pin, LOW); }