Startseite>Daten im EEPROM speichern
Aus Raspberry Pi Geek 08/2017

Daten im EEPROM speichern

© Mariia Voloshina, 123RF

Vergissmeinnicht

Martin Mohr

Legen Sie Daten im EEPROM des ESP8266 ab, dann überstehen diese selbst einen Stromausfall.

Um die Funktionsweise des EEPROMs im ESP8266 besser zu verstehen, bietet sich ein praxisnahes Beispiel an: Bisher war die Konfiguration des Netzwerks für die Software im Workshop immer ins Programm eingebaut. Das ist für einen Bastler vollkommen in Ordnung.

Was aber passiert, wenn Sie eine tolle IoT-Lösung gebaut haben, die Sie bei einem Interessenten zum Laufen bringen wollen? Das setzt voraus, dass Sie diese mit anderen Parametern für das Netzwerk neu kompilieren – eine wenig praktikable Lösung. Daher lernen Sie in diesem Workshop ein Programm kennen, das es Ihnen erlaubt, die entsprechenden Daten für den ESP8266 über die USB-Schnittstelle einzustellen.

EEPROM

EEPROM ist die englische Abkürzung für “electrically erasable programmable read-only memory”. Frei übersetzt heißt das, Sie dürfen Daten in einem nicht flüchtigen Speicher ablegen und wieder löschen. Intern bestehen diese speziellen Speicher aus Feldeffekttransistoren mit jeweils isoliertem Gate.

Das Auslesen stellt keinerlei Problem dar, doch überleben die Bausteine nur eine begrenzte Anzahl von Schreibvorgängen. Typischerweise kommt es nach rund 100 000 Zyklen zu ersten Fehlern. Achten Sie daher beim Programmieren darauf, nicht zu oft in den Speicher zu schreiben: Ein Speichern von Messwerten im Sekundentakt bedeutet sehr schnell das Ende für den Chip.

Testaufbau

Der Testaufbau fällt diesmal sehr spartanisch aus: Er besteht nur aus einen ESP8266 und den zum Betrieb nötigen Komponenten (Abbildung 1), der Schaltplan gestaltet sich dementsprechend übersichtlich (Abbildung 2). Alle hier verwendeten Teile kamen in vorherigen Teilen dieser Reihe schon zur Sprache.

Abbildung 1: Da es beim Schreiben von Daten ins EEPROM eher auf die Software ankommt, fällt der Versuchsaufbau in diesem Workshop sehr übersichtlich aus.

Abbildung 1: Da es beim Schreiben von Daten ins EEPROM eher auf die Software ankommt, fällt der Versuchsaufbau in diesem Workshop sehr übersichtlich aus.

Abbildung 2: Der Schaltplan zeigt die zum Schreiben in den nichtflüchtigen Speicher notwendigen Teile, die eigentliche Arbeit leistet aber diesmal die Software.

Abbildung 2: Der Schaltplan zeigt die zum Schreiben in den nichtflüchtigen Speicher notwendigen Teile, die eigentliche Arbeit leistet aber diesmal die Software.

Allerdings fällt die Software diesmal etwas komplexer aus. Als Entwicklungsumgebung kommt wieder die Arduino IDE zum Einsatz. Das Programm aus Listing 1 gibt Ihnen die Möglichkeit, die Parameter für die Konfiguration des WLAN-Zugangs über die USB-Schnittstelle einzugeben. Die Funktion loop() am Schluss bleibt erst einmal leer, hier ist Platz für Ihren eigenen Code.

Listing 1

 

#include <ESP8266WiFi.h>
#include <EEPROM.h>
String ssid;
String pass;
char ssidbuffer[20];
char passbuffer[20];
void setup() {
  Serial.begin(115200);
  Serial.println("");
  Serial.println("Press any Key to start Setup");
  unsigned long start=millis();
  while((start+60000)>millis()) {
    yield();
    if (Serial.available()) {
      Serial.read();
      Serial.read();
      setupmenu();
      connectWIFI();
      return;
    }
  }
  connectWIFI();
};
void connectWIFI() {
  readPROM();
  Serial.println("") ;
  Serial.println("Connect to ") ;
  Serial.println(ssid) ;
  Serial.println(pass) ;
  ssid.toCharArray(ssidbuffer,20);
  pass.toCharArray(passbuffer,20);
  WiFi.begin(ssidbuffer,passbuffer );
  while (WiFi.status()!=WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
};
void setupmenu() {
  Serial.println("Enter Setup");
  Serial.print("SSID:");
  ssid=String("");
  while(true) {
    if (Serial.available()) {
      char c=Serial.read();
      Serial.write(c);
      if (c==13) {
        break;
      }
      else {
        ssid=String(ssid+c);
      }
    yield();
    }
  }
  Serial.print("PASS:") ;
  pass=String("");
  while(true) {
    if (Serial.available()) {
      char c=Serial.read();
      Serial.write(c);
      if (c==13) {
        break;
      }
      else {
        pass=String(pass+c);
      }
      yield();
    }
  }
  ssid.trim();
  pass.trim();
  Serial.println("");
  Serial.println(ssid);
  Serial.println("");
  Serial.println(pass);
  writePROM();
  Serial.println("Saved to EEPROM");
  };
void readPROM() {
  EEPROM.begin(512);
  EEPROM.get(0,ssidbuffer);
  ssid=String(ssidbuffer);
  EEPROM.get(21,passbuffer);
  pass=String(passbuffer);
  EEPROM.commit();
  EEPROM.end();
};
void writePROM() {
  EEPROM.begin(512);
  strncpy(ssidbuffer,ssid.c_str(),20);
  EEPROM.put(0,ssidbuffer);
  strncpy(passbuffer,pass.c_str(),20);
  EEPROM.put(21,passbuffer);
  EEPROM.commit();
  EEPROM.end();
};
void loop() {
  // Hierhin kommt Ihr Programm.
}

Die zwei Funktionen readPROM() (Zeile 88) und writePROM() (Zeile 98) lesen und speichern die Variablen ssid und pass im EEPROM. Achten Sie darauf, die Variablen immer an dieselbe Adresse zu schreiben und wieder auszulesen.

Der erste Parameter der Befehle EEPROM.get() und EEPROM.put() gibt an, welche Speicheradresse im EEPROM zum Einsatz kommt. Mit EEPROM.begin() definieren Sie, wie viele Bytes aus dem Speicher Sie verwenden wollen. Die Befehle EEPROM.commit() und EEPROM.end() dienen dazu, die Änderungen im EEPROM festzuschreiben beziehungsweise die Kommunikation zu beenden.

Das externe EEPROM des ESP8266 sprechen Sie über die SPI-Schnittstelle an. Darauf lassen sich nur primitive Datentypen speichern wie Ganz- und Fließkommazahlen, Zeichen (char) und Pointer sowie deren unterschiedliche Ausprägungen. Deshalb wandelt die Software auch die Zeichenketten ssid und pass vor dem Speichern in Char-Arrays um (Zeile 32 und 33).

Verbindungsaufbau

Die Funktion connectWIFI() (Zeile 26) verwendet diese beiden Variablen, um sich mit einem WLAN zu verbinden. Über readPROM() lesen Sie sie ein.

Da Sie für Zugriffe auf das EEPROM und die Methode WiFi.begin() Arrays von Zeichen benötigen, bringt das Programm mit ssidbuffer[] und passbuffer[] zwei solche, global definierte Strukturen mit. Beide speichern je maximal 20 Zeichen – für längere SSIDs oder Passworte müssen Sie die Länge anpassen. Vergessen Sie in diesem Fall nicht, auch die Funktionen readPROM() und writePROM() anzupassen.

In der Funktion setup() (Zeile 8) initialisieren Sie die serielle Schnittstelle. Danach fragt die Software die Daten vom Anwender ab. Erfolgt innerhalb von 60 Sekunden keine Eingabe, ruft die Software die Funktion connectWIFI() auf, und der Controller versucht, sich mit eventuell im EEPROM gespeicherten Daten mit dem WLAN zu verbinden. Gibt der User innerhalb von 60 Sekunden etwas ein, kommt die Funktion setupmenu() zum Zug.

Wie Sie im Code sehen, ruft das Programm innerhalb der While-Schleife immer wieder die Funktion yield() auf. Das verhindert, dass der ESP8266 abstürzt. Die Funktion gibt dem Mikrocontroller die Möglichkeit, interne Verwaltungsprogramme auszuführen. Viele Abstürze lassen sich auf das Fehlen dieser Funktion in Schleifen zurückführen.

Die beiden Aufrufe von Serial.read() dienen dazu, den Eingangspuffer der seriellen Schnittstelle zu leeren. Unterlassen Sie das, erkennt setupmenu() eine Eingabe, wo gar keine war.

Daten einlesen

Bei setupmenu() (Zeile 46) handelt es sich um die wichtigste Funktion des Programms: Sie liest die SSID und das Passwort ein und speichert beide mithilfe von writePROM() dauerhaft. Als einzige neue Funktion kommt hier trim() zum Einsatz. Es entfernt Leerzeichen am Anfang und Ende von Zeichenketten. Alle anderen Programmabläufe kamen in der ein oder anderen Weise in dieser Reihe schon zum Einsatz.

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDFUmfang: 4 HeftseitenPreis €0,99
(inkl. 19% MwSt.)
€0,99 – Kaufen
RASPBERRY PI GEEK KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS
Deutschland