如何使用 EEPROM 将 Arduino 内存中保存的数字重新引入程序?

问题描述

我正在尝试使用 Arduino Uno + TFT LCD 制作幻灯片

其中三个步骤:

  1. 显示形状
  2. 用户触摸屏幕的指定区域
  3. 显示下一张幻灯片

设备可能会在幻灯片期间关闭,我想让 Arduino 记住我们在关闭之前正确的步骤,以便它可以从最近的上一个位置开始。

为此,我正在尝试使用 EEPROM(欢迎任何其他建议)。 但是,每次我关闭设备并再次打开它时,它都会从幻灯片中的上一个位置开始,但是,当我触摸指定区域时,幻灯片不会继续。

当我检查串行监视器时,state 变量(这是我用来将幻灯片中的进程状态保存在内存中的变量)返回一个巨大的随机数。

这里是串行监视器日志

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

这是我的简化和广泛评论:D 代码

// 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,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,0xFFE0);
      t = !t;
      if (t == true) {
        n++;
        state++;//<----------- state variable increases by each level--------
      }
      t = !t;

      EEPROM.write(0,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;

  }
}

解决方法

EEPROM.read 和 EEPROM.write 函数作用于字节 而您的“状态”变量是一个 int,它是 2 个或更多字节,因此只有部分数据被读取和写入。

尝试使用 EEPROM.put()EEPROM.get() 函数。

这些是多态函数(使用 C++ 模板),因此它们会自动检测您正在写入的任何变量类型中的字节数(可能使用 sizeof())并相应地读取或写入字节数。

还要注意不同的界面。这两个函数通过引用而不是通过值来读写变量