Lesen und Schreiben von EEPROM in ESP8266

13

Ich muss wissen, wie ich ganzzahlige Werte in das EEPROM schreiben und den Wert beim Einschalten beibehalten kann.

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

Ich möchte RedValuein EEPROM schreiben . Wie geht das?

Eingebetteter Geek
quelle
Schauen Sie sich die EEPROM-Beispielskizzen an, die installiert werden, wenn Sie der Arduino-Idee
Jaromanda X
Sie haben eine Frage, ob Flash-Abhängigkeiten mit dem EEPROM bestehen. Kann ich mit 1 MB (kein SPIFFS) flashen und auf das EEPROM zugreifen? Danke T
riker1

Antworten:

25

Während EEPROM.readund EEPROM.writesind gültige Methoden, ist es wie das Wischen des Bodens mit einer Zahnbürste. Verwenden Sie EEPROM.putund EEPROM.getstattdessen.

Zum Beispiel:

#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);
}

UPDATE : Wenn Sie verstehen möchten, wie das "EEPROM" im ESP8266 emuliert wird, sollten Sie speziell auf https://github.com/esp8266/Arduino/tree/master/libraries/EEPROM verweisen EEPROM.h.

Wird auch EEPROM.endnicht benötigt, löscht es einfach den lokalen Byte-Array-Cache des Flash / EEPROM aus dem RAM. Es dient einer anderen Funktion.

Codechimp
quelle
Sie haben meinen Tag gerettet, ich habe mehr als fünf Stunden nach einer Lösung gesucht und Sie haben sie gegeben!
Nonozor
Die eigentliche Arduino-Dokumentation fehlt hier wirklich und die Quellen helfen auch nicht wirklich. Wird EEPROM.end () noch benötigt? Warum wird begin (512) benötigt? Eine Kombination aus get () / put () oder die Verwendung von update () würde dazu beitragen, den Verschleiß des EEPROM zu verhindern. Vielleicht könnten Sie die Antwort aktualisieren.
Bim
Ich habe genau diesen Code für eine NodeMCU v3 kopiert / eingefügt und der geschriebene Wert wird nach einem Aus- und Wiedereinschalten nicht abgerufen (ich habe den "Schreibabschnitt für den zweiten Lauf" auskommentiert).
WhiskerBiscuit
@WhiskerBiscuit, sehen Sie eine Ausgabe in der seriellen Konsole? Sind Sie sicher, dass die Baudrate richtig eingestellt ist? Ich habe nicht v3, nur v0.9, kann also nicht helfen, wenn dies ein Vorwärtskompatibilitätsproblem ist.
Codechimp
2
aus der Referenz "EEPROM.write schreibt nicht sofort in Flash, sondern Sie müssen EEPROM.commit () aufrufen, wenn Sie Änderungen an Flash speichern möchten. EEPROM.end () schreibt ebenfalls fest und gibt die RAM-Kopie des EEPROM-Inhalts frei. ""
Juraj
7

EEPROM.write(pos, val)schreibt ein Byte ( val) an die Adresse von pos. Ein "int" in ESP8266 benötigt 4 Bytes, ist also etwas komplizierter, da das EEPROM in Bytes und nicht ints arbeitet.

Hier ist ein Code zum Schreiben eines Int valan einer bestimmten Stelle posim 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();
}

und natürlich müssen Sie es zurücklesen:

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;
}

In Arduino rufen Sie an EEPROM.begin(), aber in ESP8266 müssen Sie anrufen EEPROM.begin(n), wo nsich die Gesamtzahl der benötigten Bytes befindet.

Und denken Sie daran, dass EEPROM eine kurze Lebensdauer haben (nach Anzahl der Schreibvorgänge). Sie müssen die Anzahl der Schreibvorgänge minimieren!

EEPROM ist permanent; Sie müssen nichts tun.

gre_gor
quelle
Ich habe einige Suchanfragen durchgeführt und es scheint, dass EEPROMs viel mehr Schreibzyklen als Flash-Speicher verarbeiten können, aber dann verfügt der Flash-Speicher auch über einen Controller, der die Verwendung fehlerhafter Abschnitte beendet und mit den verbleibenden funktionierenden weiterarbeitet.
Qwertie
1
UPVOTED wegen des Lebenszyklusalarms. 100.000 Zyklen, sagen manche.
Tony Gil
1

Methode unter Verwendung der Anzahl der Buchstaben.

#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;
}
360
quelle
0

Ich verwende 2 separate Funktionen in meinem Code auf ESP8266 - eine mit EEPROM.put(), eine mit EEPROM.get().

Ich hatte EEPROM.begin(sizeof...);nur in EEPROM.put()Funktion und putarbeitete. Aber es hat eine ganze Weile gedauert, bis ich herausgefunden habe, dass es auch vorher verwendet werden muss EEPROM.get().

PeterM
quelle
-1

Verwenden #include <EEPROM.h>

EEPROM.write(0, RedValue);   // To store in 0th Location
EEPROM.commit();
Eingebetteter Geek
quelle
3
Sie haben vergessenEEPROM.begin()
per1234