Wemos D1 EEProm put/get не получает правильное значение

Привет всем! У меня в Arduino IDE есть следующий код:

#include <EEPROM.h>
#include <ArduinoJson.h>

bool debuggin         = true;
int brightness        = 255;
int ambientLight      = 30;
struct RGBLA {
  uint8_t R;
  uint8_t G;
  uint8_t B;
  uint8_t L;
  uint8_t A;
};

void setup() {
  Serial.begin(9600);

  while (!Serial) {
    ; // ждем подключения последовательного порта. Требуется только для Leonardo
  }

  EEPROM.begin(512);
  readSavedSettings();
  updateEEProm(255,255,255,200,35,true,false);
}

RGBLA readEEProm() {
  int addr = 0;
  RGBLA customVars;

  EEPROM.get(addr, customVars);
  return customVars;
}

void readSavedSettings() {
  RGBLA returnedVars = readEEProm();
  if (debuggin) { Serial.println("START readSavedSettings"); }

  if (returnedVars.A == 00 || returnedVars.A == 0) {
    if (debuggin) { Serial.println("'A' not found! Default 30"); }
  } else {
    ambientLight = returnedVars.A;
    if (debuggin) {
      Serial.print("'A' found! ");
      Serial.println(ambientLight);
    }
  }

  for(uint8_t i = 0; i < 3/*strip.numPixels()*/; i++) {
    if (debuggin) {
      Serial.print("LED ");
      Serial.print(i);
      Serial.print(" set to: R: ");
      Serial.print((uint8_t)returnedVars.R);
      Serial.print(", G: ");
      Serial.print((uint8_t)returnedVars.G);
      Serial.print(", B: ");
      Serial.println((uint8_t)returnedVars.B);
    }
  }

  if (debuggin) {
    Serial.println("Turned off RGB LEDS");
    Serial.println("END readSavedSettings");
  }
}

void updateEEProm(uint8_t R, 
                  uint8_t G, 
                  uint8_t B, 
                  uint8_t L, 
                  uint8_t A, 
                  bool saveRGBL,
                  bool saveA) {
  int addr = 0;
  RGBLA customVars;

  //Сохраняем старый json перед очисткой EEProm
  EEPROM.get(addr, customVars);

  //Очистить EEProm
  for (unsigned int i = 0; i < EEPROM.length(); i++) {
    EEPROM.write(i, 0);
  }

  if (saveRGBL) {
    //Получаем значение A, чтобы мы могли сохранить его как то же самое значение
    DynamicJsonBuffer jsonBuffer(JSON_OBJECT_SIZE(5));
    JsonObject& root = jsonBuffer.createObject();

    if (debuggin) {
      Serial.print("Old JSON:");
      Serial.print(" R: ");
      Serial.print((uint8_t)customVars.R);
      Serial.print(" G: ");
      Serial.print((uint8_t)customVars.G);
      Serial.print(" B: ");
      Serial.print((uint8_t)customVars.B);
      Serial.print(" L: ");
      Serial.print((uint8_t)customVars.L);
      Serial.print(" A: ");
      Serial.println((uint8_t)customVars.A);
    }

    root["R"] = (uint8_t)R;
    root["G"] = (uint8_t)G;
    root["B"] = (uint8_t)B;
    root["L"] = (uint8_t)L;
    root["A"] = (uint8_t)customVars.A;

    if (debuggin) {
      Serial.print("New JSON:");
      Serial.print(" R: ");
      Serial.print((uint8_t)root["R"]);
      Serial.print(" G: ");
      Serial.print((uint8_t)root["G"]);
      Serial.print(" B: ");
      Serial.print((uint8_t)root["B"]);
      Serial.print(" L: ");
      Serial.print((uint8_t)root["L"]);
      Serial.print(" A: ");
      Serial.println((uint8_t)root["A"]);
    }

    EEPROM.put(addr, root);
  }

  if (saveA) {
    //Получаем значения R,G,B,L, чтобы сохранить их в том же значении
    DynamicJsonBuffer jsonBuffer(JSON_OBJECT_SIZE(5));
    JsonObject& root = jsonBuffer.createObject();

    if (debuggin) {
      Serial.print("Old JSON:");
      Serial.print(" R: ");
      Serial.print((uint8_t)customVars.R);
      Serial.print(" G: ");
      Serial.print((uint8_t)customVars.G);
      Serial.print(" B: ");
      Serial.print((uint8_t)customVars.B);
      Serial.print(" L: ");
      Serial.print((uint8_t)customVars.L);
      Serial.print(" A: ");
      Serial.println((uint8_t)customVars.A);
    }

    root["R"] = (uint8_t)customVars.R;
    root["G"] = (uint8_t)customVars.G;
    root["B"] = (uint8_t)customVars.B;
    root["L"] = (uint8_t)customVars.L;
    root["A"] = (uint8_t)A;

    if (debuggin) {
      Serial.print("New JSON:");
      Serial.print(" R: ");
      Serial.print((uint8_t)root["R"]);
      Serial.print(" G: ");
      Serial.print((uint8_t)root["G"]);
      Serial.print(" B: ");
      Serial.print((uint8_t)root["B"]);
      Serial.print(" L: ");
      Serial.print((uint8_t)root["L"]);
      Serial.print(" A: ");
      Serial.println((uint8_t)root["A"]);
    }

    EEPROM.put(addr, root);
  }
}

void loop() {
}

И вот результат этого кода:

START readSavedSettings
'A' found! 96
LED 0 set to: R: 48, G: 255, B: 255
LED 1 set to: R: 48, G: 255, B: 255
LED 2 set to: R: 48, G: 255, B: 255
Turned off RGB LEDS
END readSavedSettings
Old JSON: R: 48   G: 255 B: 255 L: 63   A: 96
New JSON: R: 255  G: 255 B: 255 L: 200  A: 96
Old JSON: R: 48   G: 255 B: 255 L: 63   A: 160
New JSON: R: 48   G: 255 B: 255 L: 63   A: 35

Теперь, когда я его сбрасываю, вот что выводится:

⸮dOX⸮,R⸮X⸮4xC⸮⸮⸮START readSavedSettings
'A' found! 96
LED 0 set to: R: 48, G: 255, B: 255
LED 1 set to: R: 48, G: 255, B: 255
LED 2 set to: R: 48, G: 255, B: 255
Turned off RGB LEDS
END readSavedSettings
Old JSON: R: 48   G: 255 B: 255 L: 63   A: 96
New JSON: R: 255  G: 255 B: 255 L: 200  A: 96
Old JSON: R: 48   G: 255 B: 255 L: 63   A: 160
New JSON: R: 48   G: 255 B: 255 L: 63   A: 35

Почему в старом JSON снова есть значение 'L', равное 63, когда должно быть значение нового JSON, равное 200? Почему он не сохранил его, но сохранил все остальные? Кроме того, почему 'R' 48, когда должно быть 255, как G и B?

Что-то не так в моем коде?

Обновление 1

Вот что получится после добавления к нему .end():

START readSavedSettings
'A' found! 160
LED 0 set to: R: 48, G: 255, B: 255
LED 1 set to: R: 48, G: 255, B: 255
LED 2 set to: R: 48, G: 255, B: 255
Turned off RGB LEDS
END readSavedSettings
Old JSON: R: 48   G: 255  B: 255  L: 63 A: 160
New JSON: R: 255  G: 255  B: 255  L: 200 A: 160
Old JSON: R: 128  G: 12   B: 17   L: 17 A: 60
New JSON: R: 128  G: 12   B: 17   L: 17 A: 35

и код, который я использую:

void setup() {
  // инициализируем последовательный порт и ждем открытия порта:
  Serial.begin(9600);
  while (!Serial) {
    ; // ждем подключения последовательного порта. Требуется только для Leonardo
  }

  EEPROM.begin(512);
  readSavedSettings();
  updateEEProm(255,255,255,200,35,true,false); //Сохраняем все значения, кроме «A»
  EEPROM.end();
  updateEEProm(255,255,255,200,35,false,true); //Сохраняем только значение 'A'
  EEPROM.end();
}

, 👍0

Обсуждение

вам следует попробовать SPIFFS вместо EEPROM: интерфейс ez-файла, 1-3 МБ места, не требуется нарезка или разделители..., @dandavis

@dandavis, правда. У библиотеки эмуляции есть одно небольшое преимущество. Она не стирается при загрузке образа SPIFFS., @Juraj

Почему вы помещаете Json root в EEPROM в конце updateEEProm?, @Juraj

@Juraj, ты имеешь в виду часть **.put()**?, @StealthRT

вы читаете структуру RGBLA, но записываете json в EEPROM. что не подходит для EEPROM, @Juraj

@Juraj использование **.put()** делает его совместимым со строками, в которых находится JSON., @StealthRT

вы пишете в EEPROM root, а не customVars. но вы читаете customVars, а не json, @Juraj

@Juraj customVars собирает то, что в данный момент находится в EEProm. Затем я сохраняю переданные значения R,G,B,L и помещаю их в корневую структуру, а затем сохраняю как новые данные для EEProm., @StealthRT

root не является структурой. Это класс для обработки JSON. Его нельзя сохранить в EEPROM. А если бы и можно, его нельзя было бы прочитать в RGBLA., @Juraj


1 ответ


2

Библиотека эмуляции EEPROM esp8266 требует вызова commit() для сохранения образа памяти EEPROM во флэш-памяти.

Добавьте EEPROM.commit(); или EEPROM.end(); в качестве последней строки в вашей функции updateEEProm(). Ссылка на документацию:

Вторая проблема в том, что вы не записываете структуру RGBLA в EEPROM, вместо этого вы пытаетесь записать переменную root, которая является экземпляром класса JsonObject. Типы классов не могут быть помещены в EEPROM.

,

То есть это работает даже при использовании **.put()**?, @StealthRT

конечно. все функции эмуляции работают с образом ОЗУ эмулируемой EEPROM. commit() или end() записывает образ во флэш-память. begin() считывает образ из флэш-памяти в ОЗУ., @Juraj

Хм, даже выполнение **updateEEProm(255,255,255,200,35,true,false); EEPROM.commit(); updateEEProm(255,255,255,200,35,false,true); EEPROM.commit();**, похоже, все равно не сохраняет его?, @StealthRT