/* Program 3-5 Scan the 4x4 matrix keypad and write the key code * to the LEDs and the Serial monitor. * */ const int LED[] = {10, 11, 12, 13}; void setup() { /* initialize Serial monitor */ Serial.begin(9600); Serial.println("Keypad:"); /* initialize LEDs for display */ for (int i = 0; i < 4; i++) { pinMode(LED[i], OUTPUT); } /* turn off all LEDs */ digitalGroupWrite(LED, 4, 0); /* initialize pins connected to keypad */ keypad_init(); } /* this loop function replaces the loop function of Program 3-5 */ void loop() { char key; key = keypad_getkey(); /* read the keypad */ digitalGroupWrite(LED, 4, key); /* and write it to the LEDs */ /* if a key is pressed, send the key code to Serial monitor */ if(key != 0) { Serial.print(" key = "); Serial.println(key, DEC); delay(10); /* wait 10 ms for contact bounce */ while(keypad_getkey() != 0) {} /* wait for key release */ delay(10); /* wait 10 ms for contact bounce */ } } /* This function intialize the pins connected to the keypad. * Rows are used as excitation and columns are used as input. * * The connections between the keypad and the pins are: * Function Arduino * row 0 9 J3-23 - J4-37 * row 1 8 J3-24 - J4-38 * row 2 7 J3-25 - J2-19 * row 3 6 J3-26 - J4-39 * col 0 5 J2-11 - J4-40 * col 1 4 J2-12 - J4-36 * col 2 3 J2-13 - J1-4 * col 3 2 J1-8 - J1-3 */ const int ROW[] = {6, 7, 8, 9}; const int COL[] = {2, 3, 4, 5}; void keypad_init(void) { /* all pins are initialized as input */ for (int i = 0; i < 4; i++) { pinMode(ROW[i], INPUT_PULLUP); pinMode(COL[i], INPUT_PULLUP); } } /* This is a non-blocking function to read the keypad. If a key is pressed, * it returns a keycode. Otherwise, a zero is returned. * Columns are used as input. There are configured with internal pullup. * When these pins are not active, they are high. * Rows are used for excitation. First all rows are driven low and the * input pins are read. If no keys are pressed, it will read all ones. * Otherwise, some key is pressed. * If any key is pressed, the program drives one row low at a time and * leave the rest of the rows inactive (pulled high by internal pullup) * then read the input pins. Knowing which row is active and which * column is active, the program can decide the key that is pressed. */ char keypad_getkey(void) { int i; int row, col; /* check to see any key pressed first */ /* enable all rows as output */ for (i = 0; i < 4; i++) pinMode(ROW[i], OUTPUT); digitalGroupWrite(ROW, 4, 0x00); /* drive all rows low */ /* read all columns */ col = digitalGroupRead(COL, 4); /* disable all rows */ for (i = 0; i < 4; i++) pinMode(ROW[i], INPUT_PULLUP); if (col == 0x0F) return 0; /* no key pressed, return a zero */ /* If a key is pressed, it comes here to find out which key is pressed. */ /* One row is activated at a time and the inputs are read to see */ /* which column is active. */ for (row = 0; row < 4; row++) { /* disable all rows */ for (i = 0; i < 4; i++) pinMode(ROW[i], INPUT_PULLUP); pinMode(ROW[row], OUTPUT); /* enable one row */ digitalWrite(ROW[row], LOW); /* drive the active row low */ delayMicroseconds(10); /* wait for signal to settle */ col = digitalGroupRead(COL, 4); /* read all columns */ if (col != 0x0F) break; /* if not all the inputs are high, some key is pressed. */ } /* disable all rows */ for (i = 0; i < 4; i++) pinMode(ROW[i], INPUT_PULLUP); if (row == 4) return 0; /* if we get here, no key is pressed */ /* gets here when one of the rows has key pressed */ if (col == 0xE) return row * 4 + 1; /* key in column 0 */ if (col == 0xD) return row * 4 + 2; /* key in column 1 */ if (col == 0xB) return row * 4 + 3; /* key in column 2 */ if (col == 0x7) return row * 4 + 4; /* key in column 3 */ return 0; /* just to be safe */ } /* write to a group of output pins */ void digitalGroupWrite(const int* group, int length, int data) { for (length--; length >= 0; length--) { digitalWrite(group[length], data & (1 << length) ? HIGH : LOW); } } /* read from a group of input pins */ int digitalGroupRead(const int* group, int length) { int data = 0; for (length--; length >= 0; length--) { data <<= 1; data |= digitalRead(group[length]) ? 1 : 0; } return data; }