Dynamically changing IP address of Ethernet Shield (not DHCP and without reboot)

I was doing some searching through the forums (the links are listed below). And I have a question, is it possible to dynamically change the IP address of the Ethernet Shield without saving the saving the IP to the EEPROM and rebooting/reseting the Arduino?

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

I would like to change the IP address of the Arduino via a separate host (which is not DHCP server). Similar to DHCP, Arduino would boot and starts listening on the broadcast IP address, once it receives configuration information, it would change to specified IP and and would start operating based on parameters in the configure it received. So far, the only way it seems possible to change the IP address is to reboot the entire Arduino, which seems a little excessive for something as simple as an IP change.

Thank you,
Aaron

You will need to statically address your device

Ethernet.begin(mac, ip, gateway, subnet);

all arguements are byte arrays see documentation at: http://arduino.cc/en/Reference/EthernetIPAddress

What happens if there are subsequent calls to Ethernet.begin?

Cylindric: What happens if there are subsequent calls to Ethernet.begin?

With static assignment, the ip changes to the new ip sent to Ethernet.begin(). I have tested that.

I have not used the dhcp service yet. Maybe you could try that? :)

FWIW: Even tho it will do that, some routers, and especially my cablemodem, do not like this. If I use another ip with that mac, it will take several hours for the new ip to use the cablemodem.

LamboAlpha: Arduino would boot and starts listening on the broadcast IP address, once it receives configuration information, it would change to specified IP and and would start operating based on parameters in the configure it received.

Can you clarify this a bit? What is being broadcast? Are you trying to pick up some sort of arbitrary data packets? Is the 'other device' doing UDP broadcasts?

LamboAlpha: So far, the only way it seems possible to change the IP address is to reboot the entire Arduino, which seems a little excessive for something as simple as an IP change.

According to SuferTim, you do not need to reboot the arduino - you can just call Ethernet.begin() again with some new IP address - I'm still not sure how you're getting this new address delivered.

Hi Cylindric.

That first part is dhcp. Why re-invent the wheel?

The second part (changing static ips) I tested with the serial I/O. I used a trigger character (my favorite is ‘e’) entered in the serial monitor to call Ethernet.begin() again (this time in loop, not setup) to change the ip. It takes a couple seconds to change after sending the new ip. I use a delay(2000) after the change. Then you should be able to ping the new ip.

Well sure, that's what I would use, but I'm asking the OP, as he seems to be specifically NOT wanting to use DHCP.

Cylindric: Well sure, that's what I would use, but I'm asking the OP, as he seems to be specifically NOT wanting to use DHCP.

I know. For specifically not wanting to use it, the OP did describe dhcp quite well. :)

If the OP uses Ethernet.begin() correctly, it should not be too difficult to accomplish that. I did not test how the web client or server code responds to the ip change, just tested the ping.

Thank you, ajofscott, Cylindric and SurferTim,

I had try placing a Ethernet.begin statement into the loop. I did try it again, and I can ping the new IP address, but it does not respond to any incoming packets. I have setup a counter and have it printing to the debugging port. I know that the Arduino is still functional and not resetting or hanging. I am not sure what is wrong with my implementation or otherwise. I am using UDPSendReceive sketch as basis. I have only added a counter (which is being printed to the debugging port) and a loop which changes the IP address once it receives a packet.

I answer the questions, I am trying not to use DHCP because I am also passing other configuration information to the Arduino. I am trying to get it to get it to send a broadcast, which is a configuration request. It would then listen to all broadcast packet and once it has received the configuration information (which contains an IP address and other information) the Arduino would start operating based on that configuration, which also include changing of IP address.

Side note, I never realized that closing/disconnecting the bugging port and reopening/reconnecting it resets the Arduino.

Thank you.

I gather this configuration server is custom?

Yes, it is custom server/setup. I had thought about saving the IP address to EEPROM and then reset/reboot the Arduino based on the saved configuration information. However, I wondered if it would be possible to change the IP address of Arduino while running.

I don’t see where you say what chip you are using for your ethernet shield, but if it is the w5100 chip, you might study the data sheet for that chip, and the code in the ethernet and DHCP librarys. The IP address array is obviously stored in some particular memory location, so if you identify that location you should be able to chang what is stored there as desired.

I just tested the web server, and it works with the new ip. I restarted the server tho. Upload and open the serial monitor. Check the server on the first ip (192.168.0.2). Then press ‘e’ and enter on the serial monitor. Check the second ip (192.168.0.3).
Here is the code:

// Web server test for IDE V1.0 only.
#include <SPI.h>
#include <Ethernet.h>

// change network settings to yours
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip( 192,168,0,2 );
IPAddress ip2( 192,168,0,3 );

IPAddress gateway( 192,168,0,1 );
IPAddress subnet( 255,255,255,0 );
IPAddress dns( 192,168,0,1 );

EthernetServer server(80);

void setup()
{
  Serial.begin(9600);
  pinMode(4,OUTPUT);
  digitalWrite(4,HIGH);
  Ethernet.begin(mac, ip, dns, gateway, subnet);
  delay(2000);
  server.begin();
  Serial.println("Ready");
}

char outBuf[256];

void loop()
{
  while(Serial.available())
  {
    char c = Serial.read();
  
    if(c == 'e')
    {
      Serial.println("Changing ip");
      Ethernet.begin(mac,ip2,dns,gateway,subnet);
      delay(2000);
      server.begin();
      Serial.println("Changed");
    }
  }
 
  // listen for incoming clients
  EthernetClient client = server.available();
  if(client) {
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    Serial.println("Client");
    
    while (client.connected()) {
      while(client.available()) {
        char c = client.read();
        if (c == '\n' && currentLineIsBlank) {
          // send a standard http response
          Serial.println("Sending response");
          client.write("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n<html><body><H1>TEST</H1></body></html>\r\n");
          client.stop();
        }
        if (c == '\n') {
          currentLineIsBlank = true;
        } 
        else if (c != '\r') {
          currentLineIsBlank = false;
        }
      }
    }
    
    Serial.println("done");
  }
}

LamboAlpha: Yes, it is custom server/setup. I had thought about saving the IP address to EEPROM and then reset/reboot the Arduino based on the saved configuration information. However, I wondered if it would be possible to change the IP address of Arduino while running.

Yes you CAN.... BUT If you have any: server.begin() Client.begin() Then you need to close them down before re-issuing the IP address via Ethernet.begin() Specifically because the Ethernet.begin(), completely re-initialises the ethernet chip and so if you have any outstanding connections or buffers things could get very messy,unless your code is absolutely bullet proof.

Really it is quite poor for the library to bitch slap the whole ethernet chip just to change an IP address, and the question would be what happens if you are on a network where you use DHCP and the DHCP issues a renewable IP address that is only valid for 60 minutes, the ethernet data-sheet does not specifically exclude reconfiguration of (GAR,SHAR,SUBR & SIPR), after the initialization of the chip so really these functions should be split out in the library.

HC

@hardcore: I'll go with the "bitch slap". It works. Are you offering an alternative? Or just venting?

This is open source. You know where the code is. Code it up. Debug it. Submit it here: http://code.google.com/p/arduino/

Thanks for volunteering! :)

As for offering 'alternatives' please take a look at my work on the TWS & the linux Kernel, to name a couple.

Thanks for your previous contributions, but I don't see how that helps the OP in this case.