nodeMCU saves numbers in flash memory but not characters

hello beautiful people...
I m just tryin to feed my nodeMCU with an api key from browser as client and save it into flash memory(EEPROM) and expect my board to recall it when powered on at any other time.....it happens when i feed numbers to it but when i tried givin it strings as whole or character by character.....it didnt recall any of it when powered again....could you please help me here and suggest the expected mistake....
Thanks already

oh heres the code

#include <EEPROM.h>
#include <ESP8266WiFi.h>          //https://github.com/esp8266/Arduino
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiClient.h>

  String ssid,pass;
  uint8_t addr =0;
  int x;
  char pq[100];
  unsigned long int api;
const char 
  *pageheader = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">",
  *htmlhead = "<html><head><title>Your Title</title><meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" /></head>",
  *bodystyle = "<body style=\"color: wheat; background-color: teal; font-size: 12pt; font-family: sans-serif;\">",
  *htmlclose = "</body></html>";
char  *username = "corph", *password = "corph@786";
String s,API_KEY; 
ESP8266WebServer server(80);
String page;
void setup() {
  Serial.begin(115200);
  EEPROM.begin(512);
  WiFi.begin(username,password);
  while (WiFi.status()!= WL_CONNECTED) {
    delay(500);
    Serial.print("->");
  }  

  for(x=0;x<=API_KEY.length();x++){
        API_KEY=EEPROM.read(x);
    }

Serial.println(WiFi.localIP());
  server.begin();
  server.on("/",handleRoot);
  server.on("/wifisave",handleWifiSave);
}

void loop() {

  server.handleClient();
  Serial.println("x in loop");
  Serial.println(API_KEY);
}
void handleRoot() {
  String s;
  s+=pageheader;
  s+=htmlhead;
  s+=bodystyle;
  s+="<form method=\"get\" action=\"http://";
  s+=WiFi.localIP().toString();
  s+="/wifisave\" name=\"ssidnpass\">";  // here you put the distination of the form, the URL that will be requested upon submission
  s+= "<b>API_KEY</b> : <input type=\"text\" value=\"";
  s+= "\" name=\"API_KEY\" size=\"50\" maxlength=\"160\"/>
";
  s+= "<input type=\"submit\" value=\"Save\"></form>"; 
  s+=htmlclose; 
  server.send(200, "text/html", s);  // send 200 == OK see https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html      
}

void handleWifiSave() {
  if (server.hasArg("API_KEY")) {
    API_KEY=server.arg("API_KEY");
//    api='API_KEY';
//    api='server.arg("API_KEY")';
    Serial.println(API_KEY);
    for(x=0;x<=API_KEY.length();x++){
       EEPROM.write(x,'API_KEY[x]');
    }
    
     EEPROM.commit(); 
  }        
 
  String s;  s+=pageheader;
  s+=htmlhead;
  s+=bodystyle;
  s+="<b>API_KEY</b> : ";
  s+=API_KEY;
  s+="
<form method=\"get\" action=\"http://";
  s+=WiFi.localIP().toString();
  s+="\" name=\"home\">"; 
  s+= "<input type=\"submit\" value=\"Home\"></form>"; 
  s+=htmlclose;  
  server.send(200, "text/html", s);
  handleRoot();
}
  for (x = 0; x <= API_KEY.length(); x++)
  {
    API_KEY = EEPROM.read(x);
  }

What will be the length of API_KEY at this point in setup() ?
Why are you trying to read it from multiple EEPROM locations anyway ?

thanks UKHeliBob
thats a mistake....i will correct right now
would u please tell me how am i reading it at multiple locations

still didnt work :frowning: :frowning:

would u please tell me how am i reading it at multiple locations

You are using a for loop thus reading a single byte from several EEPROM locations

Post your code as it is now

i just now tried using get and put but aint workin either
heres the code

#include <EEPROM.h>
#include <ESP8266WiFi.h>          //https://github.com/esp8266/Arduino
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiClient.h>

  String ssid,pass;
  uint8_t addr =0;
  int x,k;
  char pq[100];
  unsigned long int api;
const char 
  *pageheader = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">",
  *htmlhead = "<html><head><title>Your Title</title><meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" /></head>",
  *bodystyle = "<body style=\"color: wheat; background-color: teal; font-size: 12pt; font-family: sans-serif;\">",
  *htmlclose = "</body></html>";
char  *username = "corph", *password = "corph@786";
String s,API_KEY; 
ESP8266WebServer server(80);
String page;
void setup() {
  Serial.begin(115200);
  EEPROM.begin(512);
  WiFi.begin(username,password);
  while (WiFi.status()!= WL_CONNECTED) {
    delay(500);
    Serial.print("->");
  }  
//  API_KEY=EEPROM.read(addr);
//  for(x=0;x<=50;x++){
        API_KEY=EEPROM.get(addr);
//    }

Serial.println(WiFi.localIP());
  server.begin();
  server.on("/",handleRoot);
  server.on("/wifisave",handleWifiSave);
}

void loop() {

  server.handleClient();
  Serial.println("x in loop");
  Serial.println(API_KEY);
}
void handleRoot() {
  String s;
  s+=pageheader;
  s+=htmlhead;
  s+=bodystyle;
  s+="<form method=\"get\" action=\"http://";
  s+=WiFi.localIP().toString();
  s+="/wifisave\" name=\"ssidnpass\">";  // here you put the distination of the form, the URL that will be requested upon submission
  s+= "<b>API_KEY</b> : <input type=\"text\" value=\"";
  s+= "\" name=\"API_KEY\" size=\"50\" maxlength=\"160\"/>
";
  s+= "<input type=\"submit\" value=\"Save\"></form>"; 
  s+=htmlclose; 
  server.send(200, "text/html", s);  // send 200 == OK see https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html      
}

void handleWifiSave() {
  if (server.hasArg("API_KEY")) {
    API_KEY=server.arg("API_KEY");

    Serial.println(API_KEY);
//    for(x=0;x<=API_KEY.length();x++){
       EEPROM.get(addr,API_KEY);
//    }
    
     EEPROM.commit(); 
  }        
 
  String s;  s+=pageheader;
  s+=htmlhead;
  s+=bodystyle;
  s+="<b>API_KEY</b> : ";
  s+=API_KEY;
  s+="
<form method=\"get\" action=\"http://";
  s+=WiFi.localIP().toString();
  s+="\" name=\"home\">"; 
  s+= "<input type=\"submit\" value=\"Home\"></form>"; 
  s+=htmlclose;  
  server.send(200, "text/html", s);
  handleRoot();
}

heres error message

Arduino: 1.8.8 (Windows Store 1.8.19.0) (Windows 10), Board: "NodeMCU 0.9 (ESP-12 Module), 80 MHz, Flash, 4M (1M SPIFFS), v2 Lower Memory, Disabled, None, Only Sketch, 115200"

C:\Users\MEHARR\Desktop\tetee\tetee.ino: In function 'void setup()':

tetee:31:32: error: no matching function for call to 'EEPROMClass::get(uint8_t&)'

         API_KEY=EEPROM.get(addr);

                                ^

C:\Users\MEHARR\Desktop\tetee\tetee.ino:31:32: note: candidate is:

In file included from C:\Users\MEHARR\Desktop\tetee\tetee.ino:1:0:

C:\Users\MEHARR\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.4.2\libraries\EEPROM/EEPROM.h:44:6: note: template<class T> T& EEPROMClass::get(int, T&)

   T &get(int const address, T &t) {

      ^

C:\Users\MEHARR\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.4.2\libraries\EEPROM/EEPROM.h:44:6: note:   template argument deduction/substitution failed:

C:\Users\MEHARR\Desktop\tetee\tetee.ino:31:32: note:   candidate expects 2 arguments, 1 provided

         API_KEY=EEPROM.get(addr);

                                ^

Multiple libraries were found for "ESP8266WebServer.h"
 Used: C:\Users\MEHARR\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.4.2\libraries\ESP8266WebServer
 Not used: C:\Users\MEHARR\Documents\Arduino\libraries\ESPWebServer-master
exit status 1
no matching function for call to 'EEPROMClass::get(uint8_t&)'

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

I believe that the ESP8266 EEPROM library does not have the put() and get() methods so you will have to write and read each character individually and in any case you have used the wrong syntax

thanks man for your immediate reply
i just corrected this error, by using API_KEY=EEPROM.get(addr,API_KEY).....and then i print API_KEY in loop and i get gibberish values in serial monitor nor is web page assesiable ....now that u suggest using read and write..i tried usin em before as you can see the code.....could u please suggest how can i use read or write to deal with strings......as i saw them cozy with numbers...i tried to use ascii values of each character in string.....but aint workin....also i strongly believe it must work that way....now i m experimenting a bit and m about to bang my head to wall

UKHeliBob:

  for (x = 0; x <= API_KEY.length(); x++)

{
    API_KEY = EEPROM.read(x);
  }



What will be the length of API_KEY at this point in setup() ?

you don't know, so you'd need to use a terminating character and read until that. also you could just add to the String, by now the use of them becomes a tad problematic, but on a ESP ach, let's just see if YOU can get it to work.

for(x=0;x<=API_KEY.length();x++){
       EEPROM.write(x,'API_KEY[x]');
    }
    
     EEPROM.commit(); 
  }

sort of is ok, but the write should be EEPROM.write(x,API_KEY.char at(x)); (did that other syntax even compile ?) and just before the EEPROM.commit(); you could add EEPROM.write(x,'\r'); as a terminating character, using your counter variables globally is not very elegant, but it comes in handy here.

Now we are stuck with the issue that i also tend to run into, in our sketch we first read what is there on the EEPROM before we have ever written to it, now how are you going to tackle that and how will you re-write the reading function so it tests for a a terminating character and reads until it has found that (up to a limit, don't read forever.)

for
EEPROM.write(x,API_KEY.char at(x));

error message
exit status 1
expected unqualified-id before 'char'

sabishaw:
for
EEPROM.write(x,API_KEY.char at(x));

error message
exit status 1
expected unqualified-id before 'char'

sorry that's a typo it should be .charAt() but you could have found that if you would have googled it.
see

thanks Deva_Rishi

but you could have found that if you would have googled it.
see

that gives me a chance to call myself a moron.....i shud have googled it
i did what you said....when it comes to reading....i just tried to read first character.....but that too didnt happen........why isnt put and get workin

this is when writing

for (byte x = 0; x < API_KEY.length(); x++ )   // do not put  <=
  {
    EEPROM.write(x,API_KEY.charAt(x));  // stores ascii of char , one by one
  }

EEPROM.write(100,API_KEY.length());   // stores string len

EEPROM.commit();

and this is when reading back

 String API = ""; 

for (byte x = 0; x < EEPROM.read(100); x++ )  // retrieve string len
  {
   char c = EEPROM.read(x);  // gets the ascii, convert it to char

   API += c ;  append char to new API
  }

Serial.println(API);  // prints it

you will be able to read back char as well as numbers

yaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaay
hell yaaaaaaaaaaaaaaaaay

thanks KASSIMSAMJI....it just worked and marked end to my project........it is quite wise programmin man!
"ALL HAIL AFRICA" ...(beczuse KASSIMSAMJI is from Africa)....i just tracked ya man...........
nevertheless lemme thank ya'll....for ya'll inspire me to help others ..i want to see want to see what it feels like.....
bye