Saving touch screen calibration data, after power off.

Hello everyone,

I'm a relatively new to Arduino programming. I have used them in the past to build robots, but now I'm doing something brand new to me. That being working with touch screens. luckily I have gotten my ESP32 based board working well with the screen, with a custom gui that's almost done. So now I need to save the calibration form the screen. The TFT_eSPI library has a touch calibration function built in. It only outputs to a uint16_t array with 6 slots (0 - 5). So to make it work It looks something like this:

#include <TFT_eSPI.h>
#include <SPI.h>
TFT_eSPI tft = TFT_eSPI();

uint16_t calData[6];

void setup() {

tft.calibrateTouch( calData, TFT_MAGENTA, TFT_BLACK, 15); // Runs a test that has you touch the corners of the screen
tft.setTouch(calData);     // setTouch actually implements the data form calibrateTouch

}

void loop() {
//Rest of the code

}

From what I have been reading EPROMM only accepts values for 0 - 255 (8 bit). The calibration data ranges from 0 to like 4800. I don't think converting such a large range into a small range is good idea because I lose so much precision, but I'm also not 100% sure of that.

TLDR; What is the best way and/or easiest way to store user inputted uint_16_t with a large range, so its not lost on power off?

Additional info (as if you need it after that long post):
The screen is 240 x 320, it also has a SD card slot. Board chip is the ESP32-WROOM32 and the board is called the NodeMCU Esp-32s.

Thanks in advanced, anything helps!

Hi there

I don't know how well you are into C programming, but pointers and type casting are your friends in this case. Pointers (as the name hints) points to a location in memory, and type casting allows you to manipulate data as another data type than originally intended.
A byte is 8 bits and you are trying to save 16 bits of data. The solution will look something like this:

#include <TFT_eSPI.h>
#include <SPI.h>
#include <EEPROM.h>
TFT_eSPI tft = TFT_eSPI();

uint16_t calData[6]; //You need 6 values, right?
 
void setup() {

tft.calibrateTouch( calData, TFT_MAGENTA, TFT_BLACK, 15); // Runs a test that has you touch the corners of the screen
tft.setTouch(calData);     // setTouch actually implements the data form calibrateTouch

for(int i=0; i<6; i++) {
  static int EEPROMaddress = 0; //To keep track of eeprom address
  byte* pointer = (byte*)&calData[i]; //a pointer to a byte. (byte*) casts the pointer to type 'byte*' (byte pointer)
  EEPROM.write(EEPROMaddress, *pointer); //Write the first byte of the value (* is used to access the data at the pointer)
  pointer++;
  EEPROMaddress++;
  EEPROM.write(EEPROMaddress, *pointer); //Write the second byte
  
}
}
void loop () {
  
}

To read the data from the EEPROM you will need to do the reverse:

for(int i=0; i<6, i++) {
    static int EEPROMaddress = 0;
    byte* pointer = (byte*)&calData[i];
    EEPROM.read(EEPROMaddress, *pointer);
    pointer++;
    EEPROMaddress++;
    EEPROM.write(EEPROMaddress, *pointer);
  }

I haven't been able to test the code.
I hope it helps.

EDIT:
If you want a quick solution you can use EEPROM.put() and EEPROM.get() - they will allow you to put any datatype on the EEPROM. But i encourage you to read about and understand pointers and type casting. :slight_smile:

SECOND EDIT:
I'm not sure the ESP32 EEPROM library can handle put() and get() - if not, you need the pointers and type casting.

kasperbruun:
Hi there

I don't know how well you are into C programming, but pointers and type casting are your friends in this case. Pointers (as the name hints) points to a location in memory, and type casting allows you to manipulate data as another data type than originally intended.
A byte is 8 bits and you are trying to save 16 bits of data. The solution will look something like this:

#include <TFT_eSPI.h>

#include <SPI.h>
#include <EEPROM.h>
TFT_eSPI tft = TFT_eSPI();

uint16_t calData[6]; //You need 6 values, right?

void setup() {

tft.calibrateTouch( calData, TFT_MAGENTA, TFT_BLACK, 15); // Runs a test that has you touch the corners of the screen
tft.setTouch(calData);    // setTouch actually implements the data form calibrateTouch

for(int i=0; i<6; i++) {
  static int EEPROMaddress = 0; //To keep track of eeprom address
  byte* pointer = (byte*)&calData[i]; //a pointer to a byte. (byte*) casts the pointer to type 'byte*' (byte pointer)
  EEPROM.write(EEPROMaddress, pointer); //Write the first byte of the value ( is used to access the data at the pointer)
  pointer++;
  EEPROMaddress++;
  EEPROM.write(EEPROMaddress, *pointer); //Write the second byte
 
}
}
void loop () {
 
}




To read the data from the EEPROM you will need to do the reverse:



for(int i=0; i<6, i++) {
    static int EEPROMaddress = 0;
    byte* pointer = (byte*)&calData[i];
    EEPROM.read(EEPROMaddress, *pointer);
    pointer++;
    EEPROMaddress++;
    EEPROM.write(EEPROMaddress, *pointer);
  }




I haven't been able to test the code.
I hope it helps.

EDIT:
If you want a quick solution you can use EEPROM.put() and EEPROM.get() - they will allow you to put any datatype on the EEPROM. But i encourage you to read about and understand pointers and type casting. :-)

I'm not too far into C programming. I'm using this project to motivate myself to learn more. I think I understand some of the concepts you are talking about. So what I'm understanding so far. The code you have here is going through each number in the array and breaking it up. It takes the first byte from the first number and saves it to first byte of EPPROM memory, then it takes the second byte of the number and save it in the next slot. then repeat for the next number until its all saved???

I'm more confused by reading the EPPROM. So its reading the first byte then taking the second byte and combining them (I don't know whats that called)? Then writing it to the Array.

Edit: About your edits:
First: I'm reading more about Pointers and Type Casting as we speak here. I think this is the best solution.
Second: I know EPPROM in general works, but I'm not sure if there are any odd functions that don't.

Hello again!
I was a bit tired last night. Forget about what i wrote about reading the EEPROM. The EEPROM read function returns a byte with the read data.
I also fixed a couple of my own mistakes in the first answer. The code you should use looks like this:

#include <TFT_eSPI.h>
#include <SPI.h>
#include <EEPROM.h>
TFT_eSPI tft = TFT_eSPI();

uint16_t calData[6]; //You need 6 values, right?

void setup() {

  tft.calibrateTouch( calData, TFT_MAGENTA, TFT_BLACK, 15); // Runs a test that has you touch the corners of the screen
  tft.setTouch(calData);     // setTouch actually implements the data form calibrateTouch

  // Write calibration data to EEPROM
  for (int i = 0; i < 6; i++) {
    static int EEPROMaddress = 0; //To keep track of eeprom address
    byte* pointer = (byte*)&calData[i]; //a pointer to a byte. (byte*) casts the pointer to type 'byte*' (byte pointer)
    EEPROM.write(EEPROMaddress, *pointer); //Write the first byte of the value (* is used to access the data at the pointer)
    pointer++; //Let the pointer point to the next byte in memory
    EEPROMaddress++;
    EEPROM.write(EEPROMaddress, *pointer); //Write the second byte
    EEPROMaddress++;
  }
  // Done writing.

  // Read calibration data from EEPROM
  for (int i = 0; i < 6; i++) {
    static int EEPROMaddress = 0;
    byte* pointer = (byte*)&calData[i]; //Have a pointer point to where the data should be placed
    *pointer = EEPROM.read(EEPROMaddress); //Read the data to that location
    EEPROMaddress++;
    pointer++;
    *pointer = EEPROM.read(EEPROMaddress); //Read the second byte
    EEPROMaddress++;
  }
  // Done reading.
}
void loop () {

}

It's still not tested. :slight_smile:

Thanks so much!
I have been doing lots of reading and trying out simpler uses of EEPROM. I think, I now understand it enough to get what is going on here. I'll have to make some very minor tweaks to it because the ESP32 EEPROM library needs to have a commit command. I will add that to the write part of the code.

This has been incredibly helpful. Thanks Again!

Happy to help. Did you get it working? :slight_smile:

kasperbruun:
Happy to help. Did you get it working? :slight_smile:

I'm going to guess that the OP did not manage to save the calibration data AFTER POWER OFF, as required by the thread title.