This is a demonstration program which draws a keypad on the LCD and uses the touch screen to allow an operator to key-in an access code. Two possible codes are allowed to grant to different levels of access. Additionally the push button is used to allow an operator to send Moorse Code pulses in to the device which is checked against two characters to determine if there was a match, and if so, access is granted.
Dependencies: LCD_DISCO_F429ZI mbed TS_DISCO_F429ZI mbed-os BSP_DISCO_F429ZI
Also draws a mushroom on the screen and animates it.
SecurityUnlockDemo-Moorse.cpp@2:444eeedb41f0, 2019-06-01 (annotated)
- Committer:
- Damotclese
- Date:
- Sat Jun 01 21:04:17 2019 +0000
- Revision:
- 2:444eeedb41f0
- Parent:
- 1:316582aec4fb
Added some analog inputs in an effort to assist the random number generator.;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Damotclese | 1:316582aec4fb | 1 | |
Damotclese | 1:316582aec4fb | 2 | // ---------------------------------------------------------------------- |
Damotclese | 1:316582aec4fb | 3 | // SecurityUnlockDemo-Moorse.cpp |
Damotclese | 1:316582aec4fb | 4 | // |
Damotclese | 1:316582aec4fb | 5 | // Fredric L. Rice, June 2019 |
Damotclese | 1:316582aec4fb | 6 | // |
Damotclese | 1:316582aec4fb | 7 | // This module contains the code which performs the Moorse Code |
Damotclese | 2:444eeedb41f0 | 8 | // functionality. The push button is used to enter pulses in to the |
Damotclese | 2:444eeedb41f0 | 9 | // unlocking mechanism, and the LEDs are used to indicate when the |
Damotclese | 2:444eeedb41f0 | 10 | // pushbutton is down, and when a "dash" has been entered so that |
Damotclese | 2:444eeedb41f0 | 11 | // the user knows the dash was long enough to register as a dash. |
Damotclese | 2:444eeedb41f0 | 12 | // |
Damotclese | 2:444eeedb41f0 | 13 | // Once the operator stops entering dashes and dots, afterabout 3 |
Damotclese | 2:444eeedb41f0 | 14 | // seconds the software will evaluate the entry to see if it matches |
Damotclese | 2:444eeedb41f0 | 15 | // the expected / desired characters and if they do, access is granted. |
Damotclese | 1:316582aec4fb | 16 | // |
Damotclese | 1:316582aec4fb | 17 | // ---------------------------------------------------------------------- |
Damotclese | 1:316582aec4fb | 18 | |
Damotclese | 1:316582aec4fb | 19 | #include "mbed.h" // The mbed operating system |
Damotclese | 1:316582aec4fb | 20 | #include "LCD_DISCO_F429ZI.h" // For controlling the LCD |
Damotclese | 1:316582aec4fb | 21 | #include "TS_DISCO_F429ZI.h" // For controlling the touch screen |
Damotclese | 1:316582aec4fb | 22 | #include "SecurityUnlockDemo-Main.h" // Bring in the main module |
Damotclese | 1:316582aec4fb | 23 | #include "SecurityUnlockDemo-Moorse.h" // Always include our own header |
Damotclese | 1:316582aec4fb | 24 | |
Damotclese | 1:316582aec4fb | 25 | // ---------------------------------------------------------------------- |
Damotclese | 1:316582aec4fb | 26 | // Describe data which is defined externally that we may access |
Damotclese | 1:316582aec4fb | 27 | // |
Damotclese | 1:316582aec4fb | 28 | // ---------------------------------------------------------------------- |
Damotclese | 1:316582aec4fb | 29 | |
Damotclese | 1:316582aec4fb | 30 | // We may be accessing the LCD |
Damotclese | 1:316582aec4fb | 31 | extern LCD_DISCO_F429ZI st_lcd; |
Damotclese | 1:316582aec4fb | 32 | |
Damotclese | 1:316582aec4fb | 33 | // We may be accessing the touch screen |
Damotclese | 1:316582aec4fb | 34 | extern TS_DISCO_F429ZI st_touchScreen; |
Damotclese | 1:316582aec4fb | 35 | |
Damotclese | 1:316582aec4fb | 36 | // ---------------------------------------------------------------------- |
Damotclese | 1:316582aec4fb | 37 | // Define local data storage |
Damotclese | 1:316582aec4fb | 38 | // |
Damotclese | 1:316582aec4fb | 39 | // ---------------------------------------------------------------------- |
Damotclese | 1:316582aec4fb | 40 | |
Damotclese | 1:316582aec4fb | 41 | // When the push button is used, we drive the lEDs |
Damotclese | 1:316582aec4fb | 42 | static DigitalOut st_moorseLED(LED1); |
Damotclese | 1:316582aec4fb | 43 | static DigitalOut st_moorseDash(LED2); |
Damotclese | 1:316582aec4fb | 44 | |
Damotclese | 1:316582aec4fb | 45 | // For the Moorse Code access, we describe the dots and dashes which |
Damotclese | 1:316582aec4fb | 46 | // describe the letters C and Q. We do not care about testing for a |
Damotclese | 1:316582aec4fb | 47 | // period of quiet beteen characters, we ignore silence, we only |
Damotclese | 1:316582aec4fb | 48 | // test the length of when the key is held down |
Damotclese | 1:316582aec4fb | 49 | static const uint8_t * ACCESS_MOORSE = "-.-.--.-"; |
Damotclese | 1:316582aec4fb | 50 | |
Damotclese | 1:316582aec4fb | 51 | // Instantiate a digitial input mapped as our push button |
Damotclese | 1:316582aec4fb | 52 | static DigitalIn st_pushButton(PA_0); |
Damotclese | 1:316582aec4fb | 53 | |
Damotclese | 1:316582aec4fb | 54 | // To drive the Moorse Code access, we maintain counters which keep |
Damotclese | 1:316582aec4fb | 55 | // trash of how long the push button has been detected to be held |
Damotclese | 1:316582aec4fb | 56 | // down. Since the button is checked 10 times a second, the count |
Damotclese | 1:316582aec4fb | 57 | // indicates about how many milliseconds the button was held down. |
Damotclese | 1:316582aec4fb | 58 | // If it wraps, we don't care since that means the operator is holding |
Damotclese | 1:316582aec4fb | 59 | // the button down for a very long time |
Damotclese | 1:316582aec4fb | 60 | static uint16_t u16_buttonDownCount; |
Damotclese | 1:316582aec4fb | 61 | |
Damotclese | 1:316582aec4fb | 62 | // To determine whether the operator is finished with entering a |
Damotclese | 1:316582aec4fb | 63 | // Moorse Code access code, we maintain a counter of "up" time, |
Damotclese | 1:316582aec4fb | 64 | // a.k.a. quiet time. |
Damotclese | 1:316582aec4fb | 65 | static uint16_t u16_buttonUpCount; |
Damotclese | 1:316582aec4fb | 66 | |
Damotclese | 1:316582aec4fb | 67 | // When Moorse Code pulses are entered, we store the down time for |
Damotclese | 1:316582aec4fb | 68 | // else pulse in this array |
Damotclese | 1:316582aec4fb | 69 | static uint16_t au16_moorseCharacters[MAX_MOORSE_PULSES]; |
Damotclese | 1:316582aec4fb | 70 | |
Damotclese | 1:316582aec4fb | 71 | // As Moorse Code pulses are entered with the push button, we keep |
Damotclese | 1:316582aec4fb | 72 | // track of how many down presses there have been |
Damotclese | 1:316582aec4fb | 73 | static uint8_t u8_moorsePulseCount; |
Damotclese | 1:316582aec4fb | 74 | |
Damotclese | 1:316582aec4fb | 75 | // ---------------------------------------------------------------------- |
Damotclese | 1:316582aec4fb | 76 | // MoorseInit() |
Damotclese | 1:316582aec4fb | 77 | // |
Damotclese | 1:316582aec4fb | 78 | // This function initializes the locally-held data. It also sets the |
Damotclese | 1:316582aec4fb | 79 | // push button to have no pull-up or pull-down resister |
Damotclese | 1:316582aec4fb | 80 | // |
Damotclese | 1:316582aec4fb | 81 | // ---------------------------------------------------------------------- |
Damotclese | 1:316582aec4fb | 82 | void MoorseInit(void) |
Damotclese | 1:316582aec4fb | 83 | { |
Damotclese | 1:316582aec4fb | 84 | // Initialize locall-held data in this module |
Damotclese | 1:316582aec4fb | 85 | u16_buttonDownCount = 0; |
Damotclese | 1:316582aec4fb | 86 | u16_buttonUpCount = 0; |
Damotclese | 1:316582aec4fb | 87 | u8_moorsePulseCount = 0; |
Damotclese | 1:316582aec4fb | 88 | |
Damotclese | 1:316582aec4fb | 89 | // Set the push button to not have an internal pull-up or down |
Damotclese | 1:316582aec4fb | 90 | st_pushButton.mode(PullNone); |
Damotclese | 1:316582aec4fb | 91 | |
Damotclese | 1:316582aec4fb | 92 | // Ensure that both of the LEDs are turned OFF |
Damotclese | 1:316582aec4fb | 93 | st_moorseLED = st_moorseDash = 0; |
Damotclese | 1:316582aec4fb | 94 | } |
Damotclese | 1:316582aec4fb | 95 | |
Damotclese | 1:316582aec4fb | 96 | // ---------------------------------------------------------------------- |
Damotclese | 1:316582aec4fb | 97 | // MoorseProcessButtonDownThenRelease() |
Damotclese | 1:316582aec4fb | 98 | // |
Damotclese | 1:316582aec4fb | 99 | // After the push button has been used to send a down pulse, this |
Damotclese | 1:316582aec4fb | 100 | // function is called to store the down time, if there is room to |
Damotclese | 1:316582aec4fb | 101 | // store it. |
Damotclese | 1:316582aec4fb | 102 | // |
Damotclese | 1:316582aec4fb | 103 | // ---------------------------------------------------------------------- |
Damotclese | 1:316582aec4fb | 104 | static void MoorseProcessButtonDownThenRelease(void) |
Damotclese | 1:316582aec4fb | 105 | { |
Damotclese | 1:316582aec4fb | 106 | // Make sure that we have a valid button down timer |
Damotclese | 1:316582aec4fb | 107 | if (u16_buttonDownCount > 0) |
Damotclese | 1:316582aec4fb | 108 | { |
Damotclese | 1:316582aec4fb | 109 | // Is there room to store another pulse period? |
Damotclese | 1:316582aec4fb | 110 | if (u8_moorsePulseCount < MAX_MOORSE_PULSES) |
Damotclese | 1:316582aec4fb | 111 | { |
Damotclese | 1:316582aec4fb | 112 | // There is, so store the down counter timer |
Damotclese | 1:316582aec4fb | 113 | au16_moorseCharacters[u8_moorsePulseCount++] = u16_buttonDownCount; |
Damotclese | 1:316582aec4fb | 114 | } |
Damotclese | 1:316582aec4fb | 115 | } |
Damotclese | 1:316582aec4fb | 116 | } |
Damotclese | 1:316582aec4fb | 117 | |
Damotclese | 1:316582aec4fb | 118 | // ---------------------------------------------------------------------- |
Damotclese | 1:316582aec4fb | 119 | // MoorseProcessMoorseDigits() |
Damotclese | 1:316582aec4fb | 120 | // |
Damotclese | 1:316582aec4fb | 121 | // After the push button has been used to send Moore pulses, and after |
Damotclese | 1:316582aec4fb | 122 | // the button has not been pressed for 3 seconds, this function gets |
Damotclese | 1:316582aec4fb | 123 | // called to process the pulses. |
Damotclese | 1:316582aec4fb | 124 | // |
Damotclese | 1:316582aec4fb | 125 | // We consider a value of 5 or higher to be 500 milliseconds down, or |
Damotclese | 1:316582aec4fb | 126 | // a "dash." Any down pulse shorter than that is considere to be a "dot." |
Damotclese | 1:316582aec4fb | 127 | // |
Damotclese | 1:316582aec4fb | 128 | // ---------------------------------------------------------------------- |
Damotclese | 1:316582aec4fb | 129 | static void MoorseProcessMoorseDigits(void) |
Damotclese | 1:316582aec4fb | 130 | { |
Damotclese | 1:316582aec4fb | 131 | uint8_t u8_testLoop = 0; |
Damotclese | 1:316582aec4fb | 132 | uint8_t au8_reportString[21] = { 0 }; |
Damotclese | 1:316582aec4fb | 133 | uint8_t au8_moorseString[21] = { 0 }; |
Damotclese | 1:316582aec4fb | 134 | |
Damotclese | 1:316582aec4fb | 135 | // Since we have pulses, clear the display to get ready for a report |
Damotclese | 1:316582aec4fb | 136 | st_lcd.Clear(LCD_COLOR_WHITE); |
Damotclese | 1:316582aec4fb | 137 | |
Damotclese | 1:316582aec4fb | 138 | for (u8_testLoop = 0; u8_testLoop < u8_moorsePulseCount; u8_testLoop++) |
Damotclese | 1:316582aec4fb | 139 | { |
Damotclese | 1:316582aec4fb | 140 | // Build a report of the times that we measured |
Damotclese | 1:316582aec4fb | 141 | (void)sprintf((char *)au8_reportString, "Time: %u", |
Damotclese | 1:316582aec4fb | 142 | au16_moorseCharacters[u8_testLoop]); |
Damotclese | 1:316582aec4fb | 143 | |
Damotclese | 1:316582aec4fb | 144 | // Was the time down greater than 500 milliseconds? |
Damotclese | 1:316582aec4fb | 145 | if (au16_moorseCharacters[u8_testLoop] > 5) |
Damotclese | 1:316582aec4fb | 146 | { |
Damotclese | 1:316582aec4fb | 147 | // It was, so we consider that to be a dash |
Damotclese | 1:316582aec4fb | 148 | au8_moorseString[u8_testLoop] = '-'; |
Damotclese | 1:316582aec4fb | 149 | } |
Damotclese | 1:316582aec4fb | 150 | else |
Damotclese | 1:316582aec4fb | 151 | { |
Damotclese | 1:316582aec4fb | 152 | // It was not so we consider that to be a dot |
Damotclese | 1:316582aec4fb | 153 | au8_moorseString[u8_testLoop] = '.'; |
Damotclese | 1:316582aec4fb | 154 | } |
Damotclese | 1:316582aec4fb | 155 | |
Damotclese | 1:316582aec4fb | 156 | // Display the times that we measured |
Damotclese | 1:316582aec4fb | 157 | st_lcd.DisplayStringAt(1, LINE(u8_testLoop + 1), au8_reportString, LEFT_MODE); |
Damotclese | 1:316582aec4fb | 158 | } |
Damotclese | 1:316582aec4fb | 159 | |
Damotclese | 1:316582aec4fb | 160 | // Make sure that the string of Moorse Code pulses is NULL terminated |
Damotclese | 1:316582aec4fb | 161 | au8_moorseString[u8_testLoop] = 0x00; |
Damotclese | 1:316582aec4fb | 162 | |
Damotclese | 1:316582aec4fb | 163 | // Build a report showing what the Moorse Code looks like |
Damotclese | 1:316582aec4fb | 164 | (void)sprintf((char *)au8_reportString, "Moorse code: %s", au8_moorseString); |
Damotclese | 1:316582aec4fb | 165 | |
Damotclese | 1:316582aec4fb | 166 | // Display what the Moorse Code looked like |
Damotclese | 1:316582aec4fb | 167 | st_lcd.DisplayStringAt(1, LINE(u8_testLoop + 1), au8_moorseString, LEFT_MODE); |
Damotclese | 1:316582aec4fb | 168 | |
Damotclese | 1:316582aec4fb | 169 | // Is that enough pulses to satisfy all required Moorse pulses? |
Damotclese | 1:316582aec4fb | 170 | if (u8_moorsePulseCount == strlen((char *)ACCESS_MOORSE)) |
Damotclese | 1:316582aec4fb | 171 | { |
Damotclese | 1:316582aec4fb | 172 | // It was, are the pulses what we expect for Level 1 access? |
Damotclese | 1:316582aec4fb | 173 | if (! memcmp(au8_moorseString, ACCESS_MOORSE, u8_moorsePulseCount)) |
Damotclese | 1:316582aec4fb | 174 | { |
Damotclese | 1:316582aec4fb | 175 | st_lcd.DisplayStringAt(1, LINE(u8_testLoop + 2), |
Damotclese | 1:316582aec4fb | 176 | (uint8_t *)"Access granted", LEFT_MODE); |
Damotclese | 1:316582aec4fb | 177 | |
Damotclese | 1:316582aec4fb | 178 | // Leave everything up on the screen for 5 seconds |
Damotclese | 1:316582aec4fb | 179 | wait(5.0); |
Damotclese | 1:316582aec4fb | 180 | |
Damotclese | 1:316582aec4fb | 181 | // Grant access level 1 |
Damotclese | 1:316582aec4fb | 182 | MainGrantAccess(1); |
Damotclese | 1:316582aec4fb | 183 | } |
Damotclese | 1:316582aec4fb | 184 | } |
Damotclese | 1:316582aec4fb | 185 | } |
Damotclese | 1:316582aec4fb | 186 | |
Damotclese | 1:316582aec4fb | 187 | // ---------------------------------------------------------------------- |
Damotclese | 1:316582aec4fb | 188 | // MoorseScanPushButton() |
Damotclese | 1:316582aec4fb | 189 | // |
Damotclese | 1:316582aec4fb | 190 | // This function will check to see what the state of the push button |
Damotclese | 1:316582aec4fb | 191 | // is, and it will drive the Moorse Code entry access functionality. |
Damotclese | 1:316582aec4fb | 192 | // |
Damotclese | 1:316582aec4fb | 193 | // A push button held down for 500 milliseconds or longer is considered |
Damotclese | 1:316582aec4fb | 194 | // to be a "dash." And down time shorter than that is considered to be |
Damotclese | 1:316582aec4fb | 195 | // a "dot." After 3 seconds of quiet time after a down time has been |
Damotclese | 1:316582aec4fb | 196 | // detected, we consider the operator to have finished pulsing in all |
Damotclese | 1:316582aec4fb | 197 | // Moorse Code pulses. |
Damotclese | 1:316582aec4fb | 198 | // |
Damotclese | 1:316582aec4fb | 199 | // ---------------------------------------------------------------------- |
Damotclese | 1:316582aec4fb | 200 | void MoorseScanPushButton(void) |
Damotclese | 1:316582aec4fb | 201 | { |
Damotclese | 1:316582aec4fb | 202 | // Acquire / poll the state of the push button |
Damotclese | 1:316582aec4fb | 203 | int i_buttonState = st_moorseLED = st_pushButton.read(); |
Damotclese | 1:316582aec4fb | 204 | |
Damotclese | 1:316582aec4fb | 205 | // Is the button not being pressed? |
Damotclese | 1:316582aec4fb | 206 | if (0 == i_buttonState) |
Damotclese | 1:316582aec4fb | 207 | { |
Damotclese | 1:316582aec4fb | 208 | // The button is not down, was the button down before? |
Damotclese | 1:316582aec4fb | 209 | if (u16_buttonDownCount > 0) |
Damotclese | 1:316582aec4fb | 210 | { |
Damotclese | 1:316582aec4fb | 211 | // The push button was down and now it has been released. |
Damotclese | 1:316582aec4fb | 212 | // Process the button down time |
Damotclese | 1:316582aec4fb | 213 | MoorseProcessButtonDownThenRelease(); |
Damotclese | 1:316582aec4fb | 214 | } |
Damotclese | 1:316582aec4fb | 215 | |
Damotclese | 1:316582aec4fb | 216 | // Add another count to the time that the button has been up |
Damotclese | 1:316582aec4fb | 217 | u16_buttonUpCount++; |
Damotclese | 1:316582aec4fb | 218 | |
Damotclese | 1:316582aec4fb | 219 | // Since the button is not being pressed, make sure that |
Damotclese | 1:316582aec4fb | 220 | // the Dash LED is turned OFF |
Damotclese | 1:316582aec4fb | 221 | st_moorseDash = 0; |
Damotclese | 1:316582aec4fb | 222 | |
Damotclese | 1:316582aec4fb | 223 | // Has the button been up for at least 3 seconds? Since |
Damotclese | 1:316582aec4fb | 224 | // we are called 10 times a second, we check for 3 counts. |
Damotclese | 1:316582aec4fb | 225 | // We only check if there has been at least 1 down pulse. |
Damotclese | 1:316582aec4fb | 226 | if (u8_moorsePulseCount > 0 && u16_buttonUpCount >= 30) |
Damotclese | 1:316582aec4fb | 227 | { |
Damotclese | 1:316582aec4fb | 228 | // The operator appears to be finished with entering |
Damotclese | 1:316582aec4fb | 229 | // the Moorse digits so process what may have come in |
Damotclese | 1:316582aec4fb | 230 | MoorseProcessMoorseDigits(); |
Damotclese | 1:316582aec4fb | 231 | |
Damotclese | 1:316582aec4fb | 232 | // Discard all Moorse down pulses we may have accumulated |
Damotclese | 1:316582aec4fb | 233 | u8_moorsePulseCount = 0; |
Damotclese | 1:316582aec4fb | 234 | } |
Damotclese | 1:316582aec4fb | 235 | |
Damotclese | 1:316582aec4fb | 236 | // Discard the button down counter |
Damotclese | 1:316582aec4fb | 237 | u16_buttonDownCount = 0; |
Damotclese | 1:316582aec4fb | 238 | } |
Damotclese | 1:316582aec4fb | 239 | else |
Damotclese | 1:316582aec4fb | 240 | { |
Damotclese | 1:316582aec4fb | 241 | // The button is down so count how long it is down |
Damotclese | 1:316582aec4fb | 242 | u16_buttonDownCount++; |
Damotclese | 1:316582aec4fb | 243 | |
Damotclese | 1:316582aec4fb | 244 | // Discard any button on time |
Damotclese | 1:316582aec4fb | 245 | u16_buttonUpCount = 0; |
Damotclese | 1:316582aec4fb | 246 | |
Damotclese | 1:316582aec4fb | 247 | // Is the button being held down long enough to indicate a dash? |
Damotclese | 1:316582aec4fb | 248 | if (u16_buttonDownCount >= 5) |
Damotclese | 1:316582aec4fb | 249 | { |
Damotclese | 1:316582aec4fb | 250 | // It is, so indicate the fact by illuminating the Dash LED |
Damotclese | 1:316582aec4fb | 251 | st_moorseDash = 1; |
Damotclese | 1:316582aec4fb | 252 | } |
Damotclese | 1:316582aec4fb | 253 | } |
Damotclese | 1:316582aec4fb | 254 | } |
Damotclese | 1:316582aec4fb | 255 | |
Damotclese | 1:316582aec4fb | 256 | // End of file |
Damotclese | 1:316582aec4fb | 257 |