Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: Hotboards_keypad mbed
Fork of DynamicKeypad by
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
Generated on Sat Jul 23 2022 16:56:06 by
1.7.2
