ESP32 Arduino: Set static IP address

In this tutorial we are going to learn how to setup a static IP address for our ESP32, using the Arduino core. The tests from this tutorial were done using a DFRobot’s ESP32 module integrated in a ESP32 development board.

Introduction

In this tutorial we are going to learn how to setup a static IP address for our ESP32, using the Arduino core.

When we connect the ESP32 to a WiFi network without providing a static address, there’s no guarantee we will always obtain the same local IP address. This happens because, in that case, the ESP32 will use the services of a DHCP provider to get its address.

DHCP (Dynamic Host Configuration Protocol) is a network management protocol where a DHCP server dynamically assigns IP addresses and other network configuration parameters to each device of the network [1]. DHCP is very useful since it avoids the need for a network administrator to manually provide IP addresses to all the devices of the network [1]. In home networks, it is typically the router that acts as a DHCP server [2].

So, as already mentioned, the ESP32 will act as a DHCP client to obtain its local IP address.

It’s important to take in consideration that the DHCP server can also provide additional parameters for the client configuration [1][3]:

  • Subnet Mask – a Subnet mask is a 32-bit number that masks an IP address, and divides the IP address into network address and host address [4].
  • Gateway address – in a typical home network, this corresponds to the IP address of the router, which is the device that connects the local network to the Internet [5].
  • DNS IP address – IP address of the domain name server.

All these parameters are important for the ESP32 to correctly reach other devices inside the network and also outside the network.

When we set a static IP address, the ESP32 doesn’t use DHCP to get these parameters, as can be seen in the implementation of the begin method (the method we use to connect to the network).

Consequently, we will need to pass these network configuration parameters to the method we use to set a static IP for the ESP32. We should use correct parameters or some functionalities may not work. For example, if we don’t set the DNS server IP correctly, it will not be possible to do the resolution of names into IP addresses and trying to send a simple ping to a domain will fail.

So, the first thing we will do is connect our ESP32 to the WiFi network without setting a static IP address. That way, it will use the DHCP protocol to fetch the correct network configuration parameters, which we will print to the serial monitor.

Then, after having the correct ones for our network, we will set the static IP address of the ESP32 but keeping the remaining network parameters correct. Note that you should use an IP address that is available in your network.

The code shown on this tutorial is based on the example from the Arduino core, which I encourage you to try.

The tests from this tutorial were done using a DFRobot’s ESP32 module integrated in a ESP32 development board.

If you prefer a video tutorial, please check the video below.

Finding the network parameters

In this section we will connect the ESP32 to the WiFi network without providing any static IP. Thus, as explained in the previous section, the ESP32 will obtain the network parameters using the DHCP protocol.

So, it is expected that all the parameters that the ESP32 will obtain are correct for the network and that we can use them later when assigning a static IP to the ESP32.

We will start by including the WiFi.h library, which will expose the WiFi extern variable. This variable not only allows us to connect the ESP32 to a network but also allows to access some of its configuration parameters.

#include <WiFi.h>

Then we will define two variables that will hold the WiFi network credentials: network name and password.

const char* ssid = "yourNetworkName";
const char* password =  "yourNetworkPass";

Moving on to the Arduino setup, we will start by opening a serial connection and then we will connect the microcontroller to the WiFi network,

Serial.begin(115200);

WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print("Connecting...\n\n");
}

Then we will obtain the network parameters. We will start by obtaining the local IP assigned to the ESP32 with a call to the localIP method on the WiFi extern variable.

Serial.print("Local IP: ");
Serial.println(WiFi.localIP());

To obtain the subnet mask, we simply need to call the subnetMask method.

Serial.print("Subnet Mask: ");
Serial.println(WiFi.subnetMask());

For the gateway IP address, we can call the gatewayIP method.

Serial.print("Gateway IP: ");
Serial.println(WiFi.gatewayIP());

To get the main and backup DNS server IP addresses, we can call the dnsIP method, passing as input the values 0 and 1, respectively.

Serial.print("DNS 1: ");
Serial.println(WiFi.dnsIP(0));
Serial.print("DNS 2: ");
Serial.println(WiFi.dnsIP(1));

The complete code can be seen below.

#include <WiFi.h>

const char* ssid = "yourNetworkName";
const char* password =  "yourNetworkPass";
   
void setup(){
  Serial.begin(115200);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print("Connecting...\n\n");
  }

  Serial.print("Local IP: ");
  Serial.println(WiFi.localIP());
  Serial.print("Subnet Mask: ");
  Serial.println(WiFi.subnetMask());
  Serial.print("Gateway IP: ");
  Serial.println(WiFi.gatewayIP());
  Serial.print("DNS 1: ");
  Serial.println(WiFi.dnsIP(0));
  Serial.print("DNS 2: ");
  Serial.println(WiFi.dnsIP(1));
}
   
void loop(){}

To test the code, simply change the network name and password placeholders on the code to your network credentials. The expected result can be seen in figure 1. Naturally, the values for your network will most likely differ from mine.

As can be seen, the IP address assigned to my device by the DHCP server gets printed. Additional, we can see the subnet mask, the gateway IP and both DNS server IPs. Except for the local IP, we will use the remaining parameters in the next section.

Output of the program, showing the network parameters obtained from the DCHP server.
Figure 1 – Output of the program, showing the network parameters obtained from the DCHP server.

Setting a static IP for the ESP32

Like before, we will start by importing the WiFi.h library. We will also import the ESP32Ping.h library, to confirm we can still reach a server outside our network after setting a static IP address for the ESP32.

#include <WiFi.h>
#include <ESP32Ping.h>

Then we will define two variables with the WiFi network credentials.

const char* ssid = "yourNetworkName";
const char* password =  "yourNetworkPass";

Now we are going to define some objects of class IPAddress to hold the network parameters we need to configure:

  • Static IP to assign to the ESP32;
  • Gateway IP;
  • Subnet Mask;
  • DNS server IP (same variable will be used for main and backup server since, as we have seen in the previous section, the values are equal for my network).
IPAddress staticIP(192, 168, 1, 150);
IPAddress gateway(192, 168, 1, 254);
IPAddress subnet(255, 255, 255, 0);
IPAddress dns(192, 168, 1, 254);

Note that I’ve assigned the value 192.168.1.150 for the IP address of my ESP32. It is in the same subnet obtained before. Also, it is an IP address that is not being used by any other device in my network.

Also, don’t forget to use the network parameters you have obtained by running the code from the previous section, which will most likely differ from mine.

Moving on to the Arduino setup, we will start by opening a serial connection, to output the results of the program.

Serial.begin(115200);

Then we will call the config method on the WiFi extern variable to setup the previously defined network parameters. Note that, by doing this, DHCP won’t be used, like already mentioned before.

The order of the parameters is the following:

  • Static IP address for the ESP32
  • Network Gateway IP
  • Subnet mask
  • Main DNS server
  • Backup DNS server

Since this method returns a Boolean value indicating if the configuration was done correctly or not, we will use this value for error checking.

if (WiFi.config(staticIP, gateway, subnet, dns, dns) == false) {
    Serial.println("Configuration failed.");
}

From this point onward we connect to the network like we did before. We start by calling the begin method on the WiFi extern variable and then we poll the connection status until it is successful.

WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print("Connecting...\n\n");
}

Followed by that we will print the network parameters, like we did on the previous section.

Serial.print("Local IP: ");
Serial.println(WiFi.localIP());
Serial.print("Subnet Mask: ");
Serial.println(WiFi.subnetMask());
Serial.print("Gateway IP: ");
Serial.println(WiFi.gatewayIP());
Serial.print("DNS 1: ");
Serial.println(WiFi.dnsIP(0));
Serial.print("DNS 2: ");
Serial.println(WiFi.dnsIP(1));

To finalize, we are going to ping Google, to check if we correctly configured the network parameters. You can check here a tutorial on how to ping a remote host from the ESP32.

bool success = Ping.ping("www.google.com", 3);
 
if(!success){
    Serial.println("\nPing failed");
    return;
}
 
Serial.println("\nPing successful.");

The final code can be seen below.

#include <WiFi.h>
#include <ESP32Ping.h>

const char* ssid = "yourNetworkName";
const char* password =  "yourNetworkPass";

IPAddress staticIP(192, 168, 1, 150);
IPAddress gateway(192, 168, 1, 254);
IPAddress subnet(255, 255, 255, 0);
IPAddress dns(192, 168, 1, 254);
   
void setup(){
  Serial.begin(115200);

  if (WiFi.config(staticIP, gateway, subnet, dns, dns) == false) {
    Serial.println("Configuration failed.");
  }
   
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print("Connecting...\n\n");
  }

  Serial.print("Local IP: ");
  Serial.println(WiFi.localIP());
  Serial.print("Subnet Mask: ");
  Serial.println(WiFi.subnetMask());
  Serial.print("Gateway IP: ");
  Serial.println(WiFi.gatewayIP());
  Serial.print("DNS 1: ");
  Serial.println(WiFi.dnsIP(0));
  Serial.print("DNS 2: ");
  Serial.println(WiFi.dnsIP(1));
  
  bool success = Ping.ping("www.google.com", 3);
 
  if(!success){
    Serial.println("\nPing failed");
    return;
  }
 
  Serial.println("\nPing successful.");
}
   
void loop(){}

Once again, to test the code, compile it and upload it to your device, after putting the correct credentials and network parameters that apply to your scenario.

When the procedure finishes, open the Arduino IDE serial monitor. You should get an output similar to figure 2. As can be seen, all the parameters we have set were then printed to the serial monitor and the ping to the Google server was successful.

Output of the program, after setting the ESP32 to use a static IP address.
Figure 2 – Output of the program, after setting the ESP32 to use a static IP address.

If we try to ping the ESP32 from another device in the network, it should also answer to the ping. This is exemplified in figure 3. Note that I’ve pinged the same exact address I’ve assigned to my ESP32.

Result of pinging the ESP32, after manually setting the network parameters.
Figure 3 – Result of pinging the ESP32, after manually setting the network parameters.

References

[1] https://en.wikipedia.org/wiki/Dynamic_Host_Configuration_Protocol

[2] https://stevessmarthomeguide.com/understanding-dhcp-home-networks/

[3] https://www.cisco.com/c/en/us/td/docs/switches/lan/catalyst3750x_3560x/software/release/12-2_55_se/configuration/guide/3750xscg/swipaddr.pdf

[4] https://www.iplocation.net/subnet-mask

[5] https://en.wikipedia.org/wiki/Default_gateway

Leave a Reply