3x4 keypad library (Extended not only 3x4 but 4x4,4x5 and 5x5 keys)

Dependents:   Keypad_input_OS2 Keypad_input

see /users/kenjiArai/notebook/keypadkey-matrix--control/

Revision:
3:0ea41738b560
Parent:
2:a3545b56bdd7
Child:
4:f74ca02cdba1
--- a/Keypad.cpp	Thu Dec 21 22:46:19 2017 +0000
+++ b/Keypad.cpp	Mon Apr 06 04:53:25 2020 +0000
@@ -1,107 +1,190 @@
 /*
- * Mbed Library / Akizuki AE-KIT45-KEYPAD4X3
- *  http://akizukidenshi.com/catalog/g/gK-12229/
+ * Mbed Library
+ *  example:
+ *      Akizuki AE-KIT45-KEYPAD4X3
+ *      http://akizukidenshi.com/catalog/g/gK-12229/
  *
- * Copyright (c) 2017 Kenji Arai / JH1PJL
- *  http://www.page.sannet.ne.jp/kenjia/index.html
- *  http://mbed.org/users/kenjiArai/
+ * Copyright (c) 2017,'20 Kenji Arai / JH1PJL
+ *  http://www7b.biglobe.ne.jp/~kenjia/
+ *  https://os.mbed.com/users/kenjiArai/
  *      Created:    September 27th, 2017
- *      Revised:    December  22nd, 2017
+ *      Revised:    April      6th, 2020
  */
 
 #include "Keypad.h"
 
-//extern Serial pc;
-//extern DigitalOut my_led;
+//#define DEBUG_LED     // for debug
+
+#if defined(DEBUG_LED)
+extern DigitalOut my_led;
+#define LEDON   {my_led=1;}
+#define LEDOFF  {my_led=0;}
+#else
+#define LEDON   {;}
+#define LEDOFF  {;}
+#endif
 
 Keypad::Keypad(
     PinName kx, PinName ky, PinName kz,
     PinName ka, PinName kb, PinName kc, PinName kd
 )
 {
-    k_in[0]  = new DigitalIn (ka, PullUp);
-    k_in[1]  = new DigitalIn (kb, PullUp);
-    k_in[2]  = new DigitalIn (kc, PullUp);
-    k_in[3]  = new DigitalIn (kd, PullUp);
-    k_out[0] = new DigitalOut (kx);
-    k_out[1] = new DigitalOut (ky);
-    k_out[2] = new DigitalOut (kz);
+    k_in[0]  = new DigitalIn(ka, PullUp);
+    k_in[1]  = new DigitalIn(kb, PullUp);
+    k_in[2]  = new DigitalIn(kc, PullUp);
+    k_in[3]  = new DigitalIn(kd, PullUp);
+    k_out[0] = new DigitalOut(kx);
+    k_out[1] = new DigitalOut(ky);
+    k_out[2] = new DigitalOut(kz);
+    key_mode    = 12;
+    key_in_num  = 4;
+    key_out_num = 3;
+    initialize();
+}
+
+Keypad::Keypad(
+    PinName kx, PinName ky, PinName kz, PinName kw,
+    PinName ka, PinName kb, PinName kc, PinName kd
+)
+{
+    k_in[0]  = new DigitalIn(ka, PullUp);
+    k_in[1]  = new DigitalIn(kb, PullUp);
+    k_in[2]  = new DigitalIn(kc, PullUp);
+    k_in[3]  = new DigitalIn(kd, PullUp);
+    k_out[0] = new DigitalOut(kx);
+    k_out[1] = new DigitalOut(ky);
+    k_out[2] = new DigitalOut(kz);
+    k_out[3] = new DigitalOut(kw);
+    key_mode    = 16;
+    key_in_num  = 4;
+    key_out_num = 4;
+    initialize();
+}
+
+Keypad::Keypad(
+    PinName kx, PinName ky, PinName kz, PinName kw,
+    PinName ka, PinName kb, PinName kc, PinName kd, PinName ke
+)
+{
+    k_in[0]  = new DigitalIn(ka, PullUp);
+    k_in[1]  = new DigitalIn(kb, PullUp);
+    k_in[2]  = new DigitalIn(kc, PullUp);
+    k_in[3]  = new DigitalIn(kd, PullUp);
+    k_in[4]  = new DigitalIn(ke, PullUp);
+    k_out[0] = new DigitalOut(kx);
+    k_out[1] = new DigitalOut(ky);
+    k_out[2] = new DigitalOut(kz);
+    k_out[3] = new DigitalOut(kw);
+    key_mode    = 20;
+    key_in_num  = 5;
+    key_out_num = 4;
+    initialize();
+}
+
+Keypad::Keypad(
+    PinName kx, PinName ky, PinName kz, PinName kw, PinName kv,
+    PinName ka, PinName kb, PinName kc, PinName kd, PinName ke
+)
+{
+    k_in[0]  = new DigitalIn(ka, PullUp);
+    k_in[1]  = new DigitalIn(kb, PullUp);
+    k_in[2]  = new DigitalIn(kc, PullUp);
+    k_in[3]  = new DigitalIn(kd, PullUp);
+    k_in[4]  = new DigitalIn(ke, PullUp);
+    k_out[0] = new DigitalOut(kx);
+    k_out[1] = new DigitalOut(ky);
+    k_out[2] = new DigitalOut(kz);
+    k_out[3] = new DigitalOut(kw);
+    k_out[4] = new DigitalOut(kv);
+    key_mode    = 25;
+    key_in_num  = 5;
+    key_out_num = 5;
+    initialize();
+}
+
+void Keypad::initialize(void)
+{
     *k_out[0] = 1;
     *k_out[1] = 1;
     *k_out[2] = 1;
+    if (key_mode > 12) {
+        *k_out[3] = 1;
+    }
+    if (key_mode > 20) {
+        *k_out[4] = 1;
+    }
     uint8_t j,i;
-    for (j = 0; j < 3; j++){
-        for(i = 0; i < 4; i++){
+    for (j = 0; j < key_out_num; j++) {
+        for(i = 0; i < key_in_num; i++) {
             key_transent_cntr[j][i] = CHNG_CNT;
-            key_state[j][i] = Off_state;
+            key_state[j][i] = OFF_state;
         }
     }
-    for(i = 0; i < BF_SIZE; i++){
+    for(i = 0; i < BF_SIZE; i++) {
         buf[i] = 0;
     }
     read_addr = 0;
     write_addr = 0;
-    tk.attach_us(callback(this, &Keypad::key_scan), 2000);     // 2mS
+    tk.attach_us(callback(this, &Keypad::key_scan), 2000); // 2mS
 }
 
 void Keypad::key_scan(void)
 {
-    //my_led = 1;
-    for (int32_t j = 0; j < 3; j++){
-        *k_out[0] = 1;   *k_out[1] = 1;  *k_out[2] = 1;
+    LEDON;
+    for (int32_t j = 0; j < key_out_num; j++) {
+        for (int32_t k = 0; k < key_out_num; k++) {
+            *k_out[k] = 1;
+        }
         *k_out[j] = 0;
         wait_us(1);
-        for (int32_t i = 0; i < 4; i++){
-            switch (key_state[j][i]){
-                case Off_state:
-                    //my_led = 1;
-                    if (*k_in[i] == 0){ // key on
-                        key_state[j][i] = Off_to_on_transient;
+        for (int32_t i = 0; i < key_in_num; i++) {
+            switch (key_state[j][i]) {
+                case OFF_state:
+                    if (*k_in[i] == 0) { // key on
+                        key_state[j][i] = OFF_to_ON_transient;
                         key_transent_cntr[j][i] = CHNG_CNT;
                     }
                     break;
-                case Off_to_on_transient:
-                    //my_led = 1;
-                    if (*k_in[i] == 0){ // key on
-                        if (--key_transent_cntr[j][i] < -CHNG_CNT){
-                            //my_led = 1;
-                            bf_put(j * 4 + i + 1); // save data into buffer
-                            key_state[j][i] = On_state;
+                case OFF_to_ON_transient:
+                    if (*k_in[i] == 0) { // key on
+                        if (--key_transent_cntr[j][i] < -CHNG_CNT) {
+                            // save data into buffer
+                            bf_put(j * key_in_num + i + 1);
+                            key_state[j][i] = ON_state;
                         }
                     } else {    // key off
-                        if (++key_transent_cntr[j][i] > CHNG_CNT){
-                            key_state[j][i] = Off_state;
+                        if (++key_transent_cntr[j][i] > CHNG_CNT) {
+                            key_state[j][i] = OFF_state;
                         }
                     }
                     break;
-                case On_state:
-                    //my_led = 1;
-                    if (*k_in[i] == 1){ // key off
-                        key_state[j][i] = On_to_off_transient;
+                case ON_state:
+                    if (*k_in[i] == 1) { // key off
+                        key_state[j][i] = ON_to_OFF_transient;
                         key_transent_cntr[j][i] = -CHNG_CNT;
                     }
                     break;
-                case On_to_off_transient:
-                    //my_led = 1;
-                    if (*k_in[i] == 0){ // key on
-                        if (--key_transent_cntr[j][i] < -CHNG_CNT){
-                            key_state[j][i] = On_state;
+                case ON_to_OFF_transient:
+                    if (*k_in[i] == 0) { // key on
+                        if (--key_transent_cntr[j][i] < -CHNG_CNT) {
+                            key_state[j][i] = ON_state;
                         }
                     } else {    // key off
-                        if (++key_transent_cntr[j][i] > CHNG_CNT){
-                            key_state[j][i] = Off_state;
+                        if (++key_transent_cntr[j][i] > CHNG_CNT) {
+                            key_state[j][i] = OFF_state;
                         }
                     }
                     break;
                 default:    // just in case
-                    key_state[j][i] = Off_state;
+                    key_state[j][i] = OFF_state;
                     break;
             }
-            //my_led = 0;
         }
     }
-    *k_out[0] = 1;   *k_out[1] = 1;  *k_out[2] = 1;
-    //my_led = 0;
+    for (int32_t k = 0; k < key_out_num; k++) {
+        *k_out[k] = 1;
+    }
+    LEDOFF;
 }
 
 uint8_t Keypad::read(void)
@@ -109,6 +192,18 @@
     return bf_get();
 }
 
+bool Keypad::read_state(uint8_t key_num)
+{
+    
+    uint8_t x = (key_num - 1) % key_out_num;
+    uint8_t y = (key_num - 1)/ key_out_num;
+    if (key_state[y][x] == ON_state) {
+        return true;
+    } else {
+        return false;
+    }
+}
+
 void Keypad::bf_put(char dt)
 {
     uint8_t next = write_addr + 1;
@@ -119,13 +214,14 @@
     write_addr = next;
 }
 
-int8_t Keypad::bf_get (void){
-    if (read_addr == write_addr){
+int8_t Keypad::bf_get (void)
+{
+    if (read_addr == write_addr) {
         return 0;
     }
     uint8_t dt = buf[read_addr];
     ++read_addr;
-    if (read_addr == BF_SIZE){
+    if (read_addr == BF_SIZE) {
         read_addr = 0;
     }
     return dt;