цифровая электроника
вычислительная техника
встраиваемые системы

 
» » » ESP32 и Flash память: записываем, храним и читаем постоянную информацию



ESP32 и Flash память: записываем, храним и читаем постоянную информацию

Автор: Mike(admin) от 27-12-2018, 11:05

В этой статье мы покажем вам, как хранить и считывать значения из флэш-памяти (Flash) ESP32 с помощью кода, написанного в Arduino IDE. Данные, сохраненные во флэш-памяти, остаются там даже после сброса ESP32 или при отключении питания. В качестве примера мы покажем вам, как сохранить последнее состояние линии ввода/вывода (GPIO).


ESP32 и Flash память

Данные, сохраненные во флэш-памяти, остаются там даже после сброса ESP32 или при отключении питания. Флэш-память очень похожа на EEPROM. Обе они являются энергонезависимыми типами памяти.


Сохранение данных во флэш-памяти особенно полезно для:


  1. запоминания последнего состояния переменной;
  2. сохранения настроек;
  3. сохранения значения того, сколько раз устройство было активировано;
  4. или для любого другого типа данных, которые вам нужно хранить постоянно.

Для чтения и записи с флэш-памяти ESP32 с применением Arduino IDE мы будем использовать библиотеку EEPROM. Использование этой библиотеки с ESP32 очень похоже на использование ее с Arduino. Так что, если вы применяли библиотеку EEPROM для Arduino раньше, то это не сильно отличается. С ESP32 и библиотекой EEPROM вы можете использовать до 512 байт во флэш-памяти. Это означает, что у вас есть 512 разных адресов, и вы можете сохранить значение от 0 до 255 в каждой позиции адреса.


Давайте сначала разберемся с записью во Flash. Чтобы записать данные во флэш-память, нужно использовать функцию EEPROM.write(), которая принимает в качестве аргументов местоположение или адрес, где вы хотите сохранить данные, и значение (байтовую переменную), которое вы хотите сохранить. То есть EEPROM.write(address, value).
Например, чтобы написать 9 по адресу 0, нужно ввести EEPROM.write(0, 9). Затем, чтобы данные были сохранены, следует ввести EEPROM.commit().


Теперь, чтобы прочитать байт из флэш-памяти, нужно использовать функцию EEPROM.read(). Эта функция принимает в качестве аргумента адрес байта, который вы хотите прочитать. Например, чтобы прочитать байт, сохраненный ранее в адресе 0, введите EEPROM.read(0). Эта функция вернет 9, которое является значением, которое мы сохранили в адресе 0.


Чтобы показать вам, как сохранять данные во флэш-памяти ESP32, мы сохраним последнее состояние выхода, в данном случае выхода на светодиод. Например, представьте следующий сценарий. Вы управляете лампой с ESP32, вы включаете свою лампу, но неожиданно ESP32 теряет питание. Когда питание снова включается, лампа остается выключенной - потому что она не сохраняет свое последнее состояние.


ESP32 и Flash память

Вы не хотите, чтобы это произошло. Вы хотите, чтобы ESP32 запомнил, что происходило до потери питания, и вернулся в последнее состояние. Чтобы решить эту проблему, вы можете сохранить состояние лампы во флэш-памяти. Затем вам просто нужно добавить условие в начале вашего кода, чтобы проверить последнее состояние лампы, и соответственно включить или выключить лампу.


ESP32 и Flash память

Далее показана схема подключения ESP32 и светодиода, состояние которого будет определяться из Flash.


ESP32 и Flash память

Теперь приведем комментированный код программы для работы с флэш-памятью ESP32.



// включить библиотеку для чтения и записи из/во флэш-память
#include <EEPROM.h>

// определите количество байтов, к которым вы хотите получить доступ
#define EEPROM_SIZE 1

// константы не изменятся. Они используются здесь, чтобы установить номера контактов
const int buttonPin = 4;    // номер вывода на кнопку
const int ledPin = 16;      // номер светодиодного вывода

// Variables will change:
int ledState = HIGH;         // екущее состояние выходного контакта
int buttonState;             // текущее считывание состояния входного контакта
int lastButtonState = LOW;   // предыдущее считывание состояния входного контакта

// следующие переменные являются беззнаковыми long, потому что время, измеренное
// в миллисекундах, быстро станет большим числом, чем может быть сохранено в int.
unsigned long lastDebounceTime = 0;  // последний раз выходной контакт был переключен
unsigned long debounceDelay = 50;    // время дребезга; увеличить, если выходной сигнал мигает

void setup() { 
  Serial.begin(115200);
  
  // инициализировать EEPROM с предопределенным размером
  EEPROM.begin(EEPROM_SIZE);

  pinMode(buttonPin, INPUT);
  pinMode(ledPin, OUTPUT);

  // прочитать последнее состояние светодиода из флэш-памяти
  ledState = EEPROM.read(0);
  // установить светодиод в последнее сохраненное состояние
  digitalWrite(ledPin, ledState);
}

void loop() {
  // прочитать состояние кнопки и записать в локальную переменную
  int reading = digitalRead(buttonPin);

  // Если переключатель изменился из-за шума или нажатия
  if (reading != lastButtonState) {
    // сбросить таймер дребезга
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {

    // если состояние кнопки изменилось
    if (reading != buttonState) {
      buttonState = reading;

      // переключать светодиод только в том случае, если новое состояние кнопки HIGH
      if (buttonState == HIGH) {
        ledState = !ledState;
      }
    }
  }
  // сохранить значение считывания. В следующий раз в цикле это будет lastButtonState
  lastButtonState = reading;
  
  // если переменная ledState отличается от текущего состояния светодиода
  if (digitalRead(ledPin)!= ledState) {  
    Serial.println("State changed");
    // изменить состояние светодиода
    digitalWrite(ledPin, ledState);
    // сохранить состояние светодиода во флэш-памяти
    EEPROM.write(0, ledState);
    EEPROM.commit();
    Serial.println("State saved in flash memory");
  }
}



© digitrode.ru


Теги: ESP32




Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь.
Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.

Комментарии:

Оставить комментарий
Цитата
  • Павел

  • 30 марта 2020 23:04
  • Группа: Гости
  • ICQ:
  • Регистрация: --
  • Статус:
  • Комментариев: 0
  • Публикаций: 0
^
В скетче ошибка ledState = EEPROM.read(0); должно быть не 0,а 1. Иначе при сбросе постоянно меняется состояние светодиода.Да и ещё на данной плате уже есть кнопка (пин 0) и светодиод (пин 2).

для работы штатной кнопки надо изменить значения int lastButtonState = HIGH;
if (buttonState == LOW)

на данной плате уже есть кнопка (пин 0) и светодиод (пин 2).

для работы штатной кнопки надо изменить значения int lastButtonState = HIGH;
if (buttonState == LOW)[/quote]
Цитата
  • Вольдемар

  • 12 апреля 2023 17:56
  • Группа: Гости
  • ICQ:
  • Регистрация: --
  • Статус:
  • Комментариев: 0
  • Публикаций: 0
^
Изменил код и у меня все заработало на Node MCU.
// включить библиотеку для чтения и записи из/во флэш-память
#include <EEPROM.h>
// определите количество байтов, к которым вы хотите получить доступ
#define EEPROM_SIZE 1

// константы не изменятся. Они используются здесь, чтобы установить номера контактов
const int buttonPin = D3; // номер вывода на кнопку
const int ledPin = D7; // номер светодиодного вывода

// Variables will change:
int ledState = LOW; // екущее состояние выходного контакта
int buttonState; // текущее считывание состояния входного контакта
int lastButtonState = HIGH; // предыдущее считывание состояния входного контакта

// следующие переменные являются беззнаковыми long, потому что время, измеренное
// в миллисекундах, быстро станет большим числом, чем может быть сохранено в int.
unsigned long lastTime = 0; // последний раз выходной контакт был переключен
unsigned long Delay = 50; // время дребезга; увеличить, если выходной сигнал мигает
void setup() {
Serial.begin(115200);

// инициализировать EEPROM с предопределенным размером
EEPROM.begin(EEPROM_SIZE);
pinMode(buttonPin, INPUT_PULLUP);
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, ledState);
ledState =EEPROM.read(0);
digitalWrite(ledPin, ledState);
}

void loop() {
// прочитать состояние кнопки и записать в локальную переменную
int reading = digitalRead(buttonPin);

// Если переключатель изменился из-за шума или нажатия
if (reading != lastButtonState) {
// сбросить таймер дребезга
lastTime = millis();
}

if ((millis() - lastTime) > Delay) {

// если состояние кнопки изменилось
if (reading != buttonState) {
buttonState = reading;

// переключать светодиод только в том случае, если новое состояние кнопки HIGH
if (buttonState == LOW) {
ledState = !ledState;
}
}
}
// сохранить значение считывания. В следующий раз в цикле это будет lastButtonState
lastButtonState = reading;

// если переменная ledState отличается от текущего состояния светодиода
if (digitalRead(ledPin)!= ledState) {
Serial.println("State changed");
// изменить состояние светодиода
digitalWrite(ledPin, ledState);
// сохранить состояние светодиода во флэш-памяти
EEPROM.write(0, ledState);
EEPROM.commit();
Serial.println("State saved in flash memory");
}
}