Set/Change IP Address Web Form - Ethernet Shield

@robtillaart

I know :slight_smile: But it really helps to write down this kinds of things. Otherwise I get lost in my own coding :~

Update: 1st through 3rd IP octet is not saving correctly. Working on a fix.

Meanwhile I found out your working on a different Arduino version (mine is 0.22) also I have the new Arduino Ethernet Shield. But the Idea remains the same.

FYI: I thanks to your sketch, I managed to use EEPROM for storing mac, ip, gw, sub and type (static, dhcp or unknown) and showing this info in the webpage.

The sketch starts with setting the pre-sets the first time and writes a knowing bit. The next time it runs, the sketch doesn't use pre-sets, but reads EEPROM: when type is stored as static, it takes static otherwise it takes dhcp.

Now I need to work on the GET forms in html. I haven't found out how to do that yet, but I'll get there.

I am using 022? Sounds like good progress.

Ah, then it must be a different Ethernet Shield. :slight_smile:

Now you're sending HTML in a different way then I do, I use:

Client.print("some text or other HTML code");

Now I was hoping to get help out of your sketch for the forms part, but I can't :~

I'll have to figure it out myself :frowning:

I started with client.print as well and used all of the SRAM doing so.

My sketch is using the Flash library which easily puts all that html into program memory, dramatically improving performance.

Aha, I See. Well I found a way to do the same, but I'm using the avr/pgmspace.h library. This way I can put every thing in The Flash Memory with PROGMEM and I let it flow through a buffer of let's say 100 bytes (SRAM).

This should mean I could use your HTML code for the forms. Could you filter them out and post them? Especially t he part where you get the info out of the forms.

Thanks.

Here is the basic form, you will see from my code that these are simply wrapped in

client << F("       ") << "\n";

You can accomplish the same with Progmem, not sure which is more memory efficient. I struggled freeing memory for a while and this worked best for me, at least it seemed the easier method. I will be interested to see your take on this as well.

When the form is posted, a get string is created such as this:

http://172.31.1.50/?i1=172&i2=31&i3=4&i4=50&s1=255&s2=255&s3=255&s4=0&g1=172&g2=31&g3=1&g4=1&END=END

That string is saved to inString initially then to stringOne:

String stringOne = inString;

For substring processing I am using indexOf to find the number between all of the & and = symbols.

//////////////     CHANGE IP ADDRESS FORM /////////////////////////////////////////////////////



<B>Change IP Address:</B>

<form name=\"changeipaddress\" action=\"\" method=\"get\">
<TABLE width=\"325\">
<tr>     
<td>IP Address:</td>     
<td><input type=\"text\" size=\"3\" maxlength=\"3\" name=\"i1\" value=\"172\"></td>     
<td><input type=\"text\" size=\"3\" maxlength=\"3\" name=\"i2\" value=\"31\"></td>     
<td><input type=\"text\" size=\"3\" maxlength=\"3\" name=\"i3\" value=\"1\"></td>     
<td><input type=\"text\" size=\"3\" maxlength=\"3\" name=\"i4\" value=\"50\"></td>     
</tr>

<tr>
<td>Subnet Mask:</td>     
<td><input type=\"text\" size=\"3\" maxlength=\"3\" name=\"s1\" value=\"255\"></td>     
<td><input type=\"text\" size=\"3\" maxlength=\"3\" name=\"s2\" value=\"255\"></td>     
<td><input type=\"text\" size=\"3\" maxlength=\"3\" name=\"s3\" value=\"255\"></td>     
<td><input type=\"text\" size=\"3\" maxlength=\"3\" name=\"s4\" value=\"0\"></td>     
</tr>

<tr>
<td>Gateway:</td>     
<td><input type=\"text\" size=\"3\" maxlength=\"3\" name=\"g1\" value=\"172\"></td>     
<td><input type=\"text\" size=\"3\" maxlength=\"3\" name=\"g2\" value=\"31\"></td>     
<td><input type=\"text\" size=\"3\" maxlength=\"3\" name=\"g3\" value=\"1\"></td>     
<td><input type=\"text\" size=\"3\" maxlength=\"3\" name=\"g4\" value=\"1\"></td>     
<td><input type=\"hidden\" size=\"3\" maxlength=\"3\" name=\"END\" value=\"END\"></td>     
</tr>
         //notice the hidden form element placed in order to create a final "&" character in the get string

<tr>
<td align=\"center\" colspan=\"5\"><input type=\"submit\" value=\"Update Network Configuration\"></td>
</tr>     

<tr>
<td align=\"center\" colspan=\"5\">*After changing IP address
change url in browser</td>
</tr>     
</TABLE>     
</form>

For any followers, this project is in collaboration with this one: http://arduino.cc/forum/index.php/topic,55044.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.

The revised web form code is now working properly (for me at least), see attachments.

Network_Settings_Form.pde (21 KB)

techadmin:
The revised web form code is now working properly (for me at least), see attachments.

To bad it doesn't work on my Uno and latest ethershield (microSD reader).
Can't ping the IP adres.

If I Disabling these settings I can ping the arduino but can't access the webpages:

//EEPROM address to array
// byte mac[6] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
// byte ip[4] = { ipAaddress_READ, ipBaddress_READ, ipCaddress_READ, ipDaddress_READ };
// byte gateway[4] = { gwAaddress_READ, gwBaddress_READ, gwCaddress_READ, gwDaddress_READ };
// byte subnet[4] = { subnetAaddress_READ, subnetBaddress_READ, subnetCaddress_READ, subnetDaddress_READ };

byte mac[6] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

Do you have multiple Arduino's with the same MAC address? if so change them asap as they should be unique,

just a thought.

robtillaart:

byte mac[6] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

Do you have multiple Arduino's with the same MAC address? if so change them asap as they should be unique,

just a thought.

Sorry No just one. :~

I found out that the program always jumps to void mkmethernetRESET().
Because I haven't set a new IP address the EEprom values are wrong.
I forced the program to jump to void mkmethernetDEFAULTS().
Now I get only a blank page and I can ping the Arduino.

I've been swamped and haven't had much time for further revisions of this. mkmethernetDEFAULTS() may need to do an EEPROM.write to set initial values. If your jumping straight to mkmethernetRESET(), then at some point EEPROM address 1000 had the value "199" written to it.

I was using UNO w/ the latest shield when I tested it last, however I may have statically written an IP address to EEPROM at some point initially and during a couple dozen reflashes working through the code.

Also, my Ethernet.cpp file now looks like this:

#include "w5100.h"
#include "Ethernet.h"

// XXX: don't make assumptions about the value of MAX_SOCK_NUM.
uint8_t EthernetClass::_state[MAX_SOCK_NUM] = { 
  0, 0, 0, 0 };
uint16_t EthernetClass::_server_port[MAX_SOCK_NUM] = { 
  0, 0, 0, 0 };

void EthernetClass::begin(uint8_t *mac, uint8_t *ip, uint8_t *gateway, uint8_t *subnet)
{
  W5100.init();
  W5100.setMACAddress(mac);
  W5100.setIPAddress(ip);
  W5100.setGatewayIp(gateway);
  W5100.setSubnetMask(subnet);
}

EthernetClass Ethernet;

Changing the file might make no difference.

is there any better way to get from the string to an int than going through the following process?:

int nA_IP;
char Aarray[4];
ipA_string.toCharArray(Aarray, sizeof(Aarray));
nA_IP = atoi(Aarray);

It seems very clunky. I think I will at least put that into a function instead of having to go through the process 36 times for ip, subnet and gateway.

Somebody just posted the below which might be worth a look.

From version IDE 22 the String Class has a toInt() operator returning a long.

so something like :

String s = "12345";
long x = s.toInt();

should work

I just made this function. It works great so far . . . I haven't had time yet to really test or debug though.

/*************************** sToi Function *************************************
 ** This function takes in a string and returns an int.  Arguments are a      **
 ** string to process, and the location in the string of the information you  **
 ** want (using substring notation)                                           **
 *******************************************************************************/

int sToi (String & a, int x, int y){
  int tempArraySize = y - x + 1;
  int outPut;
  char tempArray[tempArraySize];
  String tempString = a.substring(x,y);
  tempString.toCharArray(tempArray, sizeof(tempArray));
  outPut = atoi(tempArray);
  return outPut;
}


/*****************************************************************************
 *****************************************************************************/

Here is how I call the function
yourIntNameHere = sToi(yourStringNameHere,13,16);

Hope that helps other people.

Got my own project for networking setup working now:

http://arduino.cc/forum/index.php/topic,55044.0.html

now we only need to find a way to soft reset the arduino's

pls help me to change my ntp server ip