Hotboards MX / Mbed 2 deprecated Hotboards_DynamicKeypad

Dependencies:   Hotboards_keypad mbed

Fork of DynamicKeypad by Roman Valencia

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /* @file   Hotboards_keypad.cpp
00002 || @version 1.2
00003 || @author Mark Stanley
00004 || @contact mstanley@technologist.com
00005 ||
00006 ||  07/11/12 - Re-modified (from DynamicKeypadJoe2) to use direct-connect kpds
00007 ||  02/28/12 - Modified to use I2C i/o G. D. (Joe) Young
00008 ||
00009 ||
00010 || @dificulty:  Intermediate
00011 ||
00012 || @description
00013 || |    This is a demonstration of keypadEvents. It's used to switch between keymaps
00014 || |    while using only one keypad.  The main concepts being demonstrated are:
00015 || |
00016 || |        Using the keypad events, PRESSED, HOLD and RELEASED to simplify coding.
00017 || |        How to use setHoldTime() and why.
00018 || |        Making more than one thing happen with the same key.
00019 || |        Assigning and changing keymaps on the fly.
00020 || |
00021 || |    Another useful feature is also included with this demonstration although
00022 || |    it's not really one of the concepts that I wanted to show you.  If you look
00023 || |    at the code in the PRESSED event you will see that the first section of that
00024 || |    code is used to scroll through three different letters on each key.  For
00025 || |    example, pressing the '2' key will step through the letters 'd', 'e' and 'f'.
00026 || |
00027 || |
00028 || |  Using the keypad events, PRESSED, HOLD and RELEASED to simplify coding
00029 || |    Very simply, the PRESSED event occurs imediately upon detecting a pressed
00030 || |    key and will not happen again until after a RELEASED event.  When the HOLD
00031 || |    event fires it always falls between PRESSED and RELEASED.  However, it will
00032 || |    only occur if a key has been pressed for longer than the setHoldTime() interval.
00033 || |
00034 || |  How to use setHoldTime() and why
00035 || |    Take a look at keypad.setHoldTime(500) in the code.  It is used to set the
00036 || |    time delay between a PRESSED event and the start of a HOLD event.  The value
00037 || |    500 is in milliseconds (mS) and is equivalent to half a second.  After pressing
00038 || |    a key for 500mS the HOLD event will fire and any code contained therein will be
00039 || |    executed.  This event will stay active for as long as you hold the key except
00040 || |    in the case of bug #1 listed above.
00041 || |
00042 || |  Making more than one thing happen with the same key.
00043 || |    If you look under the PRESSED event (case PRESSED:) you will see that the '#'
00044 || |    is used to print a new line, Serial.println().  But take a look at the first
00045 || |    half of the HOLD event and you will see the same key being used to switch back
00046 || |    and forth between the letter and number keymaps that were created with alphaKeys[4][5]
00047 || |    and numberKeys[4][5] respectively.
00048 || |
00049 || |  Assigning and changing keymaps on the fly
00050 || |    You will see that the '#' key has been designated to perform two different functions
00051 || |    depending on how long you hold it down.  If you press the '#' key for less than the
00052 || |    setHoldTime() then it will print a new line.  However, if you hold if for longer
00053 || |    than that it will switch back and forth between numbers and letters.  You can see the
00054 || |    keymap changes in the HOLD event.
00055 || |
00056 || |
00057 || |  In addition...
00058 || |      You might notice a couple of things that you won't find in the Arduino language
00059 || |    reference.  The first would be #include <ctype.h>.  This is a standard library from
00060 || |    the C programming language and though I don't normally demonstrate these types of
00061 || |    things from outside the Arduino language reference I felt that its use here was
00062 || |    justified by the simplicity that it brings to this sketch.
00063 || |      That simplicity is provided by the two calls to isalpha(key) and isdigit(key).
00064 || |    The first one is used to decide if the key that was pressed is any letter from a-z
00065 || |    or A-Z and the second one decides if the key is any number from 0-9.  The return
00066 || |    value from these two functions is either a zero or some positive number greater
00067 || |    than zero.  This makes it very simple to test a key and see if it is a number or
00068 || |    a letter.  So when you see the following:
00069 || |
00070 || |    if (isalpha(key))    // this tests to see if your key was a letter
00071 || |
00072 || |    And the following may be more familiar to some but it is equivalent:
00073 || |
00074 || |    if (isalpha(key) != 0)   // this tests to see if your key was a letter
00075 || |
00076 || |  And Finally...
00077 || |    To better understand how the event handler affects your code you will need to remember
00078 || |    that it gets called only when you press, hold or release a key.  However, once a key
00079 || |    is pressed or held then the event handler gets called at the full speed of the loop().
00080 */
00081 #include "mbed.h"
00082 #include "Hotboards_keypad.h"
00083 #include <ctype.h>
00084 
00085 // Define the keymaps.  The blank spot (lower left) is the space character.
00086 char alphaKeys[ 4 ][ 4 ] =
00087 {
00088     { 'a' , 'd' , 'g' },
00089     { 'j' , 'm' , 'p' },
00090     { 's' , 'v' , 'y' },
00091     { ' ' , '.' , '#' }
00092 };
00093 
00094 char numberKeys[ 4 ][ 4 ] =
00095 {
00096     { '1' , '2' , '3' },
00097     { '4' , '5' , '6' },
00098     { '7' , '8' , '9' },
00099     { ' ' , '0' , '#' }
00100 };
00101 
00102 bool alpha = false;   // Start with the numeric keypad.
00103 
00104 // Defines the pins connected to the rows
00105 DigitalInOut rowPins[ 4 ] = { PA_6 , PA_7 , PB_6 , PC_7 };
00106 // Defines the pins connected to the cols
00107 DigitalInOut colPins[ 4 ] = { PA_8 , PB_10 , PB_4 , PB_5 };
00108 
00109 // Create two new keypads, one is a number pad and the other is a letter pad.
00110 Keypad numpad( makeKeymap( numberKeys ) , rowPins , colPins , 4 , 4 );
00111 Keypad ltrpad( makeKeymap( alphaKeys ) , rowPins , colPins , 4 , 4 ); 
00112 
00113 int startTime;
00114 // For this example we will use the Nucleo LED1 on pin PA_5
00115 DigitalOut led1( LED1 );
00116 
00117 // Configures the serial port
00118 Serial pc( USBTX , USBRX );
00119 
00120 // Configures a timer
00121 Timer t;
00122 
00123 char key;
00124 static char virtKey = NO_KEY;   // Stores the last virtual key press. (Alpha keys only)
00125 static char physKey = NO_KEY;   // Stores the last physical key press. (Alpha keys only)
00126 static char buildStr[ 12 ];
00127 static uint8_t buildCount;
00128 static uint8_t pressCount;
00129 static uint8_t kpadState;
00130 
00131 // Take care of some special events.
00132 
00133 void swOnState( char key )
00134 {
00135     switch( kpadState )
00136     {
00137         case PRESSED:
00138             if( isalpha( key ) )        // This is a letter key so we're using the letter keymap.
00139             {
00140                 if( physKey != key )    // New key so start with the first of 3 characters.
00141                 {
00142                     pressCount = 0;
00143                     virtKey = key;
00144                     physKey = key;
00145                 }
00146                 else                    // Pressed the same key again...
00147                 {
00148                     virtKey ++;         // so select the next character on that key.
00149                     pressCount ++;      // Tracks how many times we press the same key.
00150                 }
00151                 if( pressCount > 2 )    // Last character reached so cycle back to start.
00152                 {
00153                     pressCount = 0;
00154                     virtKey = key;
00155                 }
00156                 pc.printf( "%c" , virtKey );    // Used for testing.
00157                 if( isdigit( key ) || key == ' ' || key == '.' )
00158                 {
00159                     pc.printf( "%c" , key );
00160                 }
00161                 if( key == '#' )
00162                 {
00163                     pc.printf( "\n\r" );
00164                 }
00165                 break;
00166             }
00167         case HOLD:
00168             if( key == '#' )            // Toggle between keymaps.
00169             {
00170                 if( alpha == true )     // We are currently using a keymap with letters
00171                 {
00172                     alpha = false;      // Now we want a keymap with numbers.
00173                     led1 = 0;
00174                 }
00175                 else                    // We are currently using a keymap with numbers
00176                 {
00177                     alpha = true;       // Now we want a keymap with letters.
00178                 }
00179             }
00180             else                        // Some key other than '#' was pressed.
00181             {
00182                 buildStr[ buildCount ++ ] = ( isalpha( key ) ) ? virtKey : key;
00183                 buildStr[ buildCount ] = '\0';
00184                 pc.printf( "\n\r" );
00185                 pc.printf( buildStr );
00186             }
00187             break;
00188         case RELEASED:
00189             if( buildCount >= sizeof( buildStr ) )  // Our string is full. Start fresh.
00190             {
00191                 buildCount = 0;
00192             }
00193             break;
00194     }
00195 }
00196 
00197 void keypadEvent_ltr( KeypadEvent key )
00198 {
00199     // in here when in alpha mode.
00200     kpadState = ltrpad.getState( );
00201     swOnState( key );
00202 }
00203 
00204 void keypadEvent_num( KeypadEvent key )
00205 {
00206     // in here when using number keypad
00207     kpadState = numpad.getState( );
00208     swOnState( key );
00209 }
00210 
00211 int main()
00212 {
00213     // Starts the timer
00214     t.start( );
00215     led1 = 0;   // Turns the LED off.
00216     ltrpad.begin( makeKeymap( alphaKeys ) );
00217     numpad.begin( makeKeymap( numberKeys ) );
00218     ltrpad.addEventListener( keypadEvent_ltr ); // Add an event listener.
00219     ltrpad.setHoldTime( 500 );                  // Default is 1000mS
00220     numpad.addEventListener( keypadEvent_num ); // Add an event listener.
00221     numpad.setHoldTime( 500 );                  // Default is 1000mS
00222     
00223     while(1)
00224     {
00225         if( alpha )
00226         {
00227             key = ltrpad.getKey( );
00228         }
00229         else
00230         {
00231             key = numpad.getKey( );
00232         }
00233         if( alpha && t.read_ms( ) - startTime > 100 )
00234         {
00235             // Flash the LED if we are using the letter keymap.
00236             led1 = !led1;
00237             startTime = t.read_ms( );
00238         }
00239     }
00240 }
00241