DHCP/ Static settings [SOLVED]

Hi,

First time poster so be gentle!

I’m trying to make a device which the user can set network settings on via an I2C OLED display.

I wrote a small sketch utilising a switch function, to try and allow a single variable change to switch between Ethernet initialising with either just a MAC address (for DHCP) or with MAC, IP and Subnet (for static IP).

However I can’t get the sketch to compile. I’m aware that sketches compiled with DHCP settings are much larger than those with static and suspect this has something to do with it.

My sketch is included below.

Been compiling for a Mega 2560.

Is what I’m trying to do here at all possible, either by the method I’ve tried so far or something else entirely?

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

byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
IPAddress ip(192, 168, 1, 100);
IPAddress subnet(255, 255, 255, 0);


void setup() {
int y = 2; // 1 for DHCP, 2 for Static
Serial.begin(9600);
ethernetType(y);

}

void loop() {
  // put your main code here, to run repeatedly:
}

void ethernetType( int y ) {
  switch(y) {

    case 1:
    Ethernet.begin(mac);
    Serial.println("Initialising Ethernet with DHCP...");
    Serial.print(Ethernet.localIP());
    break;

    case 2:
    Ethernet.begin(mac, ip, subnet);
    Serial.println("Initialising Ethernet with static IP...");
    Serial.print(Ethernet.localIP());
    break;
    
  }
}

Kudos on using code tags in your first post but you missed two other important bits of information.

1) Which Arduino 2) Which error messages

For #2 you need to enable verbose output for the compile phase and then then copy and paste the output into another code window.

it compiles

use the begin() function with only mac and ip address and the library will guess the dns, gateway and mask or set all static parameters

https://github.com/arduino-libraries/Ethernet/blob/4f4ac17f296f5ffbe869730db88265ddc3e4fc15/src/Ethernet.h#L88

Hi all,

Thanks for the replies.

I decided I had become too muddled with my code before and started from scratch. AND IT WORKS!

Moving pin 22 between 5V and GND then resetting the arduino will switch it between initialising ethernet in either DHCP or Static modes. Code is below if anyone want to see.

Thanks!

#include <Ethernet.h>

int switchPin = 22;
int switchVariable;

byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
IPAddress ip(192, 168, 1, 100);
IPAddress subnet(255, 255, 255, 0);


void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(switchPin, INPUT_PULLUP);

  if (digitalRead(switchPin) == HIGH) {
    switchVariable = 0;
  } else {
    switchVariable = 1;
  }
switcher(switchVariable);
}

void loop() {
  // put your main code here, to run repeatedly:

  

}

void switcher (int switchVariable) {
  switch (switchVariable) {
    case 0:
    Serial.println("Ethernet initializing with DHCP");
    Ethernet.begin(mac);
    Serial.println("Ethernet successfully initialized with DHCP");
    Serial.println(Ethernet.localIP());
    delay(1000);
    break;

    case 1:
    Serial.println("Ethernet initializing with static IP");
    Ethernet.begin(mac, ip, subnet);
    Serial.println("Ethernet successfully initialized with static IP");
    Serial.println(Ethernet.localIP());
    delay(1000);
    break;
    
  }
}

the third parameter of begin() is DNS server not network mask

Juraj: the third parameter of begin() is DNS server not network mask

DNS, Gateway and Subnet are all optional parameters are they not?

cs75: DNS, Gateway and Subnet are all optional parameters are they not?

no. there are 4 methods

        static void begin(uint8_t *mac, IPAddress ip);
    static void begin(uint8_t *mac, IPAddress ip, IPAddress dns);
    static void begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway);
        static void begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet);

there are no optional parameters in C/C++, because you can't name which one you set. (there are parameters with default values, but the ordering of parameters must be respected https://www.learncpp.com/cpp-tutorial/77-default-arguments/)

So if I want DNS and gateway to default to the set IP with the last octet set to 1 (like it says in the Ethernet.begin reference) do I just declare those variables but leave them blank?

eg;

IPAddress dns();
IPAddress gateway();

cs75: So if I want DNS and gateway to default to the set IP with the last octet set to 1 (like it says in the Ethernet.begin reference) do I just declare those variables but leave them blank?

eg;

IPAddress dns();
IPAddress gateway();

no, you use begin(mac, ip)

So there is no way to set the MAC, IP and subnet without also setting DNS and gateway manually?

cs75: So there is no way to set the MAC, IP and subnet without also setting DNS and gateway manually?

no way. but what is the problem to set them? the library sets if not specified, gw and dns to the same ip address ending with 1

https://github.com/arduino-libraries/Ethernet/blob/4f4ac17f296f5ffbe869730db88265ddc3e4fc15/src/Ethernet.cpp#L57

So what you just said there- the library sets if not specified

Under what circumstances are the variables considered not specified so that the library sets them?

cs75: So what you just said there- the library sets if not specified

Under what circumstances are the variables considered not specified so that the library sets them?

the link is to source code. see it yourself

Okay so here is my solution;

I changed the declaration of ip, subnet, gateway and dns to byte arrays. I do not declare any values for the dns and gateway arrays initially.

In setup I call a function called dnsGateway() which sets the first three bytes of each array to whatever the ip is set to, then sets the last octet of each to 1.

Not sure it’s the most elegant but it works!

#include <Ethernet.h>

int switchPin = 22;
int switchVariable;
int dhcpActive;

byte mac[6] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
byte ip[4] = {192, 168, 2, 187};
byte subnet[4] = {255, 255, 255, 0};
byte dns[4];
byte gateway[4];


void setup() {

  Serial.begin(9600);
  pinMode(switchPin, INPUT_PULLUP);

  dnsGateway();

  if (digitalRead(switchPin) == HIGH) {
    switchVariable = 0;
  } else {
    switchVariable = 1;
  }
  switcher(switchVariable);

  Serial.println();
  Serial.println("Switcher exited");
  Serial.println("---------------------------------------");
  Serial.println();
}



void loop() {

  if (dhcpActive == 0) {
    dchpMaintain();
    Serial.println("---------------------------------------");
    Serial.println("Running DHCP Maintain");
    Serial.println("---------------------------------------");
  }
}




void switcher (int switchVariable) {
  switch (switchVariable) {
    case 0:
      Serial.println("---------------------------------------");
      Serial.println("Ethernet initializing with DHCP");
      Ethernet.begin(mac);
      Serial.println("Ethernet successfully initialized with DHCP");
      Serial.print("IP address = ");
      Serial.println(Ethernet.localIP());
      Serial.print("Subnet Mask = ");
      Serial.println(Ethernet.subnetMask());

      dhcpActive = 0;
      delay(1000);
      break;

    case 1:
      Serial.println("---------------------------------------");
      Serial.println("Ethernet initializing with static IP");
      Ethernet.begin(mac, ip, dns, gateway, subnet);
      Serial.println("Ethernet successfully initialized with static IP");
      Serial.print("IP address = ");
      Serial.println(Ethernet.localIP());
      Serial.print("Subnet Mask = ");
      Serial.println(Ethernet.subnetMask());


      dhcpActive = 1;
      delay(1000);
      break;

  }
}


int dchpMaintain () {
  Ethernet.maintain();
  Serial.println("Running DHCP Maintain");
  delay(1000);
  //return(Ethernet.maintain);
}

void dnsGateway () {
  dns[0] = ip[0];
  dns[1] = ip[1];
  dns[2] = ip[2];
  dns[3] = 1;

  gateway[0] = ip[0];
  gateway[1] = ip[1];
  gateway[2] = ip[2];
  gateway[3] = 1;
}

why not?: IPAddress dns = ip; dns[3] = 1;

Even better! Thanks

Declarations now look like this;

byte mac[6] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
byte ip[4] = {192, 168, 2, 187};
byte subnet[4] = {255, 255, 253, 0};
IPAddress dns[4];
IPAddress gateway[4];

And the dnsGateway function looks like this;

void dnsGateway () {

  IPAddress dns = ip;
  dns[3] = 1;

  IPAddress gateway = ip;
  gateway[3] = 1;
  
}

cs75: Even better! Thanks

you didn't check the source code of the library? I copied it from there

I did, which was where I got the idea for my first version from but I couldn't get it to work that way at first. Not sure what I was doing wrong.