Network settings web page FORM using EEPROM to save submit [DONE]

Finished the project, you can check it out on my project page: http://www.jo3ri.be/arduino/arduino-projects/network-settings-web-page-form-using-eeprom-to-save-submit.

and here you have a picture:

Before you get drawling, I'm not that far yet. But what I want to accomplish is a little webserver with a page to change your IP, MAC, STATIC or DHCP and save it, don't know how yet, but I'll will get there :*

So far I have been able to make the webpage:

and here you have the code so far:

/*

This a a demo webpage trying to reproduce the arduino website look
You will need the arduino ethernet shield

made by JO3RI www.JO3RI.be/arduino
*/

#include <SPI.h>
#include <Ethernet.h>

// This is the hardware address of the Arduino on your network.
// You won't need to change this. Learn more here.
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

// This is the tcp/ip address of the Arduino on your network.
// You will access the Arduino by typing it in a web browser like
// this: http://192.168.1.177 Learn more here.
// You might want to change this to be the same as your computer's
// IP address except for the last number. Learn more here.
byte ip[] = { 192, 168, 14, 85};

// Create a server named webserver listening on port 80 (http). You
// don't want to change the port number. Learn more about ports or
// the server class.
Server webserver(80);

// Functions that are run once when the Arduino is started
void setup()
{

// Bring the Arduino on the network using the MAC and IP we
//specified before. Learn more about Ethernet.begin().
Ethernet.begin(mac, ip);
// Start a server on the port we specified before. Learn more
// about server.begin().
webserver.begin();

}

// Repeat these functions as long as the Arduino is powered on
void loop()
{

// Create a client named webclient listening for connections to the
// server. Learn more about Client or server.available()
Client webclient = webserver.available();

// If someone connects to the server...
if (webclient) {

// Create a variable to hold whether or not we have received a blank
// line from the web browser
boolean current_line_is_blank = true;

// Run the following code as long as the client remains connected
// Learn more about client.connected()
while (webclient.connected()) {

// If the client has sent us some data...
// Learn more about client.available()
if (webclient.available()) {

// Keep the last letter of whatever they sent us
// Learn more about client.read()
char c = webclient.read();

// If we've gotten to the end of the line (received a newline
// character) and the line is blank, the http request has ended,
// so we can send a reply
if (c == 'n' && current_line_is_blank) {

// Send a basic HTTP response header (the blank line at the end
// is required). Learn more about client.println()
webclient.println("HTTP/1.1 200 OK");
webclient.println("Content-Type: text/html");
webclient.println();

// Now send whatever html you want to appear on the web page
webclient.println("<body marginwidth"0" marginheight="0" topmargin="0" leftmargin="0" style="margin: 0; padding: 0;">");
webclient.println("<table bgcolor="#999999" border="0" width="100%" cellpadding="1">");
webclient.println("<font color="white" size="2" face="Verdana">&nbsp Arduino Ethernet Shield setup page
");
webclient.println("<table border="0" width="100%">&nbsppre {font-size:8pt; letter-spacing:2px; line-height:8pt; font-weight:bold;}");
webclient.println("

<font color="#00979d">");
webclient.println(" ### ### TM");
webclient.println(" ## ## ## ## ");
webclient.println(" ## #### # ## ");
webclient.println(" # ### ## ### ## ");
webclient.println(" ## #### # ## ");
webclient.println(" ## ## ## ## ");
webclient.println(" ##### ##### ");
webclient.println("
&nbsp&nbsp");
webclient.println("<font color="#00979d" size="6" face="Verdana"> ARDUINO&nbsp
");
webclient.println("<table bgcolor="#00979d" border="0" width="100%" cellpadding="3">");
webclient.println("<font color="white" size="2" face="Verdana">Network info");
webclient.println("<font color="white" size="2" face="Verdana">Network setup");

break;

}

// If we received a new line character from the client ...
if (c == 'n') {

// Track that the line is blank
current_line_is_blank = true;

// If we don't receive a new line character and don't receive an r
} else if (c != 'r') {

// Track that we we got some data
current_line_is_blank = false;

}

}

}

// Give the client some time to receive the page
// Learn more about delay()
delay(1);

// Close the connection to the client now that we are finished
// Learn more about client.stop()
webclient.stop();

}

}




I still have to clean up the code so it might use less Binary sketch size: 6522 bytes

This time, I managed to get the logo in the website. I had to change it into base64, so I could put into the sketch itself. This is only as a show-off, because it eats memory, so in the later progress I'll probably ditch it.

Thanks to bubulindo in my other post http://arduino.cc/forum/index.php/topic,55064.0.html I'm able to show the network information of the webserver. Only the word "static" is just html.

Oh, and I managed to show free and used SRAM. As you can see, not much left. next thing I'll do is putting things into Flash memory and probably I need to put configuration info into EEPROM memory. So that it survives reboot.

This time I managed to get SRAM down to 493 by feeding the HTML from flash memory piece by piece to SRAM. This has it's consequences, Flash got over 8000 bytes. Next step is using EEPROM for config.

For any followers, this project is in collaboration with this one: http://arduino.cc/forum/index.php/topic,54324.0.html

If your sending your project to someone with no development experience, maybe your dad, or a potential client you've built a prototype for, or your using your Arduino in multiple locations (and not all have DHCP servers), then you just want to be able use the product out of the box on a network, like a home router, plug and play, this will be the solution.

Ok so I already got this far. I have competed the HTML (using PROGMEM to put it into Flashmemory and a buffer to flow the HTML through strait to the webclient)

EEPROM is now being used to save your choices (put getting the info out of the POST doesn't work yet). The sketch starts with pre-sets and puts those into EEPROM, the second time the sketch is run it will know and automatically read out of EEPROM (hence the reset button to clear the "know" bit => not functional yet)

network_page8.pde (15.4 KB)

Looks very promising.

@techadmin: I need your help on getting the information out of the form submission, you know: look for an ? read the what has been filled out.

I've been pretty tied up this week. You'll need to copy that get url into a string or buffer when the html form is submitted then parse the text in the buffer.

I set mine up like this:

#define maxLengthWEB 100
String inString = String(maxLengthWEB);
  if (client) {
    boolean currentLineIsBlank = true;
    while (client.connected()) {     
      if (client.available()) {
        char c = client.read();
                                          
           if (inString.length() < maxLengthWEB) {   
                inString.concat(c);        
           }

After form:

String stringOne = inString;

Then use indexOf to extract the number between the & and = symbols. This is from my code, should be able to modify to work with yours.

        int firstequaltemp = stringOne.indexOf('=');
        int secondequaltemp = stringOne.indexOf('=', firstequaltemp + 1); //firstequal + 1 means the second equal in the get string
        
        int firstandtemp = stringOne.indexOf('&');
        int secondandtemp = stringOne.indexOf('&', firstandtemp + 1);

OK, thanks. I'm busy too. Waiting for our third child to be born this week. That will give me some sleepless nights :sleeping: . But I'll continue the work for sure. 8)

Awesome man, congrats. Yeah, my 2 year old is a hand full, I'll come to my computer and find chunks of code deleted, or added characters, (I make massive code revisions), she broke my N key off, pulls wires, etc, etc.

I have my code working finally, we'll be posting soon and looking at your code again, very nice structure.

Beautiful! xD

I imagine that your problem is the sizes of pages, right?
Ever consider storing the pages in SD Card?
Because that is what I plan to do when I receive my ethernet shield and SD shield :wink:

Anyway, good luck!

Hi, all. Our newborn son Siebe is now 6 days old and doing well. Time to get back to Arduino. :smiley:

@xanok: We know you can use SD, but we don't want to. My final goal is a library for Ethernet Setup. That would make it very easy for other projects to have a network one can easy set up. (more arduino's on the same network)

So It's time to dive into the

#define maxLengthWEB 100
String inString = String(maxLengthWEB);
1 Like

I'm looking into this as well. I am especially interested in using the SD card instead of EEPROM. That way you can create an ini file on the card from another computer that contains all of the settings. Also, the HTML files can be served from the card freeing up that much more memory.

I've got serving html from an SD card working. Now I am working on reading data from the card for ethernet settings and being able to save the settings back to the card.

If there is anyone who has already been down this road I'd rather not reinvent the wheel. :slight_smile:

I finally found out how to read the data out of the URL, so now I can finish this project. I'll dump all html code and restart with a very simple web page.

DHCP or STATIC
IP
MASK
HW

This is now how the setup page will look like (for now). I want to keep memory use as low as possible, so ...

Now I'm off putting the code into arduino.

With this sketch you can already fill out the form and it will stay in the ARduino's memory. You can follow what's happening on the Serial Monitor.

#include <SPI.h>
#include <Ethernet.h>
#include <TextFinder.h>

//CHANGE THIS TO MAKE THIS SKETCH WORK

byte IP1 = 192;//the first part of the IP-address
byte IP2 = 168; //the second part of the IP-address
byte IP3 = 1; //the thirth part of the IP-address
byte IP4 = 2; //the fourth part of the IP-address
byte GW1 = 192; //the first part of the GATEWAY
byte GW2 = 168; //the second part of the GATEWAY
byte GW3 = 1; //the thirth part of the GATEWAY
byte GW4 = 1; //the fourth part of the GATEWAY
byte SUB1 = 255; //first part of the SUBNETMASK
byte SUB2 = 255; //the second part of the SUBNETMASK
byte SUB3 = 255; //the thirth part of the SUBNETMASK
byte SUB4 = 0; //the fourth part of the SUBNETMASK
byte TYPE = 1; //the type is set to 1 = static

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = {IP1,IP2,IP3,IP4};
byte gateway[] = {GW1,GW2,GW3,GW4};
byte subnet[] = {SUB1,SUB2,SUB3,SUB4};
Server server(80);

void setup()
{
  Serial.begin(9600);
  Ethernet.begin(mac, ip, gateway, subnet);
  server.begin();
  Serial.println("ready");
}

void loop()
{
  Client client = server.available();
  if (client) {
    TextFinder  finder(client );
    while (client.connected()) {      
      if (client.available()) {          
        if( finder.find("GET /") ) {
          Serial.println("connection has been made");
          if (finder.findUntil("ST", "\n\r")){
            Serial.println("found static or dhcp");
            TYPE = finder.getValue();
              while(finder.findUntil("DT", "\n\r")){
                int val = finder.getValue(); 
                if(val >= 0 && val <= 3) {
                  ip[val] = finder.getValue();
                }
                if(val >= 4 && val <= 7) {
                  subnet[val - 4] = finder.getValue();
                }
                if(val >= 8 && val <= 11) {
                  gateway[val - 8] = finder.getValue();
                }
              }
            }
            Serial.println();
            if ( TYPE == 1 ){
              Serial.print("type is static");
            }
            if ( TYPE == 2 ){
              Serial.print("type is dhcp");
            }
            Serial.println();
            Serial.print("The IP address is:");
            Serial.print(ip[0],DEC);
            for (int i= 1; i < 4; i++){
              Serial.print(".");
              Serial.print(ip[i],DEC);
            }
            Serial.println();
            Serial.print("The Subnet is:");
            Serial.print(subnet[0],DEC);
            for (int i= 1; i < 4; i++){
              Serial.print(".");
              Serial.print(subnet[i],DEC);
            }
            Serial.println();
            Serial.print("The gateway is:");
            Serial.print(gateway[0],DEC);
            for (int i= 1; i < 4; i++){
              Serial.print(".");
              Serial.print(gateway[i],DEC);
            }
            Serial.println();
          }           
        client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();
          client.print("<html><body><table><form><tr><td>TYPE: <select name=\"ST\">");
          client.print("<option value=\"1\">static</option><option value=\"2\">dhcp</option></select></td></tr>");
          client.print("<tr><td>IP: <input type=\"text\" size=\"1\" maxlength=\"3\" name=\"DT0\" value=\"");
          client.print(ip[0],DEC);
          client.print("\">.<input type=\"text\" size=\"1\" maxlength=\"3\" name=\"DT1\" value=\"");
          client.print(ip[1],DEC);
          client.print("\">.<input type=\"text\" size=\"1\" maxlength=\"3\" name=\"DT2\" value=\"");
          client.print(ip[2],DEC);
          client.print("\">.<input type=\"text\" size=\"1\" maxlength=\"3\" name=\"DT3\" value=\"");
          client.print(ip[3],DEC);
          client.print("\"></td></tr><tr><td>MASK: <input type=\"text\" size=\"1\" maxlength=\"3\" name=\"DT4\" value=\"");
          client.print(subnet[0],DEC);
          client.print("\">.<input type=\"text\" size=\"1\" maxlength=\"3\" name=\"DT5\" value=\"");
          client.print(subnet[1],DEC);
          client.print("\">.<input type=\"text\" size=\"1\" maxlength=\"3\" name=\"DT6\" value=\"");
          client.print(subnet[2],DEC);
          client.print("\">.<input type=\"text\" size=\"1\" maxlength=\"3\" name=\"DT7\" value=\"");
          client.print(subnet[3],DEC);
          client.print("\"></td></tr><tr><td>GW: <input type=\"text\" size=\"1\" maxlength=\"3\" name=\"DT8\" value=\"");
          client.print(gateway[0],DEC);
          client.print("\">.<input type=\"text\" size=\"1\" maxlength=\"3\" name=\"DT9\" value=\"");
          client.print(gateway[1],DEC);
          client.print("\">.<input type=\"text\" size=\"1\" maxlength=\"3\" name=\"DT10\" value=\"");
          client.print(gateway[2],DEC);
          client.print("\">.<input type=\"text\" size=\"1\" maxlength=\"3\" name=\"DT11\" value=\"");
          client.print(gateway[3],DEC);
          client.print("\">.</td></tr><tr><td><input type=\"submit\" value=\"SUBMIT\"></td></tr>");
          client.print("</form></table>
<FORM>");
          client.print("'\"></FORM></body></html>");
          client.print("free test SRAM = ");
          client.print(availableMemory());
          client.print(" / SRAM used = ");
          client.print(2048-availableMemory());
          break;
        }
      }
    delay(1);
    client.stop();
  }
}

int availableMemory()
{
  int size = 2048;
  byte *buf;
  while ((buf = (byte *) malloc(--size)) == NULL);
  free(buf);
  return size;
}

DONE, I managed to make the setup page. I didn't use dhcp or static any longer. Now you can change IP, SUBNETMASK and GATEWAY, but for now you'll have the hard reset. You'll also notice the sketch eats SRAM, which is not good, but you could use a buffer to flow the HTML through it, keeping all the HTML code out of SRAM.

if you want to know how, read this: http://www.jo3ri.be/arduino/arduino-projects/an-integrated-webpage-with-image

here you have the sketch:

network_page11.pde (9.04 KB)

Made it better, follow the link to my project page shown in my very first post Network settings web page FORM using EEPROM to save submit [DONE] - Exhibition / Gallery - Arduino Forum

Hello JO3RI
thankyou or your hard work here, this is exactly what I need to make a PLC network tester, with one small thing missing DHCP/Static choice.
I have been trying, but I can not make this work, it just hangs when DHCP selected. Did you manage to make that work? Why did you remove it?
I have also tried your older code with DHCP but it doesn't seem to stay selected, it changes back to static.
Any help much appreciated