0

I'm trying to make a slideshow using Arduino Uno + TFT LCD.

In which three steps happen:

  1. a shape is shown
  2. user touches a specified area of the screen
  3. it shows the next slide.

The device may turn off during the slides and I want to make Arduino remember at which step we were right before it turns off so it can start at the latest previous position.

To do that I'm trying to use EEPROM (any other suggestions are welcome). However, each time I turn off the device and turn it on again, it starts at the previous position in the slides, however, the slides won't progress when I touch the specified area.

When I check the serial monitor the state variable (which is the variable I used to save the state of progression in the slideshow in the memory) turns back a huge random number.

here is serial monitor log:

s = 0   n = 1   st = 126    X = -9  Y = 217 Pressure = 653
s = 0   n = 1   st = 126    X = -9  Y = 218 Pressure = 565
s = 0   n = 2   st = 127    X = -9  Y = 224 Pressure = 462
s = 0   n = 2   st = 127    X = -9  Y = 225 Pressure = 434

Here is my simplified and extensively commented :D code:

// libraries and and defined variables
#include <EEPROM.h>
#include "Adafruit_GFX.h"
#include "MCUFRIEND_kbv.h"

MCUFRIEND_kbv tft;
int n = 1;
int addr;
bool t = false;
#include "TouchScreen.h"
#define YP A2
#define XM A3
#define YM 8
#define XP 9


int s;
int state ;
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);

// prepairatio of LCD, there is a check() function for memory though. 
void setup(void) {

  tft.reset();
  Serial.begin(9600);
  uint16_t ID = tft.readID();
  tft.begin(ID);
  tft.setRotation(1);
  tft.invertDisplay(true);
  tft.fillScreen(0x0000);
  check(); //<------- the check function for the memory---
  
  //#FIRST picture on the LCD
  tft.fillRect(120, 160, 10, 20, 0x1C12);

}
// void loop 
void loop(void) {
// some touch screen prepairations
  digitalWrite(13, HIGH);
  TSPoint p = ts.getPoint();
  digitalWrite(13, LOW);


  pinMode(XM, OUTPUT);
  pinMode(YP, OUTPUT);
  p.x = map(p.x, 150, 920, tft.width(), 0);
  p.y = map(p.y, 120, 940, tft.height(), 0);
// first if() condition for the pressure amount needed 
  if (p.z > 100 || s == 1)  { //<----------- "s" variable was used--------
    Serial.print("s = "); Serial.print(s);//it will change becuase of state to lead us to last level
    Serial.print("\tn = "); Serial.print(n);// level of game
    Serial.print("\tst = "); Serial.print(state);//data to be remembered
    Serial.print("\tX = "); Serial.print(p.x);//area of touch
    Serial.print("\tY = "); Serial.print(p.y);//area of touch
    Serial.print("\tPressure = "); Serial.println(p.z);
 // second if() condition for the location of touching 
    if ((p.y > 217 && p.y < 241 && p.x > -10 &&  p.x < 2 && n == 1) || s == 1) {//<----------- "s" variable was used--------


      tft.fillRect(0, 0, 15, 30, 0xFFE0);

      t = !t;
      if (t == true) {
        n++;
        state++; //<----------- state variable increases by each level--------
      }
      t = !t;

      EEPROM.write(0, state);//<----------- state is being written to the memory so that the next time the device is on, it remembers how far it went--------
    }
  }

  if (p.z > 100 || s == 2  )  {//<----------- "s" variable was used--------


    if ((p.y > 210 && p.y < 241 && p.x > 8 &&  p.x < 12 && n == 2) || s == 2)  {


      tft.fillRect(0, 0, 15, 30, 0xFFE0);
      t = !t;
      if (t == true) {
        n++;
        state++;//<----------- state variable increases by each level--------
      }
      t = !t;

      EEPROM.write(0, state);//<----------- state is being written to the memory so that the next time the device is on, it remembers how far it went--------
    }
  }

}
//checking memory 
void check(void) {
  state = EEPROM.read(0);//<--- defining state by the number read from the memory-----
  if (state == 1) { //<------ if the state being read is 1, then... 
    s = s + state; //<------ make s also 1. (s here is 0 as defined at the beggining)----
  }
  if ( state == 2) { //<----------and so on---
    s = s + state;

  }
}
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190

1 Answers1

0

The EEPROM.read and EEPROM.write functions act on bytes whereas your 'state' variable is an int, which is 2 or more bytes, so only part of the data is being read and written.

Try using the EEPROM.put() and EEPROM.get() functions.

These are polymorphic functions ( using C++ templates) so they automatically detect the number of bytes in the type whatever variable you are writing(probably using sizeof()) and read or write the number of bytes accordingly.

Note also the different interface. These two functions read and write the variables by reference not by value

QuatCoder
  • 232
  • 1
  • 5
  • thanks for your answer. I tried your suggestion but it gave me the same result as before and I did not see anything different from before. – Pegah Khademi Mar 06 '21 at 17:05
  • What is the valid range of values for the s and state variables? – QuatCoder Mar 06 '21 at 17:59
  • My original work have 18 level so it should be from 0 to 18 here you can see only two levels. My main problem is state goes on for itself and I don't know why – Pegah Khademi Mar 06 '21 at 18:59
  • In the setup, have you checked that after you read the state variable from EEPROM, it is in your correct range? – QuatCoder Mar 06 '21 at 19:12
  • as you can see in the serial log that I have shared the state goes up after the first time that it remembered correctly. – Pegah Khademi Mar 07 '21 at 13:01
  • You will have to do some debugging. You could try adding a check that 'state' is always in correct range before writing to EEPROM and after reading from EEPROM. Then show an error message and stop( wait in endless loop) if it isn't. – QuatCoder Mar 07 '21 at 13:30
  • thank you. your words gave me an idea and I solved it:) – Pegah Khademi Mar 07 '21 at 16:58