【问题标题】:Arduino EEPROM getting corrupt valuesArduino EEPROM 获得损坏的值
【发布时间】:2018-08-07 09:02:24
【问题描述】:

我正在使用 Arduino Uno 将几个变量保存到 EEPROM 中。我对此的解决方案是创建一个自定义结构来存储所有需要的变量,然后使用 EEPROM.put 将它们存储到内置的 EEPROM 中。

我的问题不是在放数据时出现,而是在获取数据时出现。每当我在代码中更改某些内容和/或在短时间内使用 Arduino 时,存储在 EEPROM 中的数据就会损坏。

我通过 Serial.println() 函数检查数据。据我所知,字符串数据有时会损坏,但其他数据类型不会损坏。可能是字符串数据的问题?

struct EEPROMDATA
{
    String customMessage, emergencyMessage;
    String emergencyContact[3];
    String ownerContact;
    String idleMessage;
    int travelThreshold;
    int idleThreshold;
    char password[6];
    location locationList[3];
};

EEPROMDATA eepromstruct;

void loadReset() 
{
    EEPROM.get(100, eepromstruct);
}

void saveReset()
{
    EEPROM.put(100, eepromstruct);
}

这些是我用来从 EEPROM 保存(放置)和加载(获取)数据的函数。我读过某处以避免在第 0 个地址写入数据,这就是地址设置为 100 的原因。

请记住,这不是写入 EEPROM 的问题,因为我的程序目前没有任何对 EEPROM.put 或 saveReset() 的引用。不知何故,在程序过程中,EEPROM 数据被破坏了。不知道是硬件问题还是软件问题。

编辑:我忘了注意,在解决此问题时,每当发生损坏时,我都会重新初始化,然后再次将数据保存在 EEPROM 中。之后它会在短时间内正常工作(连续打开/关闭然后测试数据、重置设备等),直到它再次损坏。

【问题讨论】:

  • 为什么你认为如果你不保存数据就不应该损坏它们('no reference to saveReset')?
  • 我忘了注意一旦发生损坏我会重新初始化然后保存数据。然后它会在短时间内正常工作,直到再次损坏。

标签: c++ memory struct arduino arduino-uno


【解决方案1】:

首先,如果您更改类 EEPROMDATA 的定义,这将“损坏”您的 eeprom 数据。不是说 eeprom 中的数据发生了某种变化,而是说您正在尝试将旧格式写入的数据读入新格式。

接下来,字符串是可变大小的字符数组。结构采用静态内存布局。 String 类通过间接(本质上是指针)实现了可变长度存储,这不能简单地从 RAM 转换为 EEPROM。

您需要决定是要在 EEPROM 中进行静态布局(在这种情况下,您必须停止弄乱结构,并将特定数量的字符专用于您的字符串)还是动态(在这种情况下,您需要编写一个 "智能”函数来解析数据进/出 EEPROM)

【讨论】:

  • 我没有更改结构的定义,所以我在那里很安全。 “弄乱结构”是什么意思?我不应该使用 struct 来存储变量吗?如果我将所有 String 对象更改为结构内的 char[] 并仍然使用它会怎样?
  • 你需要一个静态长度数组。
【解决方案2】:

当您在代码中的某个位置声明时,您需要使用 char[] 而不是使用作为类对象的 String。在动态内存分配的情况下,对象(类的实例)应该引用内存的其他区域,以通过其方法存储其数据。即使您假设您的数据将存储在 EEPROM 中,但实际上,它存储在 RAM 的某个区域中。这就是为什么您只使用字符串数据损坏数据的原因。

【讨论】:

  • 我也很怀疑。我知道使用 String 而不是 char[] 将来会产生影响。有什么办法可以在程序中使用 String 而在 EEPROM 中只使用 char[] 吗?我们有这个项目的最后期限,我不想费力地更改所有操作和函数以适应 char[] 的使用。
  • 我不确定这对你有没有帮助。但是您可以为所有其他功能保留当前结构类型。首先,您可以定义另一个具有 char[] 而不是 String 的结构,并且应该用于从 EEPROM 加载和保存。然后你需要改变“loadReset()”和“saveReset()”。在两个函数中,您需要在 char[] 和 String 之间转换数据。这样,您可以保持其他源代码不变。
  • 很高兴知道我们正在考虑同样的方法。这是一个好主意,我不知道可能会奏效。谢谢。
  • 在我的建议之上还有一条评论是在新结构中为 EEPROM 存储器定义一个附加字段,用于在之前检查数据作为魔术代码(或版本代码)的有效性从 EEPROM 中读取数据。无论何时更改结构字段或此时,这都会对您有所帮助。
  • 感谢您的帮助。我使用了 char[] 而不是 String 并且从那以后数据没有被破坏。没有论文项目真的很有帮助。
猜你喜欢
  • 2015-08-18
  • 2017-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多