2017-02-28 97 views
1

我正在使用Arduino IDE編程ESP8266板。讀取/寫入EEPROM - 值不正確

這個想法是隨機播放隨機時間的聲音,並保存最後播放的頻率到EEPROM。然後,如果延遲時間爲4秒或更長,我有一個看門狗ISR,可以重新啓動電路板。發生這種情況並且電路板重新啓動時,我想要播放上次播放的頻率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 

有些情況下,我的輸出是正確的,但是這是罕見的。

回答

2

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]; 
+0

FWIW,這正是爲什麼我移動從EEPROM到SPIFFS;該文件界面直觀且無限。 – dandavis