Fredric Rice / Mbed 2 deprecated DemoKeypadMoorseCodeUnlockTouchAndButton

Dependencies:   LCD_DISCO_F429ZI mbed TS_DISCO_F429ZI mbed-os BSP_DISCO_F429ZI

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SecurityUnlockDemo-Keypad.cpp Source File

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