NodeMCU (Arduino) EEPROM schreiben und lesen

Hallo Community,

hoffe ihr könnt mir helfen.
Lerne mich gerade in die Nutzung vom EEPROM des NodeMCU (Arduino) ein.
Es geht mir um das abspeichern von einer IP einer Subnetzmaske und einer SSID.
Leider bekomme ich bei der Textausgabe am Ende immer ein zusätzliches Char ‚@‘ ausgegeben. Das bekomme ich nicht weg. Vielleicht könnt ihr mir sagen woran das liegt.

Viele Grüße kleiner_kaktus

Die Textausgabe:

192.168.001.111@

Mein Quellcode:

    //+++++++++++++++++++++++++++++++++++++++++++++++++++ Libraries +++++++++++++++++++++++++++++++++++++++++++++++++++

    #include <EEPROM.h>

    //+++++++++++++++++++++++++++++++++++++++++++++ Variablendeklaration ++++++++++++++++++++++++++++++++++++++++++++++

    String sSSID = "WLAN";
    int iSSID_length = 50;
    String sIP = "192.168.001.111";
    String sSNM = "255.255.255.000";


    //+++++++++++++++++++++++++++++++++++++++++++++++++++++ SETUP +++++++++++++++++++++++++++++++++++++++++++++++++++++

    void setup() {
      Serial.begin(115200);
      EEPROM.begin(4096);
      EEPROM_writeIP(sIP);
      Serial.println();
      Serial.println(EEPROM_readIP());
    }

    //+++++++++++++++++++++++++++++++++++++++++++++++++++++ LOOP ++++++++++++++++++++++++++++++++++++++++++++++++++++++

    void loop() {
    }

    //---------------------------------------- Function: Write SSID to EEPROM -----------------------------------------

    void EEPROM_writeSSID(String sSSID){
      char CharSSID[50];
      sSSID.toCharArray(CharSSID, 50);

      for (int i = 17; i<(sSSID.length()+17); i++) {
    EEPROM.write(i,CharSSID[i-17]);
      }
    }

    //---------------------------------------- Function: Read SSID to EEPROM ------------------------------------------

    String EEPROM_readSSID() {
      char CharSSID[50];
      String sSSID;

      for (int i = 17; i<(sSSID.length()+17); i++) {
    CharSSID[i-17] = EEPROM.read(i);
      }

      sSSID = String(CharSSID);
    }


    //----------------------------------------- Function: Write IP to EEPROM ------------------------------------------

    void EEPROM_writeIP(String StringIP) {

      char CharIP[16];
      StringIP.toCharArray(CharIP,16);
      
      EEPROM.write(0,CharIP[0]);
      EEPROM.write(1,CharIP[1]);
      EEPROM.write(2,CharIP[2]);
      EEPROM.write(3,CharIP[4]);
      EEPROM.write(4,CharIP[5]);
      EEPROM.write(5,CharIP[6]);
      EEPROM.write(6,CharIP[8]);
      EEPROM.write(7,CharIP[9]);
      EEPROM.write(8,CharIP[10]);
      EEPROM.write(9,CharIP[12]);
      EEPROM.write(10,CharIP[13]);
      EEPROM.write(11,CharIP[14]);
    }

    //---------------------------------------- Function: Read IP from EEPROM -----------------------------------------

    String EEPROM_readIP() {

      String ip;
      
      char CharIP[15];
      CharIP[0] = EEPROM.read(0);
      CharIP[1] = EEPROM.read(1);
      CharIP[2] = EEPROM.read(2);
      CharIP[3] = '.';
      CharIP[4] = EEPROM.read(3);
      CharIP[5] = EEPROM.read(4);
      CharIP[6] = EEPROM.read(5);
      CharIP[7] = '.';
      CharIP[8] = EEPROM.read(6);
      CharIP[9] = EEPROM.read(7);
      CharIP[10] = EEPROM.read(8);
      CharIP[11] = '.';
      CharIP[12] = EEPROM.read(9);
      CharIP[13] = EEPROM.read(10);
      CharIP[14] = EEPROM.read(11);

      ip = String(CharIP);
      return ip;
    }

Hallo!

Ein string ist dynamisch, das heißt, man kann jederzeit was dran hängen, und die Länge ist jederzeit bekannt.

Ein char array hat eine feste Länge, wird aber auch zum Speichern von Zeichenketten genutzt. Dann muss das letzte Zeichen aber 0x00 sein, um das Ende zu markieren.

Dein

beginnt ab der Speicheradresse CharIP Byte für Byte zu lesen, bis ein 0x00 kommt. Dein char array enthält aber kein 0x00, aber im Speicher steht zufällig 0x40 0x00 direkt dahinter, daher wird das 0x40 (@) noch mit in den String gepackt.

Also, mach das CharIP noch ein Byte größer, und setze dieses gleich 0x00, dann sollte es klappen.

Generell: eine IP besteht aus vier bytes, daher besteht keine Notwendigkeit, sie als ASCII mit 12 Bytes zu speichern. Auch die Subnet-Maske kann als ein Byte gespeichert werden, weil sie binär aus vielen Einsen, gefolgt von vielen Nullen besteht. Man muss sich nur merken, wieviele Einsen da stehen, und das sind nie mehr als 32.

Inzwischen haben auch Microcontroller immer mehr Speicher, und man darf da gerne verschwenderisch sein. Aber bei kleineren feilscht man auch heute noch um jedes Byte.

Hi sweber,

danke für die Unterstützung. Inzwischen habe ich das Problem gelöst und auch dein Hinweis mit den 4 bytes umgesetzt.
Deine Erklärung, dass das @ Zeichen zufällig drin stand hatte ich auch schon überlegt gehabt. Daraufhin habe ich den ganzen EEPROM mit 0 überschrieben gehabt. Das ‚@‘ war allerdings immer noch da.
Zumindest funktioniert es jetzt alles so wie es soll.
Ganz schlau werde ich trotzdem nicht draus woher das Zeichen kam.

Viele Grüße
kleiner_kaktus

Hi!
Das Zeichen kommt nicht aus dem eeprom. Du kopierst alle Zeichen aus dem eeprom zunächst in ein char array, das exakt die benötigte Größe hat. Und dann lässt du das in einen String einlesen. Weil aber nicht wirklich bekannt ist, wie groß das char array ist, liest die String-Funktion vom Anfang des Arrays bis zum nächsten 0x00, also über das Ende des Arrays hinaus. Deshalb sollst du das array größer machen, und am Ende 0x00 einfügen.