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.

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?

UserRevisionLine numberNew 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