0

For those of you familiar with my somewhat steep EEPROM learning curve...thank you for continuing to share your knowledge. I see how it's supposed to work and it's falling into place.

I've run into a new problem and I've spent two nights (~15hrs of Googling/trial and error...mostly error) trying to understand where I'm going wrong.

Below is a chunk of code that take user inputs from a webpage and saves it to EEPROM. It works as intended when only SSID and PASS fields are provided on the form. I added an "owner" field to add my name to the EEPROM (because why not?) and now the PASS field is ignored and the OWNER information is saved to the PASS and OWNER EEPROM locations.

I think it has something to do with the string.indexof("&") and repeated string.lastindexof("=") but I'm still wrapping my head around what these actually do. If I understand it correctly, the second string.lastindexof("=") is actually overwriting the PASS which was saved milliseconds earlier. If this is correct, how do I prevent this? If I'm wrong, why?

  s += "<form method='get' action='a'><label>SSID: </label><input name='ssid' length=32><br><label>PASS: </label><input name='pass' length=64><br><label>OWNER: </label><input name='owner' length=32><br><br><input type='submit'></form>";
  s += "</html>\r\n\r\n\r\n";
  Serial.println("Sending 200");
}
else if ( req.startsWith("/a?ssid=") ) {
  Serial.println("clearing eeprom");
  for (int i = 0; i < 128; ++i) {
    EEPROM.write(i, 0);
  }
  String qsid;
  qsid = req.substring(8, req.indexOf('&'));
  Serial.println(qsid);
  Serial.println("");
  String qpass;
  qpass = req.substring(req.lastIndexOf('=') + 1);
  Serial.println(qpass);
  Serial.println("");
  String owner;
  owner = req.substring(req.lastIndexOf('=') + 1);
  Serial.println(owner);
  Serial.println("");

  Serial.println("writing eeprom ssid:");
  for (int i = 0; i < qsid.length(); ++i)
  {
    EEPROM.write(i, qsid[i]);
    Serial.print("Wrote: ");
    Serial.println(qsid[i]);
  }
  Serial.println("writing eeprom pass:");
  for (int i = 0; i < qpass.length(); ++i)
  {
    EEPROM.write(32 + i, qpass[i]);
    Serial.print("Wrote: ");
    Serial.println(qpass[i]);
  }
  Serial.println("writing eeprom owner:");
  for (int i = 0; i < owner.length(); ++i)
  {
    EEPROM.write(96 + i, owner[i]);
    Serial.print("Wrote: ");
    Serial.println(owner[i]);
  }
  EEPROM.commit();

To summarize, my questions are:
-what is causing the code to skip over my PASS field and save a duplicate of OWNER into both PASS and OWNER?
-is one \r\n pair required for every field on the html form? If I used 100 fields would I need 100 * \r\n pairs after tag?

If you're interested in seeing the whole shebang, chriscook8 has graciously posted the Access Point sketch for the ESP8266 here (~250 lines). There is also a very helpful discussion about this sketch here.


Edit: 3 July 2016

I've amended the code:

s += "<form method='get' action='a'><label>SSID: </label><input name='ssid' length=32><br><label>PASS: </label><input name='pass' length=64><br><label>OWNER: </label><input name='owner' length=32><br><br><input type='submit'></form>";
s += "</html>\r\n\r\n\r\n";
Serial.println("Sending 200");
}
    else if ( req.startsWith("/a?ssid=") ) {
      Serial.println("clearing eeprom");
      for (int i = 0; i < 128; ++i) {
        EEPROM.write(i, 0);
      }
      String qsid = server.arg("ssid");
      String qpass = server.arg("pass");
      String owner = server.arg("owner");
    }
    Serial.println("writing eeprom ssid:");
    for (int i = 0; i < qsid.length(); ++i)
    {
      EEPROM.write(i, qsid[i]);
      Serial.print("Wrote: ");
      Serial.println(qsid[i]);
    }
    Serial.println("writing eeprom pass:");
    for (int i = 0; i < qpass.length(); ++i)
    {
      EEPROM.write(32 + i, qpass[i]);
      Serial.print("Wrote: ");
      Serial.println(qpass[i]);
    }
    Serial.println("writing eeprom owner:");
    for (int i = 0; i < owner.length(); ++i)
    {
      EEPROM.write(96 + i, owner[i]);
      Serial.print("Wrote: ");
      Serial.println(owner[i]);
    }
    EEPROM.commit();
    s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>Hello from ESP8266 ";
    s += "Found ";
    s += req;
    s += "<p> saved to eeprom... reset to boot into new wifi</html>\r\n\r\n";
  }
  else
  {
    s = "HTTP/1.1 404 Not Found\r\n\r\n";
    Serial.println("Sending 404");
  }
}

I also made the following replacement per your recommendations:

//WiFiServer server(80);
ESP8266WebServer server ( 80 );

...and receive an error on this line:

WiFiClient client = server.available();

'class ESP8266WebServer' has no member named 'available'

I'm sure that there is a simple replacement for this. Any idea what it might be?

Otherwise, I think I see where you're going with this and it seems much cleaner than I anticipated.

Thank you!

2
  • if you're using ESP8266WebServer - it has a function, arg(String name) ... so you'd do something like String ssid = ws.arg("ssid"); to get the ssid parameter from the request - ws in the example is a ESP8266WebServer object Jun 29, 2016 at 6:36
  • I'll look that up. Would that replace "String qsid" or "qsid = req.substring(8, req.indexOf('&'))"?
    – acpilot
    Jun 29, 2016 at 6:41

1 Answer 1

1

A code snippet for you - will expand later (just got tied up)

ESP8266WebServer server ( 80 );
...

else if ( req.startsWith("/a?ssid=") ) {
  Serial.println("clearing eeprom");
  for (int i = 0; i < 128; ++i) {
    EEPROM.write(i, 0);
  }
  String qsid = server.arg("ssid");
  String qpass = server.arg("pass");;
  String owner = server.arg("owner");

  Serial.println("writing eeprom ssid:");
  ... rest of your code
3
  • I will try this tonight.
    – acpilot
    Jun 29, 2016 at 22:41
  • I amended my OP with the new code and an error I get when I compile.
    – acpilot
    Jul 4, 2016 at 2:57
  • The best practice with EEPROM is only write it when absolutely necessary. Your clearing of EEPROM will quickly kill it.
    – user31481
    Oct 30, 2017 at 9:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.