Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 3 of 3

Thread: XRAD keypad lock: How to store string to int EEPROM teensy 3.2

  1. #1
    Junior Member XRAD's Avatar
    Join Date
    Aug 2018
    Posts
    18

    XRAD keypad lock: How to store string to int EEPROM teensy 3.2

    Hello,

    building arduino TFT touch keypad lock with 'change password' function. I want to be able to store the 'changed password' in teensy eeprom.

    I can store, read and clear EEPROM . But having trouble storing a string of numbers and recalling them from EEPROM so that they look like a string again. Tried several variants using arduino string to int.....

    string:
    Code:
    String password = "0000";


    Code:
    void writeTextfield()
    {
    
     //Serial.println(password.toInt());//string to int
    
      byte value = (password.toInt());     // converted value
    
      EEPROM.write(address, value);//write value to current address counter address, like string to int?
    
      Serial.println();
      Serial.print("Code value stored at address ");
      Serial.print(address);Serial.print(": ");
      Serial.println(value);
    
      address++;                      //increment address counter
      if (address == EEPROM.length()) //check if address counter has reached the end of EEPROM
      {
        address = 0;              //if yes: reset address counter
      }
    }

    no compile errors, just writing '0' to EEPROM for '0000', and '87' for '1111', and '101' for '1010', and '15' for '9999'......etc.....

    and these EEPROM numbers are staying in memory on reboot, unless I clear them, so that part works fine......

    Thanks in advance for any pointers!
    Last edited by XRAD; 05-08-2019 at 02:24 AM.

  2. #2
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    8,325
    Code snippets not easy to read and get full understanding, or to begin to replicate - and more info/example seems missing of what is in String password? :: " '0000' and '87' for '1111'......etc....."

    Using String type has its place where it works - though conflicts are up to user to avoid.

    In this case password is a 4 char string but is put into a byte ( 0-255 with 8 bits ) and the conversion used is :: password.toInt()

    Anything over 255 will be lost - if the string holds a text integer, or is it a bit string which won't work at all.

  3. #3
    Junior Member XRAD's Avatar
    Join Date
    Aug 2018
    Posts
    18
    Thx for reply!



    This code works great and I can recall the analog values from EEPROM

    but instead of storing:

    byte value = analogRead(tempPin); //read sensor value

    I want to store a string of text characters which happen to be the 'lock' code 0000 or 1234 or whatever string of numbers (max 12)....or what fits in 255 EEPROM size. Wondering if it can be done.......

    I am using a modified variant of this code found here: https://www.norwegiancreations.com/2...n-the-arduino/

    Code:
    #include <EEPROM.h>
     
    #define SAMPLE_TIME 2000  //The time between each EEPROM write function call in ms
     
    int tempPin = 0;      //the ADC pin
    int printPin = 2;     //the print button pin
    int erasePin = 4;    //the erase button pin
     
    int address = 0;      //EEPROM address counter
     
    unsigned long timer;
     
    float conv_coeff = 0.0;   //coefficient for converting from 0-1024 to 0-5 range
     
    void printTemp();
    void clearEEPROM();
    void writeTemp();
     
    void setup(){
      Serial.begin(115200);     //start the serial connection as always
      conv_coeff = 5.0/1024.0;  //find the coefficient to do the conversion
      timer = millis();         //millis() returns the time since program start in ms
    }
     
    void loop(){
      if(millis()-timer > SAMPLE_TIME)  //check if it's time to do a temp sensor sample
      {
        writeTemp();
        timer = millis();
      }
     
      if(!digitalRead(printPin))  //check if print button is pressed
      {
        printTemp();
        delay(500);
      }
     
      if(!digitalRead(erasePin)) //check if erase button is pressed
      {
        clearEEPROM();
        delay(500);
      }
       
      delay(1);
    }
     
    void printTemp()
    {
      for (int i = 0 ; i < EEPROM.length() ; i++) {
        byte value = EEPROM.read(i);                //read EEPROM data at address i
        if(value != 0)                              //skip "empty" addresses
        {
          float temp = value*conv_coeff;            //convert ADC values to temperature
          temp = (temp - 0.5)*100;                  //take care of the offset
     
          Serial.println(temp);
        }
      }
    }
     
    void clearEEPROM()
    {
      for (int i = 0 ; i < EEPROM.length() ; i++) {
        if(EEPROM.read(i) != 0)                     //skip already "empty" addresses
        {
          EEPROM.write(i, 0);                       //write 0 to address i
        }
      }
      Serial.println("EEPROM erased");
      address = 0;                                  //reset address counter
    }
     
    void writeTemp()
    {
      byte value = analogRead(tempPin);     //read sensor value
       
      EEPROM.write(address, value);         //write value to current address counter address
     
      Serial.print("Sensor value stored at address ");
      Serial.println(address);
       
      address++;                      //increment address counter
      if(address == EEPROM.length())  //check if address counter has reached the end of EEPROM
      {
        address = 0;              //if yes: reset address counter
      }
    }

    this is my lock sketch(not complete)....my first goal is to store the string of code characters....once I can store the code and recall it, I will begin to code a way for the user to reprogram the lock code, which will be stored in EEPROM and on next boot, read first , and will become the new keypadlock code .

    Code:
    //Hardware: keypad touch tft 320x240 adafruit feather 2.4" and teensy 3.2 feather adapter
    
    
    #include "Adafruit_GFX.h"
    #include "Adafruit_ILI9341.h"
    #include <Adafruit_STMPE610.h>
    #include <EEPROM.h>
    
    
    
    #if defined (__AVR_ATmega32U4__) || defined(ARDUINO_SAMD_FEATHER_M0) || defined (__AVR_ATmega328P__) || \
        defined(ARDUINO_SAMD_ZERO) || defined(__SAMD51__) || defined(__SAM3X8E__) || defined(ARDUINO_NRF52840_FEATHER)
    #define STMPE_CS 6
    #define TFT_CS   9
    #define TFT_DC   10
    #define SD_CS    5
    #endif
    
    #ifdef TEENSYDUINO
    #define TFT_DC   10
    #define TFT_CS   4
    #define STMPE_CS 3
    #define SD_CS    8
    #endif
    
    // Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC
    Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
    
    // The STMPE610 uses hardware SPI on the shield,
    Adafruit_STMPE610 ts = Adafruit_STMPE610(STMPE_CS);
    
    // This is calibration data for the raw touch data to the screen coordinates 320x240 feather
    #define TS_MINX 150
    #define TS_MINY 130
    #define TS_MAXX 3800
    #define TS_MAXY 3750
    
    /******************* UI details */
    #define BUTTON_X 40
    #define BUTTON_Y 100
    #define BUTTON_W 60
    #define BUTTON_H 30
    #define BUTTON_SPACING_X 20
    #define BUTTON_SPACING_Y 20
    #define BUTTON_TEXTSIZE 2
    
    // text box where numbers go
    #define TEXT_X 10
    #define TEXT_Y 10
    #define TEXT_W 220
    #define TEXT_H 50
    #define TEXT_TSIZE 3
    #define TEXT_TCOLOR ILI9341_MAGENTA
    
    // the data (code #) we store in the textfield
    #define TEXT_LEN 12
    char textfield[TEXT_LEN + 1] = "";
    uint8_t textfield_i = 0;
    
    //int tempPin = 0;      //the ADC pin
    //int printPin = 2;     //the print button pin
    //int erasePin = 1;    //the erase button pin
    
    int address = 0;      //EEPROM address counter
    
    void printTextfield();
    void clearEEPROM();
    void writeTextfield();
    
    float conv_coeff = 0.0;   //coefficient for converting from 0-1024 to 0-5 range
    
    
    
    
    //  status txt line
    #define STATUS_X 10
    #define STATUS_Y 65
    
    #define STATUS_BOOT_X 18
    #define STATUS_BOOT_Y 25
    
    /* create 15 buttons, in classic candybar phone style */
    char buttonlabels[15][5] = {"ENTR", "CLR1", "VOID", "1", "2", "3", "4", "5", "6", "7", "8", "9", "*", "0", "#" };
    uint16_t buttoncolors[15] = {ILI9341_DARKGREEN, ILI9341_RED, ILI9341_RED,
                                 ILI9341_BLUE, ILI9341_BLUE, ILI9341_BLUE,
                                 ILI9341_BLUE, ILI9341_BLUE, ILI9341_BLUE,
                                 ILI9341_BLUE, ILI9341_BLUE, ILI9341_BLUE,
                                 ILI9341_DARKGREY, ILI9341_BLUE, ILI9341_DARKGREY
                                };
    Adafruit_GFX_Button buttons[15];
    
    // Print something in the mini status bar with either flashstring
    void status(const __FlashStringHelper *msg) {
      tft.fillRect(STATUS_X, STATUS_Y, 240, 8, ILI9341_BLACK);
      tft.setCursor(STATUS_X, STATUS_Y);
      tft.setTextColor(ILI9341_WHITE);
      tft.setTextSize(1);
      tft.print(msg);
    }
    // or charstring
    void status(char *msg) {
      tft.fillRect(STATUS_X, STATUS_Y, 240, 8, ILI9341_BLACK);
      tft.setCursor(STATUS_X, STATUS_Y);
      tft.setTextColor(ILI9341_WHITE);
      tft.setTextSize(1);
      tft.print(msg);
    }
    
    
    void statusBoot(const __FlashStringHelper *msg) {
      tft.fillRect(STATUS_BOOT_X, STATUS_BOOT_Y, 205, 20, ILI9341_BLACK);
      tft.setCursor(STATUS_BOOT_X, STATUS_BOOT_Y);
      tft.setTextColor(ILI9341_WHITE);
      tft.setTextSize(2);
      tft.print(msg);
    }
    
    void statusBoot(char *msg) {
      tft.fillRect( STATUS_BOOT_X, STATUS_BOOT_Y, 205, 20, ILI9341_BLACK);
      tft.setCursor(STATUS_BOOT_X, STATUS_BOOT_Y);
      tft.setTextColor(ILI9341_WHITE);
      tft.setTextSize(2);
      tft.print(msg);
    }
    
    
    
    String password = "0000"; //Variable to store the current password
    String tempPassword = ""; //Variable to store the input password
    //int doublecheck;    //Check twice the new passoword
    //boolean armed = false;  //Variable for system state (armed:true / unarmed:false)
    //boolean input_pass;   //Variable for input password (correct:true / wrong:false)
    //boolean storedPassword = true;
    //boolean changedPassword = false;
    //boolean checkPassword = false;
    //int i = 1; //variable to index an array
    
    
    
    
    void setup() {
      Serial.begin(115200);
      Serial.println("KEYPADLOCK");
    
      // clear the screen
      tft.begin();
    
      //tft.setRotation(0);
      tft.fillScreen(ILI9341_BLACK);
    
      // eep touchscreen not found?
      if (!ts.begin()) {
        Serial.println("Couldn't start touchscreen controller");
        while (1);
      }
      Serial.println("Touchscreen started");
    
      // create buttons
      for (uint8_t row = 0; row < 5; row++) {
        for (uint8_t col = 0; col < 3; col++) {
          buttons[col + row * 3].initButton(&tft, BUTTON_X + col * (BUTTON_W + BUTTON_SPACING_X),
                                            BUTTON_Y + row * (BUTTON_H + BUTTON_SPACING_Y), // x, y, w, h, outline, fill, text
                                            BUTTON_W, BUTTON_H, ILI9341_WHITE, buttoncolors[col + row * 3], ILI9341_WHITE,
                                            buttonlabels[col + row * 3], BUTTON_TEXTSIZE);
          buttons[col + row * 3].drawButton();
        }
      }
    
      // create 'text field'
      tft.drawRect(TEXT_X, TEXT_Y, TEXT_W, TEXT_H, ILI9341_WHITE);
    
    
    
      for (int i = 0; i < 5; i++) {
        statusBoot(F("RESTRICTED ACCESS"));
        delay(500);
        clearText();
        delay(100);
      }
    
      conv_coeff = 5.0 / 1024.0;
      //conv_coeff = 1;//find the coefficient to do the conversion
    }
    
    
    void loop(void) {
      TS_Point p;
    
      if (ts.bufferSize()) {
        p = ts.getPoint();
      } else {
        // this is our way of tracking touch 'release'!
        p.x = p.y = p.z = -1;
      }
    
      // Scale from ~0->4000 to tft.width using the calibration #'s
      if (p.z != -1) {
        p.x = map(p.x, TS_MINX, TS_MAXX, tft.width(), 0);
        p.y = map(p.y, TS_MINY, TS_MAXY, 0, tft.height());
        Serial.print("("); Serial.print(p.x); Serial.print(", ");
        Serial.print(p.y); Serial.print(", ");
        Serial.print(p.z); Serial.println(") ");
      }
    
      // go thru all the buttons, checking if they were pressed
      for (uint8_t b = 0; b < 15; b++) {
        if (buttons[b].contains(p.x, p.y)) {
          //Serial.print("Pressing: "); Serial.println(b);
          buttons[b].press(true);  // tell the button it is pressed
        } else {
          buttons[b].press(false);  // tell the button it is NOT pressed
        }
      }
    
      // now we can ask the buttons if their state has changed
      for (uint8_t b = 0; b < 15; b++) {
        if (buttons[b].justReleased()) {
          // Serial.print("Released: "); Serial.println(b);
          buttons[b].drawButton();  // draw normal
        }
    
        if (buttons[b].justPressed()) {
          clearText();
          buttons[b].drawButton(true);  // draw invert!
    
          // if a numberpad button, append the relevant # to the textfield
          if (b >= 3) {
            if (textfield_i < TEXT_LEN) {
              textfield[textfield_i] = buttonlabels[b][0];
              textfield_i++;
              textfield[textfield_i] = 0; // zero terminate
    
            }
          }
    
          if (b == 12) {
            clearEEPROM();
            delay(2000);
          }
    
    
    
          if (b == 14) {
            printTextfield();
            delay(2000);
          }
    
    
    
          // clr button! delete char
          if (b == 1) {
            status(F("CLEARING LAST DIGIT..."));
            textfield[textfield_i] = 0;
            if ( textfield_i <= 0) {
              textfield_i = 0;
            }
            else {
              if (textfield > 0) {
                textfield_i--;
                textfield[textfield_i] = ' ';
              }
            }
          }
    
    
          // update the current text field
          Serial.println(textfield);
          tft.setCursor(TEXT_X + 2, TEXT_Y + 10);
          tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
          tft.setTextSize(TEXT_TSIZE);
          tft.print(textfield);
    
          //clear all characters
          if ((b == 2) && (textfield > 0))  {
            status(F("CLEARING FULL CODE..."));
            for (int i = 0; i < 13 ; i++) {
              if ( textfield_i <= 0) {
                textfield_i = 0;
              }
              else {
                textfield_i-- ;
                textfield[textfield_i] = ' ';
              }
            }
          }
    
          // update the current text field
          Serial.println(textfield);
          tft.setCursor(TEXT_X + 2, TEXT_Y + 10);
          tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
          tft.setTextSize(TEXT_TSIZE);
          tft.print(textfield);
    
          // enter code for verification
          if (b == 0) {
    
            tempPassword = textfield;
    
    
            if (tempPassword == password) {
              status(F("ACCESS GRANTED..."));
              Serial.print("ACCESS GRANTED   CODE: "); Serial.print(textfield);
              tft.setCursor(TEXT_X + 2, TEXT_Y + 10);
              tft.setTextColor( ILI9341_BLUE, ILI9341_BLACK);
              tft.setTextSize(TEXT_TSIZE);
              tft.print(textfield);
    
              writeTextfield();////eeprom
    
              delay(250);
    
    
    
    
              if (textfield > 0)  {
                for (int i = 0; i < 13 ; i++) {
                  if ( textfield_i <= 0) {
                    textfield_i = 0;
                  }
                  else {
                    textfield_i-- ;
                    textfield[textfield_i] = ' ';
                  }
                }
              }
              Serial.print(textfield);
              tft.setCursor(TEXT_X + 2, TEXT_Y + 10);
              tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
              tft.setTextSize(TEXT_TSIZE);
              tft.print(textfield);
    
    
              for (int i = 0; i < 5; i++) {
                clearText();
                delay(100);
                statusBoot(F(" LIDAR ACTIVATED"));
                delay(500);
              }
            }
    
            else {
    
              status(F("CONFIRMING CODE....ACCESS DENIED"));
              Serial.print("CONFIRMING CODE....ACCESS DENIED");
              delay(500);
              //clear all characters
              if (textfield > 0)  {
                status(F("CLEARING FULL CODE..."));
                for (int i = 0; i < 13 ; i++) {
                  if ( textfield_i <= 0) {
                    textfield_i = 0;
                  }
                  else {
                    textfield_i-- ;
                    textfield[textfield_i] = ' ';
                  }
                }
              }
              Serial.print(textfield);
              tft.setCursor(TEXT_X + 2, TEXT_Y + 10);
              tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
              tft.setTextSize(TEXT_TSIZE);
              tft.print(textfield);
            }
          }
    
          delay(100); // UI debouncing
        }
      }
    }
    
    
    void clearText() {
      tft.fillRect( STATUS_BOOT_X, STATUS_BOOT_Y, 205, 20, ILI9341_BLACK);
    }
    
    
    
    
    
    void printTextfield()
    {
      for (int i = 0 ; i < EEPROM.length() ; i++) {
        byte value = EEPROM.read(i);                //read EEPROM data at address i
        if (value != 0)                             //skip "empty" addresses
        {
    
          float newCode = value;
    
          Serial.println(newCode);
        }
      }
    }
    
    
    void clearEEPROM()
    {
      for (int i = 0 ; i < EEPROM.length() ; i++) {
        if (EEPROM.read(i) != 0)                    //skip already "empty" addresses
        {
          EEPROM.write(i, 0);                       //write 0 to address i
        }
      }
      Serial.println("EEPROM erased");
      address = 0;                                  //reset address counter
    }
    
    void writeTextfield()
    {
     
      byte value = textfield;//this is the key step, I know I can't just use 'textfield'  
    
      EEPROM.write(address, value);//write value to current address counter address, like string to int?
    
      Serial.println();
      Serial.print("Code value stored at address ");
      Serial.print(address); Serial.print(": ");
      Serial.println(value);
    
      address++;                      //increment address counter
      if (address == EEPROM.length()) //check if address counter has reached the end of EEPROM
      {
        address = 0;              //if yes: reset address counter
      }
    }

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •