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

Status
Not open for further replies.

XRAD

Well-known member
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:
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.
 
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/2017/02/using-eeprom-to-store-data-on-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
  }
}
 
Status
Not open for further replies.
Back
Top