带 ESP32-WROOM-32 的 EEPROM
EEPROM with ESP32-WROOM-32
Arduino 和 ESP-32 初学者需要帮助。
我买了一个 ESP32-WROOM-32,我意识到与 Arduino Nano、UNO 或 Mega 相比,有些东西是不一样的。
我意识到不同之处之一是如何从控制器存储和读取数据。
我想将一些数据保存到 EEPROM,即使在设备关闭时也能保留该值。
我有以下代码,我一直在我的小项目中使用 Arduino 板。该代码包括创建一个 Oled 菜单,我可以在其中导航真实页面并更改 Int 值,并且该值存储在 EEprom 中。
我上传到 esp32 的相同代码没有任何问题,菜单工作正常。我可以更改 Int 值。问题是切换 OFF/ON 板后,值不持久。
我已经在互联网上寻找一些关于 EEprom 和 ESP32 的教程并尝试实现它,但不幸的是没有结果。
#include <EEPROM.h>
#include <OneButton.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define DISP_RESET -1
const char*Vartext[] {"Data_0", "Data_1", "Data_2"};
const byte maxAnz = sizeof(Vartext) / sizeof(Vartext[0]);
const int mindata[maxAnz] {0, 0, 0};
const int maxdata[maxAnz] {10000, 200, 300};
uint32_t longstart;
byte Varindex;
byte Page = 0;
bool input;
bool changed;
bool datachanged ;
// data in struct to save on EEprom
struct mydaten {
int VarData[maxAnz];
} mydata;
const byte pinsel = 16; // select Button
const byte pinplus = 4; // Plus Button
const byte pinminus = 5; // Minus Button
OneButton Btnsel(pinsel, true);
OneButton Btnplus(pinplus, true);
OneButton Btnminus(pinminus, true);
Adafruit_SSD1306 DISP(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, DISP_RESET);
void setup() {
Serial.begin(115200);
EEPROM.get(0, mydata); // Read Data from EEPROM
for (byte i = 0; i < maxAnz; i++) {
checkminmax();
}
changed = true;
Btnsel.attachClick(selClick);
Btnsel.attachDoubleClick(selDblClick);
Btnplus.attachClick(plusClick);
Btnplus.attachDuringLongPress(plusDurPress);
Btnplus.attachLongPressStart(LongStart);
Btnminus.attachClick(minusClick);
Btnminus.attachDuringLongPress(minusDurPress);
Btnminus.attachLongPressStart(LongStart);
DISP.begin(SSD1306_SWITCHCAPVCC, 0x3C);
DISP.clearDisplay();
DISP.setTextWrap(false);
DISP.setTextSize(2);
DISP.setTextColor(WHITE);
DISP.setCursor(20, 30); DISP.print(F("Menu"));
DISP.setTextSize(2);
DISP.display();
delay(2000);
}
//--------------------------------------
void loop() {
Btnsel.tick();
Btnplus.tick();
Btnminus.tick();
if (input)Displayinput();
else Display(Page);
}
//--------------------------------------
void saveEEprom() {
if (datachanged) {
datachanged = false;
#ifdef debug
Serial.println("Save in EEprom");
#endif
EEPROM.put(0, mydata);
}
}
//--------------------------------------
void selClick() {
changed = true;
if (input) {
Varindex++;
if (Varindex >= maxAnz) Varindex = 0;
}
else {
Page++;
if (Page >= 3) Page = 0;
}
}
//--------------------------------------
void selDblClick() {
if (input) saveEEprom();
input = !input;
changed = true;
}
void plusClick() {
click(1);
}
void minusClick() {
click(-1);
}
void plusDurPress() {
longclick(1);
}
void minusDurPress() {
longclick(-1);
}
void LongStart() {
longstart = millis();
}
void click(int inc) {
if (input) {
changed = true;
datachanged = true;
mydata.VarData[Varindex] += inc;
checkminmax();
}
}
void longclick(int direction) {
static uint32_t oldtime;
int inc = 10;
if (millis() - longstart > 5000) inc = 100;
if (millis() - oldtime >= 100 && input) {
oldtime = millis();
changed = true;
datachanged = true;
mydata.VarData[Varindex] += inc * direction;
checkminmax();
}
}
void checkminmax() {
if (mydata.VarData[Varindex] < mindata[Varindex]) {
mydata.VarData[Varindex] = mindata[Varindex];
}
if (mydata.VarData[Varindex] > maxdata[Varindex]) {
mydata.VarData[Varindex] = maxdata[Varindex];
}
}
void Displayinput() { // Display bei input
if (changed ) {
changed = false;
DISP.clearDisplay();
DISP.setTextSize(2);
DISP.setCursor(0, 0); DISP.print("input");
DISP.setCursor(0, 20); DISP.print(Vartext[Varindex]);
DISP.setCursor(10, 40); DISP.print(mydata.VarData[Varindex]);
DISP.display();
}
}
void Display(byte Page) {
if (changed) {
changed = false;
DISP.clearDisplay();
if (Page == 0) {
DISP.setTextSize(1);
DISP.setCursor(0, 0);
DISP.print("variable Value");
for (byte i = 0; i < maxAnz; i++) {
byte row = i * 10 + 10;
DISP.setCursor(0, row);
DISP.print(Vartext[i]);
DISP.setCursor(80, row );
DISP.print(mydata.VarData[i]);
}
}
else if (Page == 1) {
DISP.setTextSize(2);
DISP.setCursor(0, 0); DISP.print("Page 1");
}
else if (Page == 2) {
DISP.setTextSize(2);
DISP.setCursor(0, 0); DISP.print("Page 2");
}
DISP.display();
}
}
在此先感谢您的帮助
首先要知道的是,与 Arduino 不同,ESP32 没有 EEPROM。相反,它使用闪存来模拟它。 ESP32 的 EEPROM 库已弃用;新代码应该使用 Preferences library。如果需要,您还可以使用文件系统保存数据。
回答问题:
首先,您应该在程序开始时调用 EEPROM.begin()
。所以:
#define EEPROM_SIZE LARGEST_SIZE_YOU_MAY_EVER_USE
void setup() {
Serial.begin(115200);
EEPROM.begin(EEPROM_SIZE);
EEPROM.get(0, mydata); // Read Data from EEPROM
将 EEPROM_SIZE
设置为您需要的最大字节数。
然后在你写完之后你需要调用EEPROM.commit()
。所以:
void saveEEprom() {
if (datachanged) {
datachanged = false;
#ifdef debug
Serial.println("Save in EEprom");
#endif
EEPROM.put(0, mydata);
}
EEPROM.commit();
}
这使 EEPROM 库可以最大限度地减少写入闪存的次数,闪存的耐用性相当有限。如果你在 put
什么都没有的时候调用它,那么什么都不会发生。如果您不调用它,您 put
的数据将不会被保存。
您也可以通过查看 EEPROM library's examples.
自己找到答案
有一个非常好用的文件系统,叫做SPIFFS。
如果您使用的是 Arduino IDE,您会发现一个名为 SPIFFS_test 的示例程序。它非常简单明了,展示了如何打开文件、列出目录等。
文件->示例->ESP32 示例->SPIFFS->SPIFFS_test
函数及其使用方式与标准 C 文件系统函数非常相似,甚至可能相同。
Arduino 和 ESP-32 初学者需要帮助。
我买了一个 ESP32-WROOM-32,我意识到与 Arduino Nano、UNO 或 Mega 相比,有些东西是不一样的。 我意识到不同之处之一是如何从控制器存储和读取数据。 我想将一些数据保存到 EEPROM,即使在设备关闭时也能保留该值。
我有以下代码,我一直在我的小项目中使用 Arduino 板。该代码包括创建一个 Oled 菜单,我可以在其中导航真实页面并更改 Int 值,并且该值存储在 EEprom 中。
我上传到 esp32 的相同代码没有任何问题,菜单工作正常。我可以更改 Int 值。问题是切换 OFF/ON 板后,值不持久。
我已经在互联网上寻找一些关于 EEprom 和 ESP32 的教程并尝试实现它,但不幸的是没有结果。
#include <EEPROM.h>
#include <OneButton.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define DISP_RESET -1
const char*Vartext[] {"Data_0", "Data_1", "Data_2"};
const byte maxAnz = sizeof(Vartext) / sizeof(Vartext[0]);
const int mindata[maxAnz] {0, 0, 0};
const int maxdata[maxAnz] {10000, 200, 300};
uint32_t longstart;
byte Varindex;
byte Page = 0;
bool input;
bool changed;
bool datachanged ;
// data in struct to save on EEprom
struct mydaten {
int VarData[maxAnz];
} mydata;
const byte pinsel = 16; // select Button
const byte pinplus = 4; // Plus Button
const byte pinminus = 5; // Minus Button
OneButton Btnsel(pinsel, true);
OneButton Btnplus(pinplus, true);
OneButton Btnminus(pinminus, true);
Adafruit_SSD1306 DISP(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, DISP_RESET);
void setup() {
Serial.begin(115200);
EEPROM.get(0, mydata); // Read Data from EEPROM
for (byte i = 0; i < maxAnz; i++) {
checkminmax();
}
changed = true;
Btnsel.attachClick(selClick);
Btnsel.attachDoubleClick(selDblClick);
Btnplus.attachClick(plusClick);
Btnplus.attachDuringLongPress(plusDurPress);
Btnplus.attachLongPressStart(LongStart);
Btnminus.attachClick(minusClick);
Btnminus.attachDuringLongPress(minusDurPress);
Btnminus.attachLongPressStart(LongStart);
DISP.begin(SSD1306_SWITCHCAPVCC, 0x3C);
DISP.clearDisplay();
DISP.setTextWrap(false);
DISP.setTextSize(2);
DISP.setTextColor(WHITE);
DISP.setCursor(20, 30); DISP.print(F("Menu"));
DISP.setTextSize(2);
DISP.display();
delay(2000);
}
//--------------------------------------
void loop() {
Btnsel.tick();
Btnplus.tick();
Btnminus.tick();
if (input)Displayinput();
else Display(Page);
}
//--------------------------------------
void saveEEprom() {
if (datachanged) {
datachanged = false;
#ifdef debug
Serial.println("Save in EEprom");
#endif
EEPROM.put(0, mydata);
}
}
//--------------------------------------
void selClick() {
changed = true;
if (input) {
Varindex++;
if (Varindex >= maxAnz) Varindex = 0;
}
else {
Page++;
if (Page >= 3) Page = 0;
}
}
//--------------------------------------
void selDblClick() {
if (input) saveEEprom();
input = !input;
changed = true;
}
void plusClick() {
click(1);
}
void minusClick() {
click(-1);
}
void plusDurPress() {
longclick(1);
}
void minusDurPress() {
longclick(-1);
}
void LongStart() {
longstart = millis();
}
void click(int inc) {
if (input) {
changed = true;
datachanged = true;
mydata.VarData[Varindex] += inc;
checkminmax();
}
}
void longclick(int direction) {
static uint32_t oldtime;
int inc = 10;
if (millis() - longstart > 5000) inc = 100;
if (millis() - oldtime >= 100 && input) {
oldtime = millis();
changed = true;
datachanged = true;
mydata.VarData[Varindex] += inc * direction;
checkminmax();
}
}
void checkminmax() {
if (mydata.VarData[Varindex] < mindata[Varindex]) {
mydata.VarData[Varindex] = mindata[Varindex];
}
if (mydata.VarData[Varindex] > maxdata[Varindex]) {
mydata.VarData[Varindex] = maxdata[Varindex];
}
}
void Displayinput() { // Display bei input
if (changed ) {
changed = false;
DISP.clearDisplay();
DISP.setTextSize(2);
DISP.setCursor(0, 0); DISP.print("input");
DISP.setCursor(0, 20); DISP.print(Vartext[Varindex]);
DISP.setCursor(10, 40); DISP.print(mydata.VarData[Varindex]);
DISP.display();
}
}
void Display(byte Page) {
if (changed) {
changed = false;
DISP.clearDisplay();
if (Page == 0) {
DISP.setTextSize(1);
DISP.setCursor(0, 0);
DISP.print("variable Value");
for (byte i = 0; i < maxAnz; i++) {
byte row = i * 10 + 10;
DISP.setCursor(0, row);
DISP.print(Vartext[i]);
DISP.setCursor(80, row );
DISP.print(mydata.VarData[i]);
}
}
else if (Page == 1) {
DISP.setTextSize(2);
DISP.setCursor(0, 0); DISP.print("Page 1");
}
else if (Page == 2) {
DISP.setTextSize(2);
DISP.setCursor(0, 0); DISP.print("Page 2");
}
DISP.display();
}
}
在此先感谢您的帮助
首先要知道的是,与 Arduino 不同,ESP32 没有 EEPROM。相反,它使用闪存来模拟它。 ESP32 的 EEPROM 库已弃用;新代码应该使用 Preferences library。如果需要,您还可以使用文件系统保存数据。
回答问题:
首先,您应该在程序开始时调用 EEPROM.begin()
。所以:
#define EEPROM_SIZE LARGEST_SIZE_YOU_MAY_EVER_USE
void setup() {
Serial.begin(115200);
EEPROM.begin(EEPROM_SIZE);
EEPROM.get(0, mydata); // Read Data from EEPROM
将 EEPROM_SIZE
设置为您需要的最大字节数。
然后在你写完之后你需要调用EEPROM.commit()
。所以:
void saveEEprom() {
if (datachanged) {
datachanged = false;
#ifdef debug
Serial.println("Save in EEprom");
#endif
EEPROM.put(0, mydata);
}
EEPROM.commit();
}
这使 EEPROM 库可以最大限度地减少写入闪存的次数,闪存的耐用性相当有限。如果你在 put
什么都没有的时候调用它,那么什么都不会发生。如果您不调用它,您 put
的数据将不会被保存。
您也可以通过查看 EEPROM library's examples.
自己找到答案有一个非常好用的文件系统,叫做SPIFFS。
如果您使用的是 Arduino IDE,您会发现一个名为 SPIFFS_test 的示例程序。它非常简单明了,展示了如何打开文件、列出目录等。
文件->示例->ESP32 示例->SPIFFS->SPIFFS_test
函数及其使用方式与标准 C 文件系统函数非常相似,甚至可能相同。