Память ESP8266 RTC (для загрузки)

Я использую ESP8266 с режимом глубокого сна + пробуждения, когда контакт RST становится низким.

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266HTTPClient.h>
WiFiClient client;
HTTPClient http;
RTC_DATA_ATTR int bootcount = 0;

void setup() {
    bootcount ++;
    WiFi.begin("MySSID", "password");
    while (WiFi.status() != WL_CONNECTED) {
        delay(20);
    }
    // здесь я посылаю "bootcount" с HTTP-запросом
    ESP.deepSleep(0);
}
void loop() {
}

Здесь RTC_DATA_ATTR int bootcount = 0; происходит сбой с неизвестным RTC_DATA_ATTR.

Как узнать, сколько раз ESP8266 выходил из глубокого сна?

, 👍1

Обсуждение

RTC_DATA_ATTR для esp32, @Juraj

Спасибо @Juraj, вы правы, я думаю, вы можете опубликовать это как ответ. Означает ли это, что невозможно подсчитать, сколько раз ESP8266 возобновлял/перезагружался из глубокого сна? Как сохранить/восстановить номер в памяти RTC?, @Basj


1 ответ


5

ESP8266 RTC имеет 512 байт ОЗУ, которые сохраняются при перезапуске, но не при отключении питания. Хотя эта оперативная память не сохраняется при перебоях в подаче электроэнергии, она также не имеет ограничений на запись, которые есть у флэш-памяти, что делает ее подходящей для частых операций записи, которые не должны пережить сбой питания.

Компилятор и программная среда ESP32 упрощают доступ к аналогичной памяти с помощью атрибута RTC_DATA_ATTR; к сожалению, как вы обнаружили и указал @Juraj, ESP8266 этого не делает.

К счастью, ядро Arduino для ESP8266 включает поддержку чтения и записи этой области памяти с использованием методов объекта ESP.

ESP.rtcUserMemoryRead() считывает память RTC, а ESP.rtcUserMemoryWrite() записывает память RTC. В вашем случае вы можете сделать что-то вроде этого:

void setup() {
  uint32_t bootcount;

  if(!ESP.rtcUserMemoryRead(0, &bootcount, sizeof(bootcount))) {
    Serial.println("RTC read failed!");
    while(1)
      yield();
  }

  bootcount++;

  if(!ESP.rtcUserMemoryWrite(0, &bootcount, sizeof(bootcount))) {
    Serial.println("RTC write failed!");
    while(1)
      yield();
  }

  Serial.begin(115200);
  Serial.print("boot count is ");
  Serial.println(bootcount);
}

void loop() {
}

Не так удобно, как атрибут RTC_DATA_ATTR, но он по-прежнему выполняет свою работу.

Я изменил тип bootcount из вашего примера на uint32_t, потому что он никогда не должен быть отрицательным, а размер uint32_t не зависит от размер int.

Поскольку ядро Arduino имеет открытый исходный код, вы можете ознакомиться с реализацией этих функции, если вы хотите знать, как они работают.

,