Reading/writing 到 EEPROM - 不正确的值
Reading/writing to EEPROM - incorrect values
我正在使用 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);
}
我面临的问题是值要么被错误地写入 EEPROM,要么被错误地读取。例如,这是我得到的一些输出,
Watchdog counter = 2
Frequency: 31
Saving to EEPROM
Delay time: 3000
Watchdog counter = 3
Frequency: 1245
Saving to EEPROM
Delay time: 4000
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 :
221
在这种情况下之前的频率不正确。
再次在此输出片段中,
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);
和
uint8_t idx = EEPROM.read(EEPROM_addr);
int freq = freqs[idx];
我正在使用 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);
}
我面临的问题是值要么被错误地写入 EEPROM,要么被错误地读取。例如,这是我得到的一些输出,
Watchdog counter = 2
Frequency: 31
Saving to EEPROM
Delay time: 3000
Watchdog counter = 3
Frequency: 1245
Saving to EEPROM
Delay time: 4000
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 :
221
在这种情况下之前的频率不正确。
再次在此输出片段中,
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);
和
uint8_t idx = EEPROM.read(EEPROM_addr);
int freq = freqs[idx];