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, committed 2020-04-06
- 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); };