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: LCD_DISCO_F429ZI mbed TS_DISCO_F429ZI mbed-os BSP_DISCO_F429ZI
SecurityUnlockDemo-Keypad.cpp
00001 00002 // ---------------------------------------------------------------------- 00003 // SecurityUnlockDemo-Keypad.cpp 00004 // 00005 // Fredric L. Rice, June 2019 00006 // 00007 // This module maintains the code which performs the keypad functionality 00008 // 00009 // ---------------------------------------------------------------------- 00010 00011 #include "mbed.h" // The mbed operating system 00012 #include "LCD_DISCO_F429ZI.h" // For controlling the LCD 00013 #include "TS_DISCO_F429ZI.h" // For controlling the touch screen 00014 #include "SecurityUnlockDemo-Main.h" // Bring in the main module 00015 #include "SecurityUnlockDemo-Keypad.h" // Always include our own header 00016 #include "PizzaBMPHeader.h" // For the Pizza BMP file 00017 00018 // ---------------------------------------------------------------------- 00019 // Describe data which is defined externally that we may access 00020 // 00021 // ---------------------------------------------------------------------- 00022 00023 // We may be accessing the LCD 00024 extern LCD_DISCO_F429ZI st_lcd; 00025 00026 // We may be accessing the touch screen 00027 extern TS_DISCO_F429ZI st_touchScreen; 00028 00029 // ---------------------------------------------------------------------- 00030 // Define local data storage 00031 // 00032 // ---------------------------------------------------------------------- 00033 00034 // In this demonstration we define two access levels, access level 1 00035 // grants full access to all functionality whereas access level 2 is 00036 // for accessing less functionality 00037 static const uint8_t * ACCESS_LEVEL_1 = "3141"; 00038 static const uint8_t * ACCESS_LEVEL_2 = "2040"; 00039 00040 // When we build the keypad screen, we use the data in this table 00041 // to position the touch keys rather than use math to determine 00042 // their locations. The reason why we do this is so that we can 00043 // use this table to determine which key was pressed on the touch 00044 // screen, but also we may want to place some keys offset from 00045 // others. A table gives us greater control over key location. 00046 // We place 10 pixels between each keypad. 00047 static KeypadLocation_t st_KeypadInformation[] = 00048 { 00049 // X, Y, H, W, Character 00050 { KEYPAD_LEFT_MARGIN + 0, KEYPAD_TOP_MARGIN + 0, 40, 40, '1' }, 00051 { KEYPAD_LEFT_MARGIN + 60, KEYPAD_TOP_MARGIN + 0, 40, 40, '2' }, 00052 { KEYPAD_LEFT_MARGIN + 120, KEYPAD_TOP_MARGIN + 0, 40, 40, '3' }, 00053 { KEYPAD_LEFT_MARGIN + 0, KEYPAD_TOP_MARGIN + 60, 40, 40, '4' }, 00054 { KEYPAD_LEFT_MARGIN + 60, KEYPAD_TOP_MARGIN + 60, 40, 40, '5' }, 00055 { KEYPAD_LEFT_MARGIN + 120, KEYPAD_TOP_MARGIN + 60, 40, 40, '6' }, 00056 { KEYPAD_LEFT_MARGIN + 0, KEYPAD_TOP_MARGIN + 120, 40, 40, '7' }, 00057 { KEYPAD_LEFT_MARGIN + 60, KEYPAD_TOP_MARGIN + 120, 40, 40, '8' }, 00058 { KEYPAD_LEFT_MARGIN + 120, KEYPAD_TOP_MARGIN + 120, 40, 40, '9' }, 00059 { KEYPAD_LEFT_MARGIN + 0, KEYPAD_TOP_MARGIN + 180, 40, 40, 'C' }, 00060 { KEYPAD_LEFT_MARGIN + 60, KEYPAD_TOP_MARGIN + 180, 40, 40, '0' }, 00061 { KEYPAD_LEFT_MARGIN + 120, KEYPAD_TOP_MARGIN + 180, 40, 40, 'E' }, 00062 { 0, 0, 0, 0, '+' } // End of table 00063 } ; 00064 00065 // We allow a maximum number of keys to be entered for the access code 00066 static uint8_t au8_enteredKeys[MAX_SECURITY_DIGITS + 1]; 00067 00068 // We keep track of the number of digits entered for the access code 00069 static uint8_t u8_enteredKeyCount; 00070 00071 // ---------------------------------------------------------------------- 00072 // KeypadInit() 00073 // 00074 // Initializes this module's locally-held data 00075 // 00076 // ---------------------------------------------------------------------- 00077 void KeypadInit(void) 00078 { 00079 // Initialize locall-held data in this module 00080 u8_enteredKeyCount = 0; 00081 } 00082 00083 // ---------------------------------------------------------------------- 00084 // KeypadDisplayEnteredKeys() 00085 // 00086 // This function will display the entered keys, if any, on the display 00087 // on the line defined for the entered keys. It will center the 00088 // characters. 00089 // 00090 // ---------------------------------------------------------------------- 00091 static void KeypadDisplayEnteredKeys(void) 00092 { 00093 // Display the accumulated security code digits 00094 st_lcd.DisplayStringAt(1, LINE(ENTERED_KEYS_LINE), au8_enteredKeys, CENTER_MODE); 00095 } 00096 00097 // ---------------------------------------------------------------------- 00098 // KeypadProcessEntryCode() 00099 // 00100 // This function will: 00101 // o Check the size of Level 1 access to see if it matches the 00102 // number of characters that were entered 00103 // o Check to see if the Level 1 access code matches the digits 00104 // entered 00105 // o Grant Access Level 1 if both the size and the digits match 00106 // 00107 // o Check the size of Level 2 access to see if it matches the 00108 // number of characters that were entered 00109 // o Check to see if the Level 2 access code matches the digits 00110 // entered 00111 // o Grant Access Level 2 if both the size and the digits match 00112 // 00113 // ---------------------------------------------------------------------- 00114 static void KeypadProcessEntryCode(uint8_t u8_originalKeyCount) 00115 { 00116 // See if the access code that was entered is level 1 00117 if (strlen((char *)ACCESS_LEVEL_1) == u8_originalKeyCount) 00118 { 00119 // Do the digits entered match the level 1 access code? 00120 if (! memcmp(ACCESS_LEVEL_1, au8_enteredKeys, u8_originalKeyCount)) 00121 { 00122 // It does so grant access level 1 00123 MainGrantAccess(1); 00124 return; 00125 } 00126 } 00127 00128 // That did not grant access, see if the entered value is level 2 00129 if (strlen((char *)ACCESS_LEVEL_2) == u8_originalKeyCount) 00130 { 00131 // Do the digits entered match the level 2 access code? 00132 if (! memcmp(ACCESS_LEVEL_2, au8_enteredKeys, u8_originalKeyCount)) 00133 { 00134 // It does so grant access level 1 00135 MainGrantAccess(2); 00136 return; 00137 } 00138 } 00139 } 00140 00141 // ---------------------------------------------------------------------- 00142 // KeypadProcessKeypadKey() 00143 // 00144 // This function will: 00145 // o Store the number of characters that have been entered, if any 00146 // 00147 // o Check to see if the character that is passed to the function 00148 // is a 'C' for Clear 00149 // o Clear the line of entered digits, if any 00150 // o Set the acquired character count to zero 00151 // 00152 // o Check ti see if the character entered is an 'E' for Enter 00153 // o Clear the line of any entered digits, if any 00154 // o Set the acquired character count to zero 00155 // o Call a function which evaluates the digits that have been 00156 // entered, if any 00157 // 00158 // o Checks ti see if there is room to store the newly-entered 00159 // digit in the accumulation buffer 00160 // o Stores the character in to the buffer andincrements the 00161 // entered digit counter 00162 // o Ensures that the string of entered digits is NULL terminated 00163 // o Calls a function which displays the entered digits 00164 // 00165 // ---------------------------------------------------------------------- 00166 static void KeypadProcessKeypadKey(uint8_t u8_thisKeyASCIICharacter) 00167 { 00168 uint8_t u8_originalKeyCount = u8_enteredKeyCount; 00169 // Is the key a C for Clear? 00170 00171 if ('C' == u8_thisKeyASCIICharacter) 00172 { 00173 // It is, so clear the display line of accumulated characters 00174 st_lcd.ClearStringLine(ENTERED_KEYS_LINE); 00175 00176 // Discard our accumulated digit count 00177 u8_enteredKeyCount = 0; 00178 } 00179 00180 // Is the character that was pressed en E for Enter? 00181 else if ('E' == u8_thisKeyASCIICharacter) 00182 { 00183 // It is, so before we process the code, clear the entered digits 00184 st_lcd.ClearStringLine(ENTERED_KEYS_LINE); 00185 00186 // Discard our accumulated digit count 00187 u8_enteredKeyCount = 0; 00188 00189 // Process the entry code 00190 KeypadProcessEntryCode(u8_originalKeyCount); 00191 } 00192 00193 // Anything else we assume is a numertic digit 00194 else 00195 { 00196 // Do we have room for more digits? 00197 if (u8_enteredKeyCount < MAX_SECURITY_DIGITS) 00198 { 00199 // Store the entered digit in to the accumulated key buffer 00200 au8_enteredKeys[u8_enteredKeyCount++] = u8_thisKeyASCIICharacter; 00201 00202 // Make sure that the character string is NULL terminated 00203 au8_enteredKeys[u8_enteredKeyCount] = 0x00; 00204 00205 // Update the display with the new key value 00206 KeypadDisplayEnteredKeys(); 00207 } 00208 } 00209 } 00210 00211 // ---------------------------------------------------------------------- 00212 // KeypadFlashThisKey() 00213 // 00214 // The key that was touched and whose index got passed to this function 00215 // is written in YELLOW and then restored to its original displayed 00216 // graphic with one quarter of a second between. 00217 // 00218 // ---------------------------------------------------------------------- 00219 static void KeypadFlashThisKey(uint8_t u8_thisKeyPadItem) 00220 { 00221 // Set everything to YELLOW 00222 st_lcd.SetBackColor(LCD_COLOR_YELLOW); 00223 st_lcd.SetTextColor(LCD_COLOR_YELLOW); 00224 00225 // Draw the rectangle as all yellow 00226 st_lcd.FillRect(st_KeypadInformation[u8_thisKeyPadItem].u16_screenXLocation, 00227 st_KeypadInformation[u8_thisKeyPadItem].u16_screenYLocation, 00228 st_KeypadInformation[u8_thisKeyPadItem].u16_keyHeight, 00229 st_KeypadInformation[u8_thisKeyPadItem].u16_keyWidth); 00230 00231 // Wait for one quarter of a second 00232 wait(0.25); 00233 00234 // Restore the normal colors 00235 st_lcd.SetBackColor(LCD_COLOR_WHITE); 00236 st_lcd.SetTextColor(LCD_COLOR_BLUE); 00237 00238 // Draw the rectangle with its regular color and text 00239 st_lcd.FillRect(st_KeypadInformation[u8_thisKeyPadItem].u16_screenXLocation, 00240 st_KeypadInformation[u8_thisKeyPadItem].u16_screenYLocation, 00241 st_KeypadInformation[u8_thisKeyPadItem].u16_keyHeight, 00242 st_KeypadInformation[u8_thisKeyPadItem].u16_keyWidth); 00243 00244 // Display the character near the lower right corner of the rectangle 00245 st_lcd.DisplayChar( 00246 st_KeypadInformation[u8_thisKeyPadItem].u16_screenXLocation + 00247 (st_KeypadInformation[u8_thisKeyPadItem].u16_keyHeight / 2) + 6, 00248 st_KeypadInformation[u8_thisKeyPadItem].u16_screenYLocation + 00249 (st_KeypadInformation[u8_thisKeyPadItem].u16_keyWidth / 2) + 2, 00250 st_KeypadInformation[u8_thisKeyPadItem].u8_keyASCIICharacter); 00251 } 00252 00253 // ---------------------------------------------------------------------- 00254 // KeypadHandleKeyPress() 00255 // 00256 // When a key is pressed, the X and Y coordinates of the position where 00257 // the LCD was touched gets passed to this function. 00258 // 00259 // The function steps throug each of the keys defined in the keypad 00260 // map, checking an area bounded by the beginning X and Y coordinates 00261 // of the keys, and by that position plus the height and width of 00262 // trhe key. 00263 // 00264 // If the touch screen position that was touched matches the area of 00265 // a known key, a function is called to process the new key. 00266 // 00267 // If a position of the screen was touched that does not match any 00268 // known key position, the function ignores the screen touch. 00269 // 00270 // ---------------------------------------------------------------------- 00271 void KeypadHandleKeyPress(uint16_t u16_screenX, uint16_t u16_screenY) 00272 { 00273 uint16_t u16_keyMinimumX = 0; 00274 uint16_t u16_keyMaximumX = 0; 00275 uint16_t u16_keyMinimumY = 0; 00276 uint16_t u16_keyMaximumY = 0; 00277 uint8_t u8_keyPadItem = 0; 00278 00279 // Step through the keys to check until we reach an entry that's zero 00280 while(0 != st_KeypadInformation[u8_keyPadItem].u16_screenXLocation) 00281 { 00282 // Calculate the boundaries of this key 00283 u16_keyMinimumX = st_KeypadInformation[u8_keyPadItem].u16_screenXLocation; 00284 u16_keyMaximumX = u16_keyMinimumX + st_KeypadInformation[u8_keyPadItem].u16_keyHeight; 00285 u16_keyMinimumY = st_KeypadInformation[u8_keyPadItem].u16_screenYLocation; 00286 u16_keyMaximumY = u16_keyMinimumY + st_KeypadInformation[u8_keyPadItem].u16_keyWidth; 00287 00288 // Is this the key that was pressed? 00289 if (u16_screenX > u16_keyMinimumX && u16_screenX < u16_keyMaximumX) 00290 { 00291 if (u16_screenY > u16_keyMinimumY && u16_screenY < u16_keyMaximumY) 00292 { 00293 // Flash the key that was pressed 00294 KeypadFlashThisKey(u8_keyPadItem); 00295 00296 // Process the key that was pressed 00297 KeypadProcessKeypadKey(st_KeypadInformation[u8_keyPadItem].u8_keyASCIICharacter); 00298 00299 // We are finished searching 00300 break; 00301 } 00302 } 00303 00304 // Check the next possible key area 00305 u8_keyPadItem++; 00306 } 00307 } 00308 00309 // ---------------------------------------------------------------------- 00310 // KeypadDrawKeypad() 00311 // 00312 // This function will set the LCD background to WHITE and set the 00313 // default text color to BLUE, thehn it will display information about 00314 // what theoperator should do, then the keypad is constructed on the 00315 // display using the information in the keypad map. 00316 // 00317 // ---------------------------------------------------------------------- 00318 void KeypadDrawKeypad(void) 00319 { 00320 uint8_t u8_keyPadItem = 0; 00321 00322 // For the keypad, we want the entire screen to be this color 00323 st_lcd.SetBackColor(LCD_COLOR_WHITE); 00324 00325 // For the keypad's general text we want characters to be this color 00326 st_lcd.SetTextColor(LCD_COLOR_BLUE); 00327 00328 // Display pizza 00329 st_lcd.DrawBitmap(1, 60, st_PizzaBMP); 00330 00331 // Build the ketypad display 00332 st_lcd.DisplayStringAt(1, LINE(0), (uint8_t *)"Enter access code or", CENTER_MODE); 00333 st_lcd.DisplayStringAt(1, LINE(1), (uint8_t *)"use the Moorse Code", CENTER_MODE); 00334 st_lcd.DisplayStringAt(1, LINE(2), (uint8_t *)"push button to unlock", CENTER_MODE); 00335 00336 // Step through the keys to plot until we reach an entry that's zero 00337 while(0 != st_KeypadInformation[u8_keyPadItem].u16_screenXLocation) 00338 { 00339 // Draw the rectangle 00340 st_lcd.FillRect(st_KeypadInformation[u8_keyPadItem].u16_screenXLocation, 00341 st_KeypadInformation[u8_keyPadItem].u16_screenYLocation, 00342 st_KeypadInformation[u8_keyPadItem].u16_keyHeight, 00343 st_KeypadInformation[u8_keyPadItem].u16_keyWidth); 00344 00345 // Display the character near the lower right corner of the rectangle 00346 st_lcd.DisplayChar( 00347 st_KeypadInformation[u8_keyPadItem].u16_screenXLocation + 00348 (st_KeypadInformation[u8_keyPadItem].u16_keyHeight / 2) + 6, 00349 st_KeypadInformation[u8_keyPadItem].u16_screenYLocation + 00350 (st_KeypadInformation[u8_keyPadItem].u16_keyWidth / 2) + 2, 00351 st_KeypadInformation[u8_keyPadItem].u8_keyASCIICharacter); 00352 00353 // Go to the next keypad to create 00354 u8_keyPadItem++; 00355 } 00356 } 00357 00358 // End of file 00359
Generated on Fri Jul 15 2022 16:50:53 by
1.7.2