Нужна помощь с EEPROM, не сохраняющим значения массива на ESP8266 после перезапуска
У меня проблемы с программой. Я пытаюсь сохранить загруженную строку в массив, а затем записать этот массив в EEPROM. Я запускаю программу, загружаю новый массив и сохраняю его в EEPROM. все значения отображаются правильно, пока я не перезагрузлю или не выключу устройство. Я уверен, что перезаписываю или что-то очевидное, но я ломаюсь и прошу помощи.
Подпрограммы чтения и записи EEPROM находятся в нижней части кода. Я вызываю EEPROM_Write() в server.on после разбора http get.
EDIT: по отзывам удалено все, кроме функции, с помощью EEPROM.commit(); предложение включено... все еще не работает
void EEPROM_Write(){
Serial.begin(115200);
EEPROM.begin(280);
// сохраняем значения в EEPROM
for (int i = 0; i < pwmarray1Size; i++)
{
Serial.println(pwmarray1[i]);
EEPROM.put( EEPROMStartAdress + (i * sizeof pwmarray1[0]), pwmarray1[i]);
}
Serial.println();
EEPROM.commit();
// EEPROM.end();
}
@deathrace2020, 👍1
Обсуждение1 ответ
У ESP нет настоящей EEPROM. Вместо этого класс EEPROM
для ESP использует флэш-память. Существует разница в реализации этого класса между Arduino и ESP:
В ESP все данные, которые вы записываете, сначала помещаются в буфер в оперативной памяти. Вам нужно вызвать EEPROM.commit()
, чтобы фактически записать эти данные в базовую флэш-память.
Поэтому вам нужно добавить
EEPROM.commit();
до конца вашей функции EEPROM_Write()
, иначе данные останутся в ОЗУ и, таким образом, будут потеряны при выключении питания или сбросе.
Я думаю, что ваша проблема (помимо фиксации) заключается не в вашей функции EEPROM_Write()
, а в функции EEPROM_Read()
. Если это работает неправильно, вы просто не сможете увидеть, правильно ли записываются данные. В вашем коде (который можно увидеть в истории редактирования) у вас есть эта функция:
void EEPROM_Read(){
//загружаем массив pwmarray1 с сохраненными значениями в EPROM
for (int x = 0; x < pwmarray1Size; x++){
EEPROM.get(EEPROMStartAdress + (x * sizeof pwmarray1[0]), pwmarray1[x]);
Serial.print("loading program from EPROM: ");
Serial.println(pwmarray1[x]);
}
}
Хотя в EEPROM_Write()
вы вызываете EEPROM.begin(280)
каждый раз, вы не EEPROM.end()
это там, и вы также не начинаете EEPROM в функции EEPROM_Read()
. Я не уверен в базовой реализации, но у меня она начала работать, когда я начал и закончил объект EEPROM
в обеих функциях.
Я написал тестовый код, который я составил из вашего кода и который для меня правильно сохраняет и читает массив через объект EEPROM
во флэш-память. Он правильно сохраняет данные при сбросах и циклах питания. Вы можете управлять им через Serial Monitor. Просто введите c
(для очистки массива до нуля), r
(для чтения массива из EEPROM/flash) или i
(для увеличения всех элементы массива и сохранить их в EEPROM/flash).
#include <EEPROM.h>
#define EEPROM_SIZE 280
int array[60] = {0};
const unsigned arraySize = sizeof array / sizeof array[0];
#define EEPROMStartAdress 0
void setup(){
Serial.begin(115200);
Serial.println("//////////////////////////////////////");
delay(2000);
}
void loop(){
if(Serial.available()){
char c = Serial.read();
switch(c){
case 'c':
for(uint8_t i=0;i<arraySize;i++) array[i] = 0;
EEPROM_Write();
Serial.println("EEPROM RESET");
break;
case 'r':
EEPROM_Read();
break;
case 'i':
for(uint8_t i=0;i<arraySize;i++) array[i] += 1;
EEPROM_Write();
break;
}
}
}
void EEPROM_Write(){
EEPROM.begin(EEPROM_SIZE);
// сохраняем значения в EEPROM
for (int i = 0; i < arraySize; i++)
{
EEPROM.put( EEPROMStartAdress + (i * sizeof array[0]), array[i]);
}
EEPROM.commit();
EEPROM.end();
}
void EEPROM_Read(){
EEPROM.begin(EEPROM_SIZE);
for (int x = 0; x < arraySize; x++){
EEPROM.get(EEPROMStartAdress + (x * sizeof array[0]), array[x]);
Serial.print(" ");
Serial.print(array[x]);
}
Serial.println();
EEPROM.end();
}
Удаление begin()
и end()
из EEPROM_Read()
, а также end()
из EEPROM_Write()
дает мне те же результаты, которые вы описали как свою проблему.
этикетки вводят в заблуждение. Я использую «положить» и «получить». могу ли я использовать EEPROM.commit() после установки?, @deathrace2020
put и get - это просто оболочки для записи и чтения, которые помогают вам записывать более сложные данные, чем отдельные байты. На заднем фоне происходит то же самое. Так что да, вы можете использовать EEPROM.commit()
после EEPROM.put()
., @chrisl
Я добавил EEPROM.commit() и до сих пор не получаю значения, хранящиеся в EEPROM. Знаете ли вы, влияет ли расположение «EEPROMStartAdress»?, @deathrace2020
хорошо, я потратил 30 часов, глядя и пытаясь заставить эту работу работать безрезультатно. я проанализировал тест до одного числа. разместил новый вопрос здесь: https://stackoverflow.com/questions/62415395/eps8266-writing-number-to-eeprom-fails-to-write-returns- 0?fbclid=IwAR1QxJ_EXw8jqKaiLLNoDsChW2l0CpGUlQcm Tu3WrKaijchN4qc_8Mn5quo, @deathrace2020
В настоящее время я работаю над тестовым скетчем, но на данный момент моя функция your работает с моим ESP32. Я сделаю минимальный работающий тестовый скетч, который вы сможете протестировать на своей плате. Может быть, я смогу сделать это завтра вечером. EEPROMStartAdress
просто сообщает функции, с чего начать запись в выделенном EEPROM. Не должно быть проблемой., @chrisl
если EEPROMStartAdress больше, чем выделенный размер, @Juraj
@deathrace2020 Теперь я смог точно воспроизвести и получить исправление. Я добавил решение, а также тестовый скетч, который я использовал, к ответу., @chrisl
вы можете записать весь массив одним вводом и прочитать его одним получением. `end' вызывает 'commit', @Juraj
- Как читать и записывать EEPROM в ESP8266
- Как добавить в массив из String в ардуино?
- Spiffs против Eeprom на esp8266
- В ESP8266 EEPROM сохраненные данные отличаются, когда я пытаюсь их прочитать
- Значение неинициализированной EEPROM в ESP8266
- Wemos D1 EEProm put/get не получает правильное значение
- Как отправить int массив с запросом ESP8266 http post?
- Как отсортировать строку с числом по возрастанию
что такое EEPROMStartAdress? вы можете поместить весь массив в EEPROM одним «путем», @Juraj