Arduino 读取/写入EEPROM-值不正确

Arduino 读取/写入EEPROM-值不正确,arduino,esp8266,Arduino,Esp8266,我正在使用Arduino IDE编程ESP8266板 其想法是在随机时间内播放随机频率的声音,并将最后播放的频率保存到EEPROM中。然后,我有一个看门狗ISR,如果延迟时间是4秒或更长,它会重新启动电路板。当这种情况发生并且电路板重新启动时,我想播放上一次播放的频率1秒,然后再次恢复正常功能 这是我的密码 #include <Ticker.h> #include <EEPROM.h> #define PIN_BUZZER 13 // the digital pin th

我正在使用Arduino IDE编程ESP8266板

其想法是在随机时间内播放随机频率的声音,并将最后播放的频率保存到EEPROM中。然后,我有一个看门狗ISR,如果延迟时间是4秒或更长,它会重新启动电路板。当这种情况发生并且电路板重新启动时,我想播放上一次播放的频率1秒,然后再次恢复正常功能

这是我的密码

#include <Ticker.h>
#include <EEPROM.h>
#define PIN_BUZZER 13 // the digital pin the Buzzer is attached to

PROGMEM const int freqs[] = {31, 49, 78, 123, 196, 311, 494, 784, 1245, 1976, 3136,
4978};

Ticker secondTick;

volatile int watchdogCount = 0;
volatile int freqIdx = 0; //the index that will store the last frequency before it restarts

int EEPROM_Addr = 42;

//The Watchdog Interrupt Service Routine (ISR)
void ISRwatchdog() {
  watchdogCount++;
  //The watchdog will be waken up when the couter reaches 4
  if (watchdogCount == 4) {
    ESP.restart(); //restarting the board
  }
}

void setup() {
  EEPROM.begin(4096);
  Serial.begin(115200);
  secondTick.attach(1, ISRwatchdog); //registering the watchdog ISR
  pinMode(PIN_BUZZER, OUTPUT);

  int prevFreq = EEPROM.read(EEPROM_Addr); // read previous frequency
  if (prevFreq != 255){
    Serial.println("Previous frequency found : ");
    Serial.println(prevFreq);
    analogWrite(PIN_BUZZER, 256);
    analogWriteFreq(prevFreq);
    delay(1000);
  }
}

void loop() {
  Serial.print("Watchdog counter = ");
  Serial.println(watchdogCount);
  watchdogCount = 0;

  int freq = freqs[random(0, 11)];
  Serial.print("Frequency: ");
  Serial.println(freq);
  Serial.println("Saving to EEPROM");
  EEPROM.write(EEPROM_Addr, freq);
  EEPROM.commit();

  // generating 50% PWM
  analogWrite(PIN_BUZZER, 256);
  analogWriteFreq(freq);

  //depending on the value of delay, the program may wake up the watchdog
  int delayTime = random(1, 5) * 1000;
  Serial.print("Delay time: ");
  Serial.println(delayTime);
  delay(delayTime);
}
在此情况下,先前的频率不正确

在这个输出片段中

Watchdog counter = 1
Frequency: 784
Saving to EEPROM
Delay time: 4000
Watchdog counter = 4
Frequency: 1976
Saving to EEPROM
Delay time: 1000

 ets Jan  8 2013,rst cause:2, boot mode:(3,0)

load 0x4010f000, len 1384, room 16 
tail 8
chksum 0x2d
csum 0x2d
v09f0c112
~ld
Previous frequency found : 
184

在某些情况下,我的输出是正确的,但这种情况很少见。

ESP8266的EEPROM库只存储一个字节。这意味着它不能存储超过255的值——返回的值是存储值的最低有效字节(即,
freq%256

考虑在数组中存储值的索引,而不是值本身,例如

uint8_t idx = random(0, 11);
int freq = freqs[idx];
...
EEPROM.write(EEPROM_addr, idx);


fwiw,这正是我从EEPROM转向SPIFFS的原因;文件界面直观且无限制。
uint8_t idx = random(0, 11);
int freq = freqs[idx];
...
EEPROM.write(EEPROM_addr, idx);
uint8_t idx = EEPROM.read(EEPROM_addr);
int freq = freqs[idx];