String does not return value stored in EEPROM

hello everyone, I'm having a hard time getting the value of a string, I've tried a lot and without success, could someone help me?.

due to println I can receive the value stored in the EEPROM, but when I use it in my slider_value function it returns me without any value, not even a 0

follow my example code.
It's not complete, so it doesn't get too long.
the code below has only the possible problems


#include <EEPROM.h>

#define EEPROM_SIZE 12

void writeStringToEEPROM(int addrOffset, const String &strToWrite)
{
  byte len = strToWrite.length();
  EEPROM.write(addrOffset, len);
  for (int i = 0; i < len; i++)
  {
    EEPROM.write(addrOffset + 1 + i, strToWrite[i]);
    EEPROM.commit();
  }
}

String readStringFromEEPROM(int addrOffset)
{
  int newStrLen = EEPROM.read(addrOffset);
  char data[newStrLen + 1];
  for (int i = 0; i < newStrLen; i++)
  {
    data[i] = EEPROM.read(addrOffset + 1 + i);
  }
  data[newStrLen] = '\0'; 
  return String(data);
}
 

String slider_value = readStringFromEEPROM(0);


const char* input_parameter = "value";


const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>ESP8266 Brightness Control Web Server</title>
  <style>
    html {font-family: Times New Roman; display: inline-block; text-align: center;}
    h2 {font-size: 2.3rem;}
    p {font-size: 2.0rem;}
    body {max-width: 400px; margin:0px auto; padding-bottom: 25px;}
    .slider { -webkit-appearance: none; margin: 14px; width: 360px; height: 25px; background: #FF0000;
      outline: none; -webkit-transition: .2s; transition: opacity .2s;}
    .slider::-webkit-slider-thumb {-webkit-appearance: none; appearance: none; width: 35px; height: 35px; background:#01070a; cursor: pointer;}
    .slider::-moz-range-thumb { width: 35px; height: 35px; background: #01070a; cursor: pointer; } 
  </style>
</head>
<body>
  <h2>FAN 125 PRO</h2>
  <p><span id="textslider_value">%SLIDERVALUE%</span></p>
  <p><input type="range" onchange="updateSliderPWM(this)" id="pwmSlider" min="25" max="250" value="%SLIDERVALUE%" step="1" class="slider"></p>
  <button type="button" onclick="EEPROMRequest();">Save</button>
<script>

function EEPROMRequest () {
  var xhttp = new XMLHttpRequest();
  xhttp.open("GET", "/eraseEEPROM", true);
  xhttp.send();
}


function updateSliderPWM(element) {
  var slider_value = document.getElementById("pwmSlider").value;
  document.getElementById("textslider_value").innerHTML = slider_value;
  console.log(slider_value);
  var xhr = new XMLHttpRequest();
  xhr.open("GET", "/slider?value="+slider_value, true);
  xhr.send();
}
</script>
</body>
</html>
)rawliteral";

String processor(const String& var){
  if (var == "SLIDERVALUE"){
    return slider_value;
  }
  return String();
}
void setup(){
  Serial.begin(115200);
  EEPROM.begin(EEPROM_SIZE);


//String retrievedString = readStringFromEEPROM(0);
  Serial.print("The String we read from EEPROM: ");
  //Serial.println(retrievedString);
  Serial.println(slider_value);
  
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/html", index_html, processor);
  });

  server.on("/slider", HTTP_GET, [] (AsyncWebServerRequest *request) {
    String message;
    if (request->hasParam(input_parameter)) {
      message = request->getParam(input_parameter)->value();
      slider_value = message;
      
      analogWrite(led_pin,slider_value.toInt());
    }
    else {
      message = "No message sent";
    }
    Serial.println(message);
    request->send(200, "text/plain", "OK");
  });
  
  server.begin();
}
  
void loop() {

}

Initialize from the setup, not from the global variable definition

Just brief look but data should be String type or defined by the new operator.

the problem is that in my code there are several parts that need it in the global

""'slider_value' was not declared in this scope ""

when I use it like this it works in Setup()
however my code does not allow me to use slider_value outside the global

String retrievedString = readStringFromEEPROM(0);
Serial.print("The String we read from EEPROM: ");
Serial.println(retrievedString);

The issue is that you call

String slider_value = readStringFromEEPROM(0);

before you call
EEPROM.begin();
so the simplest solution should be

String slider_value = "";

and in setup()

void setup(){
  Serial.begin(115200);
  EEPROM.begin(EEPROM_SIZE);
  slider_value = readStringFromEEPROM(0);

i would btw just declare the EEPROM a bit bigger (at no expense !)
and make sure that the write & read functions do not exceed it's size.
just in case you should declare the maximum size of the 'global String'
straight away to prevent fragmentation

void setup(){
  slider_value.reserve(30); // i am guessing the size for now.
  Serial.begin(115200);
  EEPROM.begin(EEPROM_SIZE);
  slider_value = readStringFromEEPROM(0);
1 Like

Define it globally but initialize it in the setup
You can’t call this function as a global variable initializer outside a function when the environment has not been set up

1 Like

looks easy :joy:
it worked, thank you very much!

thanks for your attention, your formula is the same solution as the friend above!

You could commit at the end of the for loop and not at each character. That would protect a bit your flash and be much faster

2 Likes

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.