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-Moorse.cpp Source File

SecurityUnlockDemo-Moorse.cpp

00001 
00002 // ----------------------------------------------------------------------
00003 // SecurityUnlockDemo-Moorse.cpp
00004 //
00005 // Fredric L. Rice, June 2019
00006 //
00007 // This module contains the code which performs the Moorse Code
00008 // functionality. The push button is used to enter pulses in to the
00009 // unlocking mechanism, and the LEDs are used to indicate when the
00010 // pushbutton is down, and when a "dash" has been entered so that
00011 // the user knows the dash was long enough to register as a dash.
00012 //
00013 // Once the operator stops entering dashes and dots, afterabout 3
00014 // seconds the software will evaluate the entry to see if it matches
00015 // the expected / desired characters and if they do, access is granted.
00016 //
00017 // ----------------------------------------------------------------------
00018 
00019 #include "mbed.h"                       // The mbed operating system
00020 #include "LCD_DISCO_F429ZI.h"           // For controlling the LCD
00021 #include "TS_DISCO_F429ZI.h"            // For controlling the touch screen
00022 #include "SecurityUnlockDemo-Main.h"    // Bring in the main module
00023 #include "SecurityUnlockDemo-Moorse.h"  // Always include our own header
00024 
00025 // ----------------------------------------------------------------------
00026 // Describe data which is defined externally that we may access
00027 //
00028 // ----------------------------------------------------------------------
00029 
00030     // We may be accessing the LCD
00031     extern LCD_DISCO_F429ZI st_lcd;
00032 
00033     // We may be accessing the touch screen
00034     extern TS_DISCO_F429ZI st_touchScreen;
00035 
00036 // ----------------------------------------------------------------------
00037 // Define local data storage
00038 //
00039 // ----------------------------------------------------------------------
00040 
00041     // When the push button is used, we drive the lEDs
00042     static DigitalOut st_moorseLED(LED1);
00043     static DigitalOut st_moorseDash(LED2);
00044 
00045     // For the Moorse Code access, we describe the dots and dashes which
00046     // describe the letters C and Q. We do not care about testing for a
00047     // period of quiet beteen characters, we ignore silence, we only
00048     // test the length of when the key is held down
00049     static const uint8_t * ACCESS_MOORSE  = "-.-.--.-";
00050 
00051     // Instantiate a digitial input mapped as our push button
00052     static DigitalIn st_pushButton(PA_0);
00053 
00054     // To drive the Moorse Code access, we maintain counters which keep
00055     // trash of how long the push button has been detected to be held
00056     // down. Since the button is checked 10 times a second, the count
00057     // indicates about how many milliseconds the button was held down.
00058     // If it wraps, we don't care since that means the operator is holding
00059     // the button down for a very long time
00060     static uint16_t u16_buttonDownCount;
00061     
00062     // To determine whether the operator is finished with entering a
00063     // Moorse Code access code, we maintain a counter of "up" time, 
00064     // a.k.a. quiet time.
00065     static uint16_t u16_buttonUpCount;
00066     
00067     // When Moorse Code pulses are entered, we store the down time for
00068     // else pulse in this array
00069     static uint16_t au16_moorseCharacters[MAX_MOORSE_PULSES];
00070     
00071     // As Moorse Code pulses are entered with the push button, we keep
00072     // track of how many down presses there have been
00073     static uint8_t u8_moorsePulseCount;
00074 
00075 // ----------------------------------------------------------------------
00076 // MoorseInit()
00077 //
00078 // This function initializes the locally-held data. It also sets the
00079 // push button to have no pull-up or pull-down resister
00080 //
00081 // ----------------------------------------------------------------------
00082 void MoorseInit(void)
00083 {
00084     // Initialize locall-held data in this module
00085     u16_buttonDownCount   = 0;
00086     u16_buttonUpCount     = 0;
00087     u8_moorsePulseCount   = 0;
00088 
00089     // Set the push button to not have an internal pull-up or down
00090     st_pushButton.mode(PullNone);
00091     
00092     // Ensure that both of the LEDs are turned OFF
00093     st_moorseLED = st_moorseDash = 0;
00094 }
00095 
00096 // ----------------------------------------------------------------------
00097 // MoorseProcessButtonDownThenRelease()
00098 //
00099 // After the push button has been used to send a down pulse, this
00100 // function is called to store the down time, if there is room to
00101 // store it.
00102 //
00103 // ----------------------------------------------------------------------
00104 static void MoorseProcessButtonDownThenRelease(void)
00105 {
00106     // Make sure that we have a valid button down timer
00107     if (u16_buttonDownCount > 0)
00108     {
00109         // Is there room to store another pulse period?
00110         if (u8_moorsePulseCount < MAX_MOORSE_PULSES)
00111         {
00112             // There is, so store the down counter timer
00113             au16_moorseCharacters[u8_moorsePulseCount++] = u16_buttonDownCount;
00114         }
00115     }
00116 }
00117 
00118 // ----------------------------------------------------------------------
00119 // MoorseProcessMoorseDigits()
00120 //
00121 // After the push button has been used to send Moore pulses, and after
00122 // the button has not been pressed for 3 seconds, this function gets 
00123 // called to process the pulses.
00124 //
00125 // We consider a value of 5 or higher to be 500 milliseconds down, or
00126 // a "dash." Any down pulse shorter than that is considere to be a "dot."
00127 //
00128 // ----------------------------------------------------------------------
00129 static void MoorseProcessMoorseDigits(void)
00130 {
00131     uint8_t u8_testLoop          = 0;
00132     uint8_t au8_reportString[21] = { 0 };
00133     uint8_t au8_moorseString[21] = { 0 };
00134     
00135     // Since we have pulses, clear the display to get ready for a report
00136     st_lcd.Clear(LCD_COLOR_WHITE);
00137 
00138     for (u8_testLoop = 0; u8_testLoop < u8_moorsePulseCount; u8_testLoop++)
00139     {
00140         // Build a report of the times that we measured
00141         (void)sprintf((char *)au8_reportString, "Time: %u", 
00142             au16_moorseCharacters[u8_testLoop]);
00143         
00144         // Was the time down greater than 500 milliseconds?
00145         if (au16_moorseCharacters[u8_testLoop] > 5)
00146         {
00147             // It was, so we consider that to be a dash
00148             au8_moorseString[u8_testLoop] = '-';
00149         }
00150         else
00151         {
00152             // It was not so we consider that to be a dot
00153             au8_moorseString[u8_testLoop] = '.';
00154         }
00155         
00156         // Display the times that we measured
00157         st_lcd.DisplayStringAt(1, LINE(u8_testLoop + 1), au8_reportString, LEFT_MODE);
00158     }
00159     
00160     // Make sure that the string of Moorse Code pulses is NULL terminated
00161     au8_moorseString[u8_testLoop] = 0x00;
00162     
00163     // Build a report showing what the Moorse Code looks like    
00164     (void)sprintf((char *)au8_reportString, "Moorse code: %s", au8_moorseString);
00165     
00166     // Display what the Moorse Code looked like
00167     st_lcd.DisplayStringAt(1, LINE(u8_testLoop + 1), au8_moorseString, LEFT_MODE);
00168 
00169     // Is that enough pulses to satisfy all required Moorse pulses?
00170     if (u8_moorsePulseCount == strlen((char *)ACCESS_MOORSE))
00171     {
00172         // It was, are the pulses what we expect for Level 1 access?
00173         if (! memcmp(au8_moorseString, ACCESS_MOORSE, u8_moorsePulseCount))
00174         {
00175             st_lcd.DisplayStringAt(1, LINE(u8_testLoop + 2), 
00176                 (uint8_t *)"Access granted", LEFT_MODE);
00177             
00178             // Leave everything up on the screen for 5 seconds
00179             wait(5.0);
00180             
00181             // Grant access level 1
00182             MainGrantAccess(1);            
00183         }
00184     }
00185 }
00186 
00187 // ----------------------------------------------------------------------
00188 // MoorseScanPushButton()
00189 //
00190 // This function will check to see what the state of the push button
00191 // is, and it will drive the Moorse Code entry access functionality.
00192 //
00193 // A push button held down for 500 milliseconds or longer is considered
00194 // to be a "dash." And down time shorter than that is considered to be
00195 // a "dot." After 3 seconds of quiet time after a down time has been
00196 // detected, we consider the operator to have finished pulsing in all
00197 // Moorse Code pulses.
00198 //
00199 // ----------------------------------------------------------------------
00200 void MoorseScanPushButton(void)
00201 {
00202     // Acquire / poll the state of the push button
00203     int i_buttonState = st_moorseLED = st_pushButton.read();
00204     
00205     // Is the button not being pressed?
00206     if (0 == i_buttonState)
00207     {
00208         // The button is not down, was the button down before?
00209         if (u16_buttonDownCount > 0)
00210         {
00211             // The push button was down and now it has been released.           
00212             // Process the button down time
00213             MoorseProcessButtonDownThenRelease();
00214         }     
00215    
00216         // Add another count to the time that the button has been up
00217         u16_buttonUpCount++;
00218         
00219         // Since the button is not being pressed, make sure that
00220         // the Dash LED is turned OFF
00221         st_moorseDash = 0;
00222         
00223         // Has the button been up for at least 3 seconds? Since
00224         // we are called 10 times a second, we check for 3 counts.
00225         // We only check if there has been at least 1 down pulse.
00226         if (u8_moorsePulseCount > 0 && u16_buttonUpCount >= 30)
00227         {
00228             // The operator appears to be finished with entering 
00229             // the Moorse digits so process what may have come in
00230             MoorseProcessMoorseDigits();
00231                 
00232             // Discard all Moorse down pulses we may have accumulated
00233             u8_moorsePulseCount = 0;
00234         }
00235             
00236         // Discard the button down counter
00237         u16_buttonDownCount = 0;
00238      }
00239     else
00240     {
00241         // The button is down so count how long it is down
00242         u16_buttonDownCount++;
00243         
00244         // Discard any button on time
00245         u16_buttonUpCount = 0;
00246         
00247         // Is the button being held down long enough to indicate a dash?
00248         if (u16_buttonDownCount >= 5)
00249         {
00250             // It is, so indicate the fact by illuminating the Dash LED
00251             st_moorseDash = 1;
00252         }
00253     }
00254 }
00255 
00256 // End of file
00257