Calling Ethernet.Begin more than once?

Is it possible to change the IP address on the fly, by calling Ethernet.begin at different times? Specifically I am working on a project using an Uno board and the Arduino Ethernet Shield and giving the user a manual interface using a LCD panel and some buttons. Via this interface, they can change the IP address, subnet mask and default gateway to something that would match their network.

I need to figure out how to code a response to a valid IP info set being provided. In other words, do I call Ethernet.begin once a valid set of IP information is provided and then not allow it to be set again (until the board is reset), or after it has been setup and they change the info can I simply reinitialize the Ethernet board with the new information?

Thanks,
Peter

I think the user being able to change the IP is a good thing.

Have you thought about storing the IP in EEPROM. It is not really meant for high cycle read/write, but for storing an IP, and retrieving it on bootup should not be a problem.

Actually storing the last set/used IP information in the EEPROM is on my list of things to code over the next few days, as time permits... (Great minds think alike.. :slight_smile: ) The idea being that on start up it would read that information out and initialize the Ethernet library using those values. However, should the user then change the IP address for any reason, the same issues still comes up - namely can I re-initialize the Ethernet library after it already has been, or do I have to just store those values and force the user to restart the system so the new information can be read back and used?

Unless you plan on doing some modification to the ethernet library, you will need to restart the Arduino. There is a register function that allows the IP to be changed, but I have not tried it, and do not know if it will take effect without a reset.

I would store the values in EEPROM, then let the user change them. When complete, save and then hit the reset button.

Add: The register function is in a part of the code that the casual user/programmer does not use. You would need to add a routine to the user modules (ethernet.cpp or client.cpp) to access that register function.

There may be a way to test if it will work without a reset. Give me a few minutes to check.

Add2: Lucky you! It works! Change the ip and gateway to your localnet, but leave the last digit a '2'. This routine will change the IP from 192.168.1.2 to 192.168.1.3.
Compile and upload this code. Open the IDE serial window, and you will see the new ip as the second line of the output. Then try to ping the new ip.

#include <SPI.h>
#include <Ethernet.h>
#include <utility/w5100.h>

byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x59, 0x66 };  
byte ip[] = { 192, 168, 1, 2 };    
byte gateway[] = { 192, 168, 1, 1 };
byte subnet[] = { 255, 255, 255, 0 };

byte ipBuf[4];
char outBuf[18];

void setup()
{
  Serial.begin(9600);
  Ethernet.begin(mac, ip, gateway, subnet);
  delay(1000);
  W5100.getIPAddress(ipBuf);
  sprintf(outBuf,"%u.%u.%u.%u\r\n",ipBuf[0],ipBuf[1],ipBuf[2],ipBuf[3]);
  Serial.write(outBuf);
  ipBuf[3] = 0x03;
  W5100.setIPAddress(ipBuf);
  delay(1000);
  W5100.getIPAddress(ipBuf);
  sprintf(outBuf,"%u.%u.%u.%u\r\n",ipBuf[0],ipBuf[1],ipBuf[2],ipBuf[3]);
  Serial.write(outBuf);
}

void loop()
{
  Serial.println("Tick");
  delay(1000);
}

I don't usually recommend using the low level functions on the ethernet shield, but you could probably get away with it using the "#include <utility/w5100.h>" and the W5100.setIPAddress() function in your code.

And before you ask, there are a few other routines in there you might need.
W5100.setGatewayIp(ipBuf)
W5100.getGatewayIp(ipBuf)
W5100.setSubnetMask(ipBuf)
W5100.getSubnetMask(ipBuf)

If you have to ask what those functions do, you probably shouldn't be doing this.

Wow, that rocks - exactly what I was looking for! (Of course I understand what those functions do - wouldn't be much of a Network Admin if I did not... :slight_smile: )

Question - I'm still fairly new to the Arduino world, so am always looking to learn new things. Where did you get/find those w5100 routines? Is there some documentation on other such commands I could get?

I figured you would know what they did, or you would not be this far along. I found those routines while tracking down a bug in the ethernet library.

I do not believe there is any "documentation" for it, except for the Wiznet datasheet. Some of the stuff, like those routines, are fairly easy to figure out what they do. Other parts are not as easy. You may find calls to functions there that "don't exist". They do, just not like you expect. They are built with a #define.

Those files are in "/arduino/libraries/Ethernet/" and "/arduino/libraries/Ethernet/utility/". The second one is where the w5100.h and w5100.cpp files are. The good stuff (including those functions) is in w5100.h, oddly enough.

pbako:
Is it possible to change the IP address on the fly, by calling Ethernet.begin at different times?

Yes.

Ethernet.begin() completely resets the Ethernet chip and starts from zero.

Thanks, fungus. That is good to know. I was not certain if that would bugger up the works or not.

I am used to working with stuff that will create a second instance of a routine if you call an init() function more than once, and with this limited memory, that would not be good.