This is a demonstration of keypadEvents. It's used to switch between keymaps while using only one keypad.
Dependencies: Hotboards_keypad mbed
Fork of DynamicKeypad by
main.cpp
- Committer:
- Hotboards
- Date:
- 2016-03-08
- Revision:
- 1:0c22e424ea51
- Parent:
- 0:d8190262fb61
File content as of revision 1:0c22e424ea51:
/* @file Hotboards_keypad.cpp || @version 1.2 || @author Mark Stanley || @contact mstanley@technologist.com || || 07/11/12 - Re-modified (from DynamicKeypadJoe2) to use direct-connect kpds || 02/28/12 - Modified to use I2C i/o G. D. (Joe) Young || || || @dificulty: Intermediate || || @description || | This is a demonstration of keypadEvents. It's used to switch between keymaps || | while using only one keypad. The main concepts being demonstrated are: || | || | Using the keypad events, PRESSED, HOLD and RELEASED to simplify coding. || | How to use setHoldTime() and why. || | Making more than one thing happen with the same key. || | Assigning and changing keymaps on the fly. || | || | Another useful feature is also included with this demonstration although || | it's not really one of the concepts that I wanted to show you. If you look || | at the code in the PRESSED event you will see that the first section of that || | code is used to scroll through three different letters on each key. For || | example, pressing the '2' key will step through the letters 'd', 'e' and 'f'. || | || | || | Using the keypad events, PRESSED, HOLD and RELEASED to simplify coding || | Very simply, the PRESSED event occurs imediately upon detecting a pressed || | key and will not happen again until after a RELEASED event. When the HOLD || | event fires it always falls between PRESSED and RELEASED. However, it will || | only occur if a key has been pressed for longer than the setHoldTime() interval. || | || | How to use setHoldTime() and why || | Take a look at keypad.setHoldTime(500) in the code. It is used to set the || | time delay between a PRESSED event and the start of a HOLD event. The value || | 500 is in milliseconds (mS) and is equivalent to half a second. After pressing || | a key for 500mS the HOLD event will fire and any code contained therein will be || | executed. This event will stay active for as long as you hold the key except || | in the case of bug #1 listed above. || | || | Making more than one thing happen with the same key. || | If you look under the PRESSED event (case PRESSED:) you will see that the '#' || | is used to print a new line, Serial.println(). But take a look at the first || | half of the HOLD event and you will see the same key being used to switch back || | and forth between the letter and number keymaps that were created with alphaKeys[4][5] || | and numberKeys[4][5] respectively. || | || | Assigning and changing keymaps on the fly || | You will see that the '#' key has been designated to perform two different functions || | depending on how long you hold it down. If you press the '#' key for less than the || | setHoldTime() then it will print a new line. However, if you hold if for longer || | than that it will switch back and forth between numbers and letters. You can see the || | keymap changes in the HOLD event. || | || | || | In addition... || | You might notice a couple of things that you won't find in the Arduino language || | reference. The first would be #include <ctype.h>. This is a standard library from || | the C programming language and though I don't normally demonstrate these types of || | things from outside the Arduino language reference I felt that its use here was || | justified by the simplicity that it brings to this sketch. || | That simplicity is provided by the two calls to isalpha(key) and isdigit(key). || | The first one is used to decide if the key that was pressed is any letter from a-z || | or A-Z and the second one decides if the key is any number from 0-9. The return || | value from these two functions is either a zero or some positive number greater || | than zero. This makes it very simple to test a key and see if it is a number or || | a letter. So when you see the following: || | || | if (isalpha(key)) // this tests to see if your key was a letter || | || | And the following may be more familiar to some but it is equivalent: || | || | if (isalpha(key) != 0) // this tests to see if your key was a letter || | || | And Finally... || | To better understand how the event handler affects your code you will need to remember || | that it gets called only when you press, hold or release a key. However, once a key || | is pressed or held then the event handler gets called at the full speed of the loop(). */ #include "mbed.h" #include "Hotboards_keypad.h" #include <ctype.h> // Define the keymaps. The blank spot (lower left) is the space character. char alphaKeys[ 4 ][ 4 ] = { { 'a' , 'd' , 'g' }, { 'j' , 'm' , 'p' }, { 's' , 'v' , 'y' }, { ' ' , '.' , '#' } }; char numberKeys[ 4 ][ 4 ] = { { '1' , '2' , '3' }, { '4' , '5' , '6' }, { '7' , '8' , '9' }, { ' ' , '0' , '#' } }; bool alpha = false; // Start with the numeric keypad. // Defines the pins connected to the rows DigitalInOut rowPins[ 4 ] = { PA_6 , PA_7 , PB_6 , PC_7 }; // Defines the pins connected to the cols DigitalInOut colPins[ 4 ] = { PA_8 , PB_10 , PB_4 , PB_5 }; // Create two new keypads, one is a number pad and the other is a letter pad. Keypad numpad( makeKeymap( numberKeys ) , rowPins , colPins , 4 , 4 ); Keypad ltrpad( makeKeymap( alphaKeys ) , rowPins , colPins , 4 , 4 ); int startTime; // For this example we will use the Nucleo LED1 on pin PA_5 DigitalOut led1( LED1 ); // Configures the serial port Serial pc( USBTX , USBRX ); // Configures a timer Timer t; char key; static char virtKey = NO_KEY; // Stores the last virtual key press. (Alpha keys only) static char physKey = NO_KEY; // Stores the last physical key press. (Alpha keys only) static char buildStr[ 12 ]; static uint8_t buildCount; static uint8_t pressCount; static uint8_t kpadState; // Take care of some special events. void swOnState( char key ) { switch( kpadState ) { case PRESSED: if( isalpha( key ) ) // This is a letter key so we're using the letter keymap. { if( physKey != key ) // New key so start with the first of 3 characters. { pressCount = 0; virtKey = key; physKey = key; } else // Pressed the same key again... { virtKey ++; // so select the next character on that key. pressCount ++; // Tracks how many times we press the same key. } if( pressCount > 2 ) // Last character reached so cycle back to start. { pressCount = 0; virtKey = key; } pc.printf( "%c" , virtKey ); // Used for testing. if( isdigit( key ) || key == ' ' || key == '.' ) { pc.printf( "%c" , key ); } if( key == '#' ) { pc.printf( "\n\r" ); } break; } case HOLD: if( key == '#' ) // Toggle between keymaps. { if( alpha == true ) // We are currently using a keymap with letters { alpha = false; // Now we want a keymap with numbers. led1 = 0; } else // We are currently using a keymap with numbers { alpha = true; // Now we want a keymap with letters. } } else // Some key other than '#' was pressed. { buildStr[ buildCount ++ ] = ( isalpha( key ) ) ? virtKey : key; buildStr[ buildCount ] = '\0'; pc.printf( "\n\r" ); pc.printf( buildStr ); } break; case RELEASED: if( buildCount >= sizeof( buildStr ) ) // Our string is full. Start fresh. { buildCount = 0; } break; } } void keypadEvent_ltr( KeypadEvent key ) { // in here when in alpha mode. kpadState = ltrpad.getState( ); swOnState( key ); } void keypadEvent_num( KeypadEvent key ) { // in here when using number keypad kpadState = numpad.getState( ); swOnState( key ); } int main() { // Starts the timer t.start( ); led1 = 0; // Turns the LED off. ltrpad.begin( makeKeymap( alphaKeys ) ); numpad.begin( makeKeymap( numberKeys ) ); ltrpad.addEventListener( keypadEvent_ltr ); // Add an event listener. ltrpad.setHoldTime( 500 ); // Default is 1000mS numpad.addEventListener( keypadEvent_num ); // Add an event listener. numpad.setHoldTime( 500 ); // Default is 1000mS while(1) { if( alpha ) { key = ltrpad.getKey( ); } else { key = numpad.getKey( ); } if( alpha && t.read_ms( ) - startTime > 100 ) { // Flash the LED if we are using the letter keymap. led1 = !led1; startTime = t.read_ms( ); } } }