Cách đọc và viết EEPROM trong ESP8266


13

Tôi cần biết làm thế nào tôi có thể viết các giá trị nguyên trong EEPROM và giữ lại giá trị khi bật nguồn.

char *Red = strstr(myTestUrl, "/R");
if (Red) {
  int RedValue  = atoi(Red + 2);
  analogWrite(12, RedValue);
  Serial.println("Red :");
  Serial.println(RedValue);
}

Tôi muốn viết RedValuebằng EEPROM. Nó được hoàn thiện bằng cách nào?


Hãy xem bản phác thảo mẫu EEPROM được cài đặt khi bạn thêm hỗ trợ ESP8266 vào ide arduino
Jaromanda X

có một câu hỏi nếu có bất kỳ phụ thuộc flash nào sử dụng EEPROM. Tôi có thể flash với 1 MB (không có SPIFFS) và có quyền truy cập vào EEPROM không? Cảm ơn T
riker1

Câu trả lời:


25

Mặc dù EEPROM.readEEPROM.writelà phương pháp hợp lệ, nó giống như lau sàn nhà bằng bàn chải đánh răng. Sử dụng EEPROM.putEEPROM.getthay vào đó.

Ví dụ:

#include <EEPROM.h>

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

  uint addr = 0;

  // fake data
  struct { 
    uint val = 0;
    char str[20] = "";
  } data;

  // commit 512 bytes of ESP8266 flash (for "EEPROM" emulation)
  // this step actually loads the content (512 bytes) of flash into 
  // a 512-byte-array cache in RAM
  EEPROM.begin(512);

  // read bytes (i.e. sizeof(data) from "EEPROM"),
  // in reality, reads from byte-array cache
  // cast bytes into structure called data
  EEPROM.get(addr,data);
  Serial.println("Old values are: "+String(data.val)+","+String(data.str));

  // fiddle with the data "read" from EEPROM
  data.val += 5;
  if ( strcmp(data.str,"hello") == 0 )
      strncpy(data.str, "jerry",20);
  else 
      strncpy(data.str, "hello",20);

  // replace values in byte-array cache with modified data
  // no changes made to flash, all in local byte-array cache
  EEPROM.put(addr,data);

  // actually write the content of byte-array cache to
  // hardware flash.  flash write occurs if and only if one or more byte
  // in byte-array cache has been changed, but if so, ALL 512 bytes are 
  // written to flash
  EEPROM.commit();  

  // clear 'data' structure
  data.val = 0; 
  strncpy(data.str,"",20);

  // reload data for EEPROM, see the change
  //   OOPS, not actually reading flash, but reading byte-array cache (in RAM), 
  //   power cycle ESP8266 to really see the flash/"EEPROM" updated
  EEPROM.get(addr,data);
  Serial.println("New values are: "+String(data.val)+","+String(data.str));
}

void loop()
{
  delay(1000);
}

CẬP NHẬT : Nếu bạn muốn hiểu cách "EEPROM" được mô phỏng trong ESP8266, bạn có thể muốn tham khảo https://github.com/esp8266/Arduino/tree/master/lologists/EEPROM , cụ thể , EEPROM.h.

Ngoài ra, EEPROM.endkhông cần thiết, nó chỉ đơn giản là xóa bộ đệm mảng byte cục bộ của flash / EEPROM khỏi RAM. Nó phục vụ trên chức năng khác.


bạn đã cứu ngày của tôi, tôi đã tìm kiếm hơn năm giờ cho một giải pháp và bạn đã đưa ra nó!
nonozor

Tài liệu thực tế về Arduino thực sự thiếu ở đây và các nguồn cũng không thực sự giúp ích. EEPROM.end () có còn cần thiết không? Tại sao bắt đầu (512) cần thiết? Cộng với kết hợp get () / put () hoặc sử dụng update () sẽ giúp ngăn ngừa hao mòn EEPROM. Có lẽ bạn có thể cập nhật câu trả lời.
Bim

Tôi đã sao chép / dán mã chính xác này cho NodeMCU v3 và nó không lấy được giá trị bằng văn bản sau một chu kỳ nguồn (tôi đã nhận xét "phần ghi cho lần chạy thứ hai").
WhiskerBiscuit

@WhiskerBcakes, bạn có thấy BẤT K output đầu ra nào trong bảng điều khiển nối tiếp không? Bạn có chắc chắn tốc độ baud được đặt chính xác? Tôi không có v3, chỉ là v0.9, vì vậy không thể giúp nếu đây là vấn đề tương thích về phía trước.
codechimp

2
từ tham chiếu "EEPROM.write không ghi vào flash ngay lập tức, thay vào đó bạn phải gọi EEPROM.commit () bất cứ khi nào bạn muốn lưu thay đổi vào flash. EEPROM.end () cũng sẽ cam kết và sẽ phát hành bản sao RAM của nội dung EEPROM. "
Juraj

7

EEPROM.write(pos, val)ghi một byte ( val) tại địa chỉ cho bởi pos. Một "int" trong ESP8266 mất 4 byte, vì vậy nó phức tạp hơn một chút, vì EEPROM hoạt động theo byte chứ không phải ints.

Đây là mã để viết một int valtại một số vị trí postrong EEPROM:

void eeWriteInt(int pos, int val) {
    byte* p = (byte*) &val;
    EEPROM.write(pos, *p);
    EEPROM.write(pos + 1, *(p + 1));
    EEPROM.write(pos + 2, *(p + 2));
    EEPROM.write(pos + 3, *(p + 3));
    EEPROM.commit();
}

và, tất nhiên, bạn cần đọc lại:

int eeGetInt(int pos) {
  int val;
  byte* p = (byte*) &val;
  *p        = EEPROM.read(pos);
  *(p + 1)  = EEPROM.read(pos + 1);
  *(p + 2)  = EEPROM.read(pos + 2);
  *(p + 3)  = EEPROM.read(pos + 3);
  return val;
}

Trong Arduino bạn gọi EEPROM.begin(), nhưng trong ESP8266 bạn phải gọi EEPROM.begin(n), ntổng số byte bạn sẽ cần là bao nhiêu.

Và hãy nhớ rằng EEPROM có tuổi thọ ngắn (theo số lần ghi). Bạn phải giảm thiểu số lượng viết!

EEPROM là vĩnh viễn; bạn không cần làm gì cả.


Tôi đã thực hiện một số tìm kiếm và có vẻ như EEPROM có thể xử lý nhiều chu kỳ ghi hơn so với lưu trữ flash nhưng sau đó lưu trữ flash cũng có bộ điều khiển để ngừng sử dụng các phần xấu và tiếp tục làm việc với các phần hoạt động còn lại.
Qwertie

1
UPVOTED vì cảnh báo vòng đời. Chu kỳ 100k, một số người nói.
tony gil

1

Phương pháp sử dụng số lượng chữ cái.

#include <ESP8266WiFi.h>

const char* SSID = "R360"; //MAX 32
const char* PASSWORD = "HFDYUK64323246"; //MAX 32

#include <EEPROM.h>

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

  EEPROM_ESP8266_GRABAR(SSID, 0); //Primero de 0 al 32, del 32 al 64, etc
  EEPROM_ESP8266_GRABAR(PASSWORD, 32); //SAVE

  Serial.println();
  Serial.println(EEPROM_ESP8266_LEER(0, 32));//Primero de 0 al 32, del 32 al 64, etc
  Serial.println(EEPROM_ESP8266_LEER(32, 64));

  WiFi.begin(EEPROM_ESP8266_LEER(0,32).c_str(), EEPROM_ESP8266_LEER(32,64).c_str());

}
//
void loop() {}
//
void EEPROM_ESP8266_GRABAR(String buffer, int N) {
  EEPROM.begin(512); delay(10);
  for (int L = 0; L < 32; ++L) {
    EEPROM.write(N + L, buffer[L]);
  }
  EEPROM.commit();
}
//
String EEPROM_ESP8266_LEER(int min, int max) {
  EEPROM.begin(512); delay(10); String buffer;
  for (int L = min; L < max; ++L)
    if (isAlphaNumeric(EEPROM.read(L)))
      buffer += char(EEPROM.read(L));
  return buffer;
}

0

Tôi sử dụng 2 chức năng riêng biệt trong mã của mình trên ESP8266 - một với EEPROM.put(), một với EEPROM.get().

Tôi EEPROM.begin(sizeof...);chỉ có EEPROM.put()chức năng và putlàm việc. Nhưng tôi đã mất khá nhiều thời gian, cho đến khi tôi phát hiện ra rằng nó cũng phải được sử dụng trước đó EEPROM.get().


-1

Sử dụng #include <EEPROM.h>

EEPROM.write(0, RedValue);   // To store in 0th Location
EEPROM.commit();

3
Bạn đã quênEEPROM.begin()
per1234
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.