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/

Files at this revision

API Documentation at this revision

Comitter:
kenjiArai
Date:
Mon Apr 06 04:53:25 2020 +0000
Parent:
2:a3545b56bdd7
Child:
4:f74ca02cdba1
Commit message:
Extended not only 3x4 but 4x4,4x5 and 5x5 keys

Changed in this revision

Keypad.cpp Show annotated file Show diff for this revision Revisions of this file
Keypad.h Show annotated file Show diff for this revision Revisions of this file
--- 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;
--- a/Keypad.h	Thu Dec 21 22:46:19 2017 +0000
+++ b/Keypad.h	Mon Apr 06 04:53:25 2020 +0000
@@ -1,12 +1,29 @@
 /*
- * 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
+ */
+// ---- Merged below and added 4x5=20, 5x5=25 library --------------------------
+
+/*
+ * 4x4 Fork: Henri Clarke
+ *          May 17th, 2018
+ *      https://os.mbed.com/users/microHenri/code/Keypad/
+ */
+
+/*
+ *  Performance
+ *      every 2ms runs XuS for key detection(5x5=25 keys)
+ *          on Nucleo-F446RE ->X=10uS, CPU occupancy is around 0.5%
+ *          on Nucleo-L152RE ->X=50uS, CPU occupancy is around 2.5%
+ *          on FRDM-K64F     ->X=28uS, CPU occupancy is around 1.4%
  */
 
 #ifndef KEYPAD_H
@@ -14,14 +31,48 @@
 
 #include "mbed.h"
 
-#define  CHNG_CNT       3
+#define  CHNG_CNT       4
+
+//------------- ASCII CODE ---------------
+#define NUL     0x00
+#define SOH     0x01
+#define STX     0x02
+#define ETX     0x03
+#define EOT     0x04
+#define ENQ     0x05
+#define ACK     0x06
+#define BEL     0x07
+#define BS      0x08
+#define HT      0x09
+#define LF      0x0a
+#define VT      0x0b
+#define FF      0x0c
+#define CR      0x0d
+#define SD      0x0e
+#define SI      0x0f
+#define DLE     0x10
+#define DC1     0x11
+#define DC2     0x12
+#define DC3     0x13
+#define DC4     0x14
+#define NAK     0x15
+#define SYN     0x16
+#define ETB     0x17
+#define CAN     0x18
+#define EM      0x19
+#define SUB     0x1a
+#define ESC     0x1b
+#define FS      0x1c
+#define GS      0x1d
+#define RS      0x1e
+#define US      0x1f
+#define SPC     0x20
 
 /**
  * @code
  * #include "mbed.h"
  * #include "Keypad.h"
  *
- * // every 2ms runs 6uS for key detection(CPU occupancy is 0.3%/Nucleo-F446RE)
  * //       output port  X  Y  Z
  * //       Input A      *  0  #
  * //       Input B      7  8  9
@@ -39,13 +90,14 @@
  *         while ((key_num = key.read()) != 0){
  *             printf("%c\r\n", *(key_table + key_num));
  *         }
- *         wait(1.0);  
+ *         wait(1.0);
  *     }
  * }
  * @endcode
  */
 
-class Keypad {
+class Keypad
+{
 public:
     /** 4x3 keypad interface:
      *  @param key input port           A,B,C,D
@@ -53,31 +105,66 @@
      */
     Keypad(PinName kx, PinName ky, PinName kz,
            PinName ka, PinName kb, PinName kc, PinName kd);
-                    
+
+    /** 4x4 keypad interface:
+     *  @param key input port           A,B,C,D
+     *  @param key output(scan) port    X,Y,Z,W
+     */
+    Keypad(PinName kx, PinName ky, PinName kz, PinName kw,
+           PinName ka, PinName kb, PinName kc, PinName kd);
+
+    /** 5x4 keypad interface:
+     *  @param key input port           A,B,C,D,E
+     *  @param key output(scan) port    X,Y,Z,W
+     */
+    Keypad(PinName kx, PinName ky, PinName kz, PinName kw,
+           PinName ka, PinName kb, PinName kc, PinName kd, PinName ke);
+
+    /** 5x5 keypad interface:
+     *  @param key input port           A,B,C,D,E
+     *  @param key output(scan) port    X,Y,Z,W,V
+     */
+    Keypad(PinName kx, PinName ky, PinName kz, PinName kw, PinName kv,
+           PinName ka, PinName kb, PinName kc, PinName kd, PinName ke);
+
     /** Read key data into buffer
      *  @param none
      *  @return key number by ASCII code
      */
     uint8_t read(void);
 
+    /** Read key ON/OFF state
+     *  @param none
+     *  @return ON(true) or OFF(false)
+     */
+    bool read_state(uint8_t key_num);
+
 protected:
-    DigitalIn   *k_in[4];
-    DigitalOut  *k_out[3];
+#define BF_SIZE     32
+#define NUM         5
+
+    DigitalIn   *k_in[NUM];
+    DigitalOut  *k_out[NUM];
     Ticker      tk;
 
     // key control
-    enum State {Off_state, Off_to_on_transient, On_state, On_to_off_transient};
-    volatile State  key_state[3][4];
-    volatile int8_t key_transent_cntr[3][4];
+    enum State {OFF_state, OFF_to_ON_transient, ON_state, ON_to_OFF_transient};
+    volatile State  key_state[NUM][NUM];
+    volatile int8_t key_transent_cntr[NUM][NUM];
     void key_scan(void);
-    
+    void initialize(void);
+
+    // mode control
+    uint8_t key_mode;
+    uint8_t key_in_num;
+    uint8_t key_out_num;
+
     // buffer control
-    #define BF_SIZE 16
-    uint8_t         read_addr;
-    uint8_t         write_addr;
-    uint8_t         buf[BF_SIZE];
-    void bf_put (char dat);
-    int8_t bf_get (void);
+    uint8_t read_addr;
+    uint8_t write_addr;
+    uint8_t buf[BF_SIZE];
+    void bf_put(char dat);
+    int8_t bf_get(void);
 
 };