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

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

Hi vk5oi,

thanks for trying out my code, now for your question.

There is a reason why I ditched DHCP. for DHCP you'll need the Arduino IDE above 1.0, but when you do, it will not compile because it's confusing DNS for some reason (I don't really know why) and it only is with the byte DNS[] = { , , , }

Now in my code you won't find anything on DNS, but I have been working on this thing for other projects and there it has DNS included (needed for things like twitter lookups). Maybe I should continue my work on this and include a choice on DHCP/STATIC. But I'll have to figure out how to get it working on the new IDE.

this is actually how those setup pages look at this moment:

from my project CastDuino (CastDuino Slave): http://www.jo3ri.be/arduino/projects/castduino

from my project DUAL TANK LEVEL MEASURING: http://www.jo3ri.be/arduino/projects/tank-level-measuring-basic

Now if you're willing to help, I could update the code so you have the choice between static and DHCP.

I need to know some things:

  • do you need other webpages (look at those screenshots, you'll see more pages for your own stuff)
  • do you need that fancy layout (or do you want minimalistic)
  • what Arduino IDE are you using?
  • do you need the DNS ip (without it, it might be quiet simple to add dhcp support)

Hello J03RI
sorry for the delay, life interferes with my fun.
Thanks again, for your work, this is (nearly) perfect for me but I could not possibly achieve this alone. Somehow I just can not get the details right.
To answer your questions.

I need only 1 page, just setup, I will use also an LCD to display IP, Gateway, connection to server (ping) ok, if DHCP or Static etc.
The fancy layout is nice, but I need only basic form for entering data.
I can use IDE 1.0 or 1.0.1
I don't think I need DNS, but...maybe to make my ping function work (for example ping www.google.com) to test internet connectivity.

I hope this is ok? I can try to explain my application further if you need, but what you have done is so close except for DHCP/Static.

Cheers, and thanks
John

I hope this is ok? I can try to explain my application further if you need, but what you have done is so close except for DHCP/Static

.

Ok, I'll continue my work and add dhcp/static switch, but you'll have to give me time.

1 more question. What has to be default? Static or dhcp. You'll have to consider a lot, before deciding.
2nd extra question. Does it have to save settings into EEEprom? Once done, you can't fall back on a simple reset button to go back to default settings (or has this to be a possible selection: save to eeprom/don't save to eeprom)
3th question: why don't I make separate program for your needs, but then I need full explanation of your project, better email about it and we'll work together. info at JO3RI.be

Hi J03RI
Please take all the time you need, I am the one who needs help, I can wait, no problems.
I think I will email, and explain the idea fully.

Cheers
John

Hello JO3RI

thanks for sharing your work!

I used your Webpage with some modifications in my project. Basically, I want to be able to change IP address from browser, transmit some simple data, and have some sensor readings.

I encountered strange bahaviour: first time I load "setup" page, and submit form data, everything works as expected. However, if I use same form to submit data again, values from first submit get transferred. After third try, data from second time finally arrives and so on. Some research showed, that parser gets all values twice: from the form (or request URL) itself, and from "referer" field.

In other words: After we press "submit" button, we also see all form contents in URL in our browser. Next time we press button, we send new form data again, and once more old data as referring URL.

The reason for the bug is that terminate expression in findUntil is wrong, and it leads to referer being parsed. According to Wiki the request line and headers must all end with /r/n. And that's what I see in Wireshark. Now, you look for /n/r, i.e. other way around. I guess, you just took example from TextFinder manual, which was wrong.

I hope I understand everything right. Feel free to correct me, if it's not the case.

Hi AntonG,

Thanks man and you are right. Some time ago, I made an other sketch (a better one) that I'm using in all, but I should make a new one, basic for other people to use, I know and I will. Just need more time.

Have fun and take a look at my other projects: http://www.jo3ri.be

Wow, this sketch goes 99% of the way I need to go for a project i just started working on.

Unfortunately, when I try to compile it in IDE 1.0.1 on Fedora, I get a TON of compilation errors:

hack.cpp:59:1: error: 'prog_char' does not name a type
hack.cpp:60:1: error: 'prog_char' does not name a type
hack.cpp:61:1: error: 'prog_char' does not name a type
hack.cpp:62:1: error: 'prog_char' does not name a type
hack.cpp:63:56: error: variable 'string_table0' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
hack.cpp:63:61: error: 'htmlx0' was not declared in this scope
hack.cpp:63:69: error: 'htmlx1' was not declared in this scope
hack.cpp:63:77: error: 'htmlx2' was not declared in this scope
hack.cpp:63:85: error: 'htmlx3' was not declared in this scope
hack.cpp:65:1: error: 'prog_char' does not name a type
hack.cpp:66:1: error: 'prog_char' does not name a type
hack.cpp:67:1: error: 'prog_char' does not name a type
hack.cpp:68:1: error: 'prog_char' does not name a type
hack.cpp:69:1: error: 'prog_char' does not name a type
hack.cpp:70:1: error: 'prog_char' does not name a type
hack.cpp:71:1: error: 'prog_char' does not name a type
hack.cpp:72:1: error: 'prog_char' does not name a type
hack.cpp:73:56: error: variable 'string_table1' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
hack.cpp:73:61: error: 'htmla0' was not declared in this scope
hack.cpp:73:69: error: 'htmla1' was not declared in this scope
hack.cpp:73:77: error: 'htmla2' was not declared in this scope
hack.cpp:73:85: error: 'htmla3' was not declared in this scope
hack.cpp:73:93: error: 'htmla4' was not declared in this scope
hack.cpp:73:101: error: 'htmla5' was not declared in this scope
hack.cpp:73:109: error: 'htmla6' was not declared in this scope
hack.cpp:73:117: error: 'htmla7' was not declared in this scope
hack.cpp:75:1: error: 'prog_char' does not name a type
hack.cpp:76:1: error: 'prog_char' does not name a type
hack.cpp:77:1: error: 'prog_char' does not name a type

Can someone point me in the right direction?

Hi there,

Using IDE 1.0.1 You'll need the pgmspace.h library: PROGMEM - Arduino Reference

But you will encounter other problems to, better is to upgrade to IDE 1.0.3 (no need to look for pgmspace.h library) or higher and you should be ready to continue

hi
i know this is an old post but is there any way that you can fix your sketch?
won`t work on 1.6.3
thank you