Advertisement
Mark2020H

Full code for keycoded lock

May 29th, 2021
1,417
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 17.75 KB | None | 0 0
  1. #include <Arduino.h>
  2. #include <EEPROM.h>
  3. #include <LiquidCrystal.h>
  4. #include <Keypad.h>
  5.  
  6.  
  7. #define STRING_TERMINATOR '\0'
  8. #define _LOCK   10
  9.  
  10.  
  11. /*MD Harrington Tuesday 29th May 2018  */
  12.  
  13. // initialize the library by associating any needed LCD interface pin
  14. // with the arduino pin number it is connected to
  15. const int rs = A0, en = A1, d4 = A2, d5 = A3, d6 = A4, d7 = A5;
  16. const int ROWS = 4 ;
  17. const int COLS = 4 ;
  18. const int MAX_INDEX  = 7 ;
  19. const int EEPROM_MIN_ADDR = 0;
  20. const int EEPROM_MAX_ADDR = 511;
  21.  
  22.  
  23.  
  24. char key ;
  25. int State = 0;
  26. int col  = 0 ;
  27. int index = 0 ;
  28. boolean locked = false ;
  29.  
  30.  
  31. char hexaKeys[ROWS][COLS] = {
  32.   {'1', '2', '3', 'A'},
  33.   {'4', '5', '6', 'B'},
  34.   {'7', '8', '9', 'C'},
  35.   {'*', '0', '#', 'D'}
  36. };
  37.  
  38.  
  39. byte rowPins[ROWS] = {9, 8, 7, 6};
  40. byte colPins[COLS] = {5, 4, 3, 2};
  41.  
  42.  
  43. char  defkey[MAX_INDEX]="123456"  ;
  44.  
  45.  
  46. char  _oldkey[MAX_INDEX] ;
  47. char  _newkey[MAX_INDEX] ;
  48.  
  49.                     /* display message strings for lcd */
  50.                     const char *msg0 = " M.D. Harrington" ;
  51.                     const char *msg1 = "Enter*||Retype#" ;
  52.                     const char *msg2 = "Codekey Entered" ;
  53.                     const char *msg3 = "User  Cancelled" ;
  54.                     const char *msg4 = "Please Re Enter" ;
  55.                     const char *msg5 = "key C  for Menu";
  56.                     const char *msg6 = "ArduinoEmbedded" ;
  57.                     const char *msg7 = " Key.Entry.Mode" ;
  58.                     const char *msg8 = " Lock B Unlock D";
  59.                     const char *msg9 = " Validating Key ";
  60.                     const char *msgA = "PassKey Accepted";
  61.                     const char *msgB = "Passkey  Invalid";
  62.                     const char *msgC = "Lock --- Engaged";
  63.                     const char *msgD = "Lock Dis-engaged";
  64.  
  65. LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
  66.  
  67.  
  68.  
  69. Keypad keypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
  70.  
  71.  
  72. void setup() {
  73.  
  74.  
  75.   Serial.begin(9600);
  76.   while (!Serial) {
  77.     ; // wait for serial port to connect. Needed for native USB port only
  78.    
  79.   }
  80.  
  81.   pinMode(_LOCK, OUTPUT) ;  
  82.  
  83.  
  84.   lcd.begin(16, 2);
  85.   lcd.clear();
  86.   showMsg(msg6 ,1,0) ;
  87.   showMsg(msg0,0,1);
  88.  
  89.   Serial.println(defkey);
  90.  
  91.  
  92.  
  93.  
  94. //Serial.print(" Default pass written to EEPROM asserted ") ;
  95. //Serial.println( eeprom_write_bytes(0,defkey,MAX_INDEX));
  96.  
  97.   // read from the EEPROM back into _oldKey
  98.  Serial.print(" Reading back from EEPROM ") ;
  99.  Serial.println(eeprom_read_string(0, _oldkey,MAX_INDEX));
  100.  Serial.println("default pass is now in _newkey  returned ") ;
  101.  
  102.  
  103.  Serial.println(_oldkey);
  104.  
  105.  
  106.  
  107. }
  108.  
  109.  
  110. /****************************************************************************************************************/
  111. // Returns true if the address is between the
  112. // minimum and maximum allowed values, false otherwise.
  113.  
  114. boolean eeprom_is_addr_ok(int addr) {
  115. return ((addr >= EEPROM_MIN_ADDR) && (addr <= EEPROM_MAX_ADDR));
  116. }  
  117.  
  118.  
  119. /***************************************************************************************************************/
  120.      
  121. /* Writes a sequence of bytes to eeprom starting at the specified address.
  122.  
  123.                 Returns true if the whole array is successfully written.
  124.                 Returns false if the start or end addresses aren't between
  125.                 the minimum and maximum allowed values.
  126.                 When returning false, nothing gets written to eeprom. */
  127.  
  128.  
  129.     boolean eeprom_write_bytes(int startAddr, const byte* array, int numBytes) {
  130.     // counter
  131.     int i;
  132.    
  133.     // both first byte and last byte addresses must fall within
  134.     // the allowed range
  135.          
  136.           if (!eeprom_is_addr_ok(startAddr) || !eeprom_is_addr_ok(startAddr + numBytes)) {
  137.           return false;
  138.           }
  139.               for (i = 0; i < numBytes; i++) {
  140.               EEPROM.write(startAddr + i, array[i]);
  141.               }
  142.    
  143.     return true;
  144.     }
  145.  
  146. /***********************************************************************************************************/
  147.  
  148.                      
  149.       boolean eeprom_read_string(int addr, char* buffer, int bufSize) {
  150.       byte ch; // byte read from eeprom
  151.       int bytesRead; // number of bytes read so far
  152.      
  153.      
  154.      
  155.             if (!eeprom_is_addr_ok(addr)) { // check start address
  156.             return false;
  157.             }
  158.      
  159.                 if (bufSize == 0) { // how can we store bytes in an empty buffer ?
  160.                 return false;
  161.      
  162.                
  163.                 }
  164.             // is there is room for the string terminator only, no reason to go further
  165.             if (bufSize == 1) {
  166.             buffer[0] = 0;
  167.             return true;
  168.             }
  169.            
  170.                   bytesRead = 0; // initialize byte counter
  171.                   ch = EEPROM.read(addr + bytesRead); // read next byte from eeprom
  172.                   buffer[bytesRead] = ch; // store it into the user buffer
  173.                   bytesRead++; // increment byte counter
  174.                                      
  175.                                      
  176.                                       /* stop conditions:                                
  177.                                        
  178.                                        the character just read is the string terminator one (0x00)
  179.                                        we have filled the user buffer
  180.                                        we have reached the last eeprom address
  181.                                        
  182.                                        */
  183.                                      
  184.                                        
  185.                                      
  186.                                      
  187.                     while ( (ch != 0x00) && (bytesRead < bufSize) && ((addr + bytesRead) <= EEPROM_MAX_ADDR) ) {
  188.                           // if no stop condition is met, read the next byte from eeprom
  189.                           ch = EEPROM.read(addr + bytesRead);
  190.                           buffer[bytesRead] = ch; // store it into the user buffer
  191.                           bytesRead++; // increment byte counter
  192.                     }
  193.                         // make sure the user buffer has a string terminator, (0x00) as its last byte
  194.                               if ((ch != 0x00) && (bytesRead >= 1)) {
  195.                               buffer[bytesRead - 1] = 0;
  196.                               }
  197.                    
  198.             return true;
  199.       }
  200.  
  201.  
  202. /**********************************************************************************************************/
  203. boolean checkPasswords(char old[], char submitted[] )
  204. {
  205.  
  206.    char *p1 ;
  207.    char *p2;
  208.    
  209.    p1 = old ;
  210.    p2 = submitted ;
  211.  
  212.  
  213.       while(*p1 == *p2)
  214.       {
  215.           if ( *p1 == '\0' || *p2 == '\0' )
  216.           break;
  217.          
  218.           p1++;
  219.           p2++;
  220.       }
  221.           if( *p1 == '\0' && *p2 == '\0' )
  222.           return true;
  223.           else
  224.           return false;
  225.    
  226.          
  227.          
  228. }
  229.  
  230. /***********************************************************************************************************/
  231.      boolean lockUnlock(){
  232.           char _key  ;
  233.           bool flag  ;
  234.              
  235.  
  236.              // B ascii dec 66 gives us locked , D ascii dec 68 gives us unlocked
  237.              while (!((_key == 66)||(_key == 68)))
  238.              {
  239.                     _key = keypad.getKey(); // get the next key press until we have one or the other
  240.                     ;
  241.                          switch(_key){
  242.                                            Serial.println(_key) ;
  243.                               case 'B' :
  244.                                           digitalWrite(_LOCK , HIGH) ; // turn on the solenoid
  245.  
  246.                                           flag = true ;
  247.                                          
  248.                                           break ;
  249.                
  250.                               case 'D' :
  251.                                           digitalWrite(_LOCK , LOW) ; // turn on the solenoid
  252.  
  253.                                           flag = false ;
  254.                                           break ;
  255.                               default:
  256.  
  257.                                           break ;
  258.  
  259.                        
  260.  
  261.                          }
  262.              }
  263.      
  264.      
  265.         return  flag ;
  266.        }
  267.  
  268.  
  269.  
  270.  
  271. /**********************************************************************************************************/
  272.  
  273. void showMsg(char * message,int top , int bot)
  274. {
  275.       // press accept to enter key
  276.          lcd.setCursor(top,bot);
  277.             lcd.print(message);
  278.              
  279.              
  280. }
  281.  
  282.  
  283. /***********************************************************************************************************/
  284.        
  285.  
  286.              
  287.  
  288.       void getUserPasskey(){
  289.  
  290.           int i = 0 ;
  291.           char *p = _newkey ;
  292.           char *initial;
  293.           initial = p ;
  294.           bool RedoFlag = true  ;
  295.           char counter[1] ;
  296.           String counterstr = String("Entries Left = ") ;
  297.           State = 2 ;
  298.  
  299.          
  300.          
  301.          
  302.                    
  303.                      
  304.           lcd.clear();
  305.           // initialise the lcd position
  306.           // write menu for get user password
  307.           showMsg(msg7,0,1) ;
  308.          
  309.           lcd.setCursor(5,0) ; //top row 5th column
  310.  
  311.           // check to see if we are still entering letter keys
  312.          
  313.          
  314.           if((key>= 65)&&(key <= 68)){
  315.             // key is letter and not digit
  316.                      
  317.                      
  318.                      while((key>= 65)&&(key <= 68))
  319.                      {
  320.                         key = keypad.getKey(); // get the next key  keep doing this untill we have digit
  321.                      }
  322.           } // end if
  323.  
  324.                     // we have digits only ;  we want to grab all digits
  325.                      
  326.             do {
  327.                    
  328.                      
  329.  
  330.  
  331.                     // we have digits only ;  we want to grab all digits
  332.  
  333.              
  334.                   if(!((key>= 65)&&(key <= 68))){ // looking for capital A,B,C,D  We dont want these We only want digits
  335.                        key = keypad.getKey(); // get next key
  336.  
  337.                         // only concerened with digits  ascii  48 to ascii 59
  338.                         if((key <=59)&&(key >= 48))
  339.                         {
  340.                             lcd.setCursor((5+i),0) ; //top row 5th column
  341.                             lcd.print(key) ;
  342.                            
  343.                             lcd.setCursor((5+i),0); // relocate  cursor back to same position
  344.                             delay(200) ;             // delay another 200ms
  345.                            
  346.                             lcd.print('*');          // hide the  digit entered
  347.                            
  348.                             lcd.setCursor(0,1);     // locate bottom row to indicate how many digits client has entered
  349.                            
  350.                             *p = key ; // put this into the array holding old password ;  pointer is initialised at array[0]
  351.                              p++ ;
  352.                              i+=1 ;  // increment i  by one
  353.                            
  354.                             itoa((6-i),counter,10); // convert integer to chararray
  355.                            
  356.                             lcd.print(counterstr + counter);// print display message for client showing entries
  357.                            
  358.                         } // end if
  359.                        
  360.                   }// end if
  361.  
  362.                   // we now have all digits  now we want a yes or no as acceptance for passkey entered
  363.  
  364.                   if (i==6)
  365.                   {
  366.                      delay(400);
  367.                      key = keypad.getKey();
  368.                      
  369.                                          
  370.                      showMsg(msg1,1,0);
  371.                      showMsg(msg5,0,1) ;
  372.  
  373.                      
  374.                      
  375.                      do {
  376.  
  377.                          
  378.                            switch(key)
  379.                            {
  380.                                case '*' :
  381.                                           lcd.clear();
  382.                                           showMsg(msg2,1,0);
  383.                                           RedoFlag = false ;
  384.                                           showMsg(msg9,0,1);
  385.                                           State = 2;  // accept state
  386.                                              
  387.                                                
  388.                                                if (checkPasswords(_oldkey,_newkey) )
  389.                                               {
  390.                                                   State = 1 ; // password accepted state
  391.                                                   showMsg(msgA,0,1);
  392.                                                       delay(1000);
  393.                                                   showMsg(msg8,0,1);
  394.  
  395.                                                           if (locked=lockUnlock()) {
  396.                                                            showMsg(msgC,0,1) ;
  397.                                                            showMsg(msg5,1,0);
  398.                                                           }
  399.                                                           else
  400.                                                               {
  401.                                                                 showMsg(msg5,1,0);
  402.                                                                 showMsg(msgD,0,1) ;
  403.                                                               }
  404.                                                        
  405.                                               }else
  406.                                                   {
  407.                                                             showMsg(msgB,0,1);
  408.                                                             delay(1000);
  409.                                                             State = 3 ; // exit back to main menu
  410.                                                   }
  411.                                          
  412.                                          
  413.                                          
  414.                                     break ;
  415.                                case '#':
  416.                                           lcd.clear();
  417.                                           showMsg(msg3,1,0);
  418.                                           RedoFlag = false ;
  419.                                           State = 3 ;
  420.                                     break ;
  421.  
  422.                                case 'C':  
  423.                                          
  424.                                           Serial.println(key);
  425.                                        
  426.                                           RedoFlag = true ;
  427.                                           State = 3; // exit state
  428.                                           Serial.print("State =" ) ;
  429.                                           Serial.println(State,DEC) ;
  430.                                     break ;
  431.                                
  432.                                
  433.                                default :
  434.  
  435.                                     break ;
  436.                                    
  437.                            
  438.                            }
  439.  
  440.                      
  441.                           key = keypad.getKey();
  442.                          
  443.                        
  444.                      } while(((key!=42)||(key!=35))&&(State !=3));
  445.                      
  446.                    
  447.                    
  448.                      
  449.                  
  450.                   } // end if i == 6
  451.  
  452.                  
  453.  
  454.                   // check to see if client rejected his entry
  455.                  
  456.                    
  457.                  
  458.  
  459.  
  460.             }while ((i < 6)&&(RedoFlag==true)) ; // end  do while (i < 6)
  461.  
  462.          
  463.        
  464.             // add our '/0' to the array
  465.           *p = STRING_TERMINATOR ;
  466.  
  467.           Serial.println(_oldkey ); // this is for debug puposes so i can see if password entry was complete  
  468.           int  dimension = (sizeof(_oldkey)/sizeof(char)); //array size  
  469.          
  470.           /* debuggging
  471.              i= 0; // initialise i
  472.              while (i < 6){
  473.              
  474.               Serial.println( _oldkey[i]);
  475.               i++ ;
  476.              }
  477.             */
  478.  
  479.          
  480.          
  481.                
  482.                      lcd.setCursor(1,0) ;
  483.                      lcd.clear();
  484.                      showMsg(msg6,1,0);
  485.                      showMsg(msg0,0,1);
  486.                
  487.                      
  488.  
  489.       }// end method
  490.    
  491.    
  492.    
  493.    /*****************************************************************************************************************/
  494.  
  495.  
  496.    
  497.  
  498.       void loop() {
  499.      
  500.      
  501.  
  502.      
  503.             key = keypad.getKey();
  504.  
  505.             /* debug purposes
  506.              *  
  507.              */
  508.              
  509.              
  510.              switch (key)
  511.              {
  512.                  
  513.                  /*using letter keys to obtain different fucntionality of main menu */
  514.                
  515.                 case 'A':
  516.                          // Serial.println("Enter Password ") ;  // for debug purposes only
  517.                          
  518.                         getUserPasskey() ;
  519.                   break ;
  520.                
  521.                
  522.                 case 'B':
  523.  
  524.                     break ;
  525.  
  526.  
  527.                 case 'C':
  528.  
  529.                     break ;
  530.  
  531.                 case 'D':
  532.  
  533.                     break ;
  534.  
  535.                 default:
  536.                          
  537.                     break ;
  538.                    
  539.  
  540.                
  541.                
  542.  
  543.  
  544.              }
  545.  
  546.  
  547.    
  548.      
  549.            
  550.        
  551.        } // end loop    
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement