// EPOCH PROJECT#25 - THE MATRIX KEYPAD // LET'S LEARN HOW TO USE THE MATRIX KEYPAD FINALLY. I PREFER THE ANALOG KEYPAD FOR SO MANY REASONS, BUT IT IS IMPORTANT TO UNDERSTAND HOW THE MATRIX KEYPAD WORKS. // CONNECT GPIO PINS 6 THROUGH 13 (8 GPIO PINS) TO MATRIX KEYPAD PINS 1 THROUGH 8 RESPECTIVELY. SO 6 TO 1, 7 TO 2, ETC. // THERE ARE LIBRARIES TO MAKE THIS PROJECT EASIER, BUT LET'S BIT-BYTE IT OUT. THAT IS HOW WE LEARN =D #define row1 10 // DECLARE THE ROWS AND COLUMNS TO THE GPIO PINS ON CHIP-A SEEN BELOW #define row2 11 #define row3 12 #define row4 13 #define column1 6 #define column2 7 #define column3 8 #define column4 9 int hold = 0; // WE'LL USE THIS INTEGER TO HOLD THE VALUE OF THE BUTTON BEING PUSHED boolean whileholder = false; // WE'LL USE THIS BOOLEAN FUNCTION TO DETERMINE WHEN TWO WHILE LOOPS END void setup() { Serial.begin(9600); // START THE SERIAL MONITOR Serial.println("Matrix Keypads"); // PRINT THIS TO THE SERIAL MONITOR, AND GO TO THE NEXT LINE ("ln") pinMode(row1,OUTPUT); // SET UP ROWS AS OUTPUTS, AND COLUMNS AS INPUTS pinMode(row2,OUTPUT); pinMode(row3,OUTPUT); pinMode(row4,OUTPUT); pinMode(column1,INPUT); pinMode(column2,INPUT); pinMode(column3,INPUT); pinMode(column4,INPUT); } void loop() { getbutton(); // THIS FUNCTION WAITS FOR A BUTTON TO BE PUSHED. ONCE PUSHED, IT PLACES THE BUTTON VALUE IN hold, AND THEN WAITS FOR THE USER TO LET GO OF THE BUTTON Serial.print(hold); // PRINT THE BUTTON VALUE TO THE SERIAL MONITOR } void getbutton() // WAIT FOR A BUTTON TO BE PRESSED { whileholder = false; // SET UP OUR BOOLEAN TO BE FALSE while(whileholder == false){ // ONLY WHEN whildholder EQUALS TRUE WILL THIS WHILE LOOP END. THIS WHILE LOOP WAITS FOR A BUTTON TO BE PRESSED. { digitalWrite(row1,HIGH); // TURN ROW1 ON/HIGH/5v delay(50); // WAIT 50ms. if(digitalRead(column1) == HIGH) // IS COLUMN1 HIGH? IF SO, YOU'VE PRESSED BUTTON#1 (SEE VALUE BELOW IN hold. IF column1 IS LOW, THEN SKIP TO THE NEXT if STATEMENT. { hold = 1; // BUTTON 1 HAS BEEN PRESSED buttonletgo(); // CALL THE buttonletgo FUNCTION. THIS FUNCTION WANTS FOR THE USER TO LET GO OF THE BUTTON, AND ONCE DONE, SETS whileholder TO TRUE, WHICH ENDS THIS LOOP WHEN THE FUNCTION RETURNS. } if(digitalRead(column2) == HIGH) // THE REST OF THIS FUNCTION FOR THE MOST PART REPEATS THE ABOVE if STATEMENT. THE REST OF THIS CODE WANTS FOR BUTTONS TO BE PRESSED, AND THEN DECODES WHICH BUTTON WAS PRESSED. { hold = 4; buttonletgo(); } if(digitalRead(column3) == HIGH) { hold = 7; buttonletgo(); } if(digitalRead(column4) == HIGH) { hold = 10; // 10 IS STAR buttonletgo(); } digitalWrite(row1,LOW); // TURN ROW1 OFF digitalWrite(row2,HIGH); // THEN IMMEDIATELY TURN ON ROW2. delay(50); // LOOK FAMILIAR? if(digitalRead(column1) == HIGH) { hold = 2; buttonletgo(); } if(digitalRead(column2) == HIGH) { hold = 5; buttonletgo(); } if(digitalRead(column3) == HIGH) { hold = 8; buttonletgo(); } if(digitalRead(column4) == HIGH) { hold = 0; buttonletgo(); } digitalWrite(row2,LOW); digitalWrite(row3,HIGH); delay(50); if(digitalRead(column1) == HIGH) { hold = 3; buttonletgo(); } if(digitalRead(column2) == HIGH) { hold = 6; buttonletgo(); } if(digitalRead(column3) == HIGH) { hold = 9; buttonletgo(); } if(digitalRead(column4) == HIGH) { hold = 11; // 11 IS THE #/POUND SYMBOL buttonletgo(); } digitalWrite(row3,LOW); digitalWrite(row4,HIGH); delay(50); if(digitalRead(column1) == HIGH) { hold = 17; // 17 IS A buttonletgo(); } if(digitalRead(column2) == HIGH) { hold = 18; // 18 = B buttonletgo(); } if(digitalRead(column3) == HIGH) { hold = 19; // 19 = C buttonletgo(); } if(digitalRead(column4) == HIGH) { hold = 20; // 20 = D buttonletgo(); } digitalWrite(row4,LOW); } } } // END OF VOID LOOP void buttonletgo() // THIS FUNCTION WAITS FOR THE USER TO RELEASE THE BUTTON { digitalWrite(row1,HIGH); // TURN ON ALL ROWS digitalWrite(row2,HIGH); digitalWrite(row3,HIGH); digitalWrite(row4,HIGH); while(whileholder == false){ // LOOK! ANOTHER WHILE LOOP USING whileholder! WE ARE ACTUALLY STILL IN THE ORIGINAL WHILE LOOP, ONLY WE'VE CALLED A FUNCTION. WHEN THIS FUNCTION TURNS whileholder TO TRUE, THEN WE WILL END BOTH WHILE LOOPS { if(digitalRead(column1) == LOW) // IF ALL OF THE columns ARE LOW (0V) THEN WE'LL TURN whileholder TO TRUE, WHICH ENDS BOTH WHILE LOOPS. IF ANY colums ARE HIGH, THEN THIS WHILE LOOP WILL CONTINUE TO LOOP AND WAIT FOR RELEASE. { if(digitalRead(column2) == LOW) { if(digitalRead(column3) == LOW) { if(digitalRead(column4) == LOW) { whileholder = true; } } } } } } digitalWrite(row1,LOW); // AFTER whileholder IS SET TO TRUE, THE LAST OF THE CODE (THIS PART) EXECUTES ONCE BEFORE THE WHILE LOOP ENDS. THIS TURNS ALL rows OFF. digitalWrite(row2,LOW); digitalWrite(row3,LOW); digitalWrite(row4,LOW); } // NOTES // I DON'T LIKE MATRIX KEYPADS. TOO MUCH CODE, AND TOO MANY GPIO PINS. // PLEASE DO THIS CHALLENGE. FIND A LIBRARY FOR A 16 DIGIT MATRIX KEYPAD, AND TRY TO USE IT IN PLACE OF ALL OF THIS CODE. YOU CAN SAVE YOURSELF SOME TIME AND CODE SPACE IF YOU USE A LIBRARY. // DID I MENTION THAT i DON'T LIKE MATRIX KEYPADS? ANALOG RESISTOR BASED KEYPAD WUT WUT!