ESP32 Static/Fixed IP Address

This tutorial shows how to set a static/fixed IP address for your ESP32 board. If you’re running a web server or Wi-Fi client with your ESP32 and every time you restart your board, it has a new IP address, you can follow this tutorial to assign a static/fixed IP address.

ESP32-static-IP-address

Static/Fixed IP Address Sketch

To show you how to fix your ESP32 IP address, we’ll use the ESP32 Web Sever code as an example. By the end of our explanation you should be able to fix your IP address regardless of the web server or Wi-Fi project you’re building.

Copy the code below to your Arduino IDE, but don’t upload it yet. You need to make some changes to make it work for you.

Note: if you upload the next sketch to your ESP32 board, it should automatically assign the fixed IP address 192.168.1.184.

/*********
  Rui Santos
  Complete project details at https://randomnerdtutorials.com  
*********/

// Load Wi-Fi library
#include <WiFi.h>

// Replace with your network credentials
const char* ssid     = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

// Set web server port number to 80
WiFiServer server(80);

// Variable to store the HTTP request
String header;

// Auxiliar variables to store the current output state
String output26State = "off";
String output27State = "off";

// Assign output variables to GPIO pins
const int output26 = 26;
const int output27 = 27;

// Set your Static IP address
IPAddress local_IP(192, 168, 1, 184);
// Set your Gateway IP address
IPAddress gateway(192, 168, 1, 1);

IPAddress subnet(255, 255, 0, 0);
IPAddress primaryDNS(8, 8, 8, 8);   //optional
IPAddress secondaryDNS(8, 8, 4, 4); //optional

void setup() {
  Serial.begin(115200);
  // Initialize the output variables as outputs
  pinMode(output26, OUTPUT);
  pinMode(output27, OUTPUT);
  // Set outputs to LOW
  digitalWrite(output26, LOW);
  digitalWrite(output27, LOW);

  // Configures static IP address
  if (!WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS)) {
    Serial.println("STA Failed to configure");
  }
  
  // Connect to Wi-Fi network with SSID and password
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  // Print local IP address and start web server
  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  server.begin();
}

void loop(){
  WiFiClient client = server.available();   // Listen for incoming clients

  if (client) {                             // If a new client connects,
    Serial.println("New Client.");          // print a message out in the serial port
    String currentLine = "";                // make a String to hold incoming data from the client
    while (client.connected()) {            // loop while the client's connected
      if (client.available()) {             // if there's bytes to read from the client,
        char c = client.read();             // read a byte, then
        Serial.write(c);                    // print it out the serial monitor
        header += c;
        if (c == '\n') {                    // if the byte is a newline character
          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response:
          if (currentLine.length() == 0) {
            // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
            // and a content-type so the client knows what's coming, then a blank line:
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println("Connection: close");
            client.println();
            
            // turns the GPIOs on and off
            if (header.indexOf("GET /26/on") >= 0) {
              Serial.println("GPIO 26 on");
              output26State = "on";
              digitalWrite(output26, HIGH);
            } else if (header.indexOf("GET /26/off") >= 0) {
              Serial.println("GPIO 26 off");
              output26State = "off";
              digitalWrite(output26, LOW);
            } else if (header.indexOf("GET /27/on") >= 0) {
              Serial.println("GPIO 27 on");
              output27State = "on";
              digitalWrite(output27, HIGH);
            } else if (header.indexOf("GET /27/off") >= 0) {
              Serial.println("GPIO 27 off");
              output27State = "off";
              digitalWrite(output27, LOW);
            }
            
            // Display the HTML web page
            client.println("<!DOCTYPE html><html>");
            client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
            client.println("<link rel=\"icon\" href=\"data:,\">");
            // CSS to style the on/off buttons 
            // Feel free to change the background-color and font-size attributes to fit your preferences
            client.println("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}");
            client.println(".button { background-color: #4CAF50; border: none; color: white; padding: 16px 40px;");
            client.println("text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}");
            client.println(".button2 {background-color: #555555;}</style></head>");
            
            // Web Page Heading
            client.println("<body><h1>ESP32 Web Server</h1>");
            
            // Display current state, and ON/OFF buttons for GPIO 26  
            client.println("<p>GPIO 26 - State " + output26State + "</p>");
            // If the output26State is off, it displays the ON button       
            if (output26State=="off") {
              client.println("<p><a href=\"/26/on\"><button class=\"button\">ON</button></a></p>");
            } else {
              client.println("<p><a href=\"/26/off\"><button class=\"button button2\">OFF</button></a></p>");
            } 
               
            // Display current state, and ON/OFF buttons for GPIO 27  
            client.println("<p>GPIO 27 - State " + output27State + "</p>");
            // If the output27State is off, it displays the ON button       
            if (output27State=="off") {
              client.println("<p><a href=\"/27/on\"><button class=\"button\">ON</button></a></p>");
            } else {
              client.println("<p><a href=\"/27/off\"><button class=\"button button2\">OFF</button></a></p>");
            }
            client.println("</body></html>");
            
            // The HTTP response ends with another blank line
            client.println();
            // Break out of the while loop
            break;
          } else { // if you got a newline, then clear currentLine
            currentLine = "";
          }
        } else if (c != '\r') {  // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }
      }
    }
    // Clear the header variable
    header = "";
    // Close the connection
    client.stop();
    Serial.println("Client disconnected.");
    Serial.println("");
  }
}

View raw code

Setting Your Network Credentials

You need to modify the following lines with your network credentials: SSID and password.

// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

Setting your Static IP Address

Then, outside the setup() and loop() functions, you define the following variables with your own static IP address and corresponding gateway IP address.

By default, the next code assigns the IP address 192.168.1.184 that works in the gateway 192.168.1.1.

// Set your Static IP address
IPAddress local_IP(192, 168, 1, 184);
// Set your Gateway IP address
IPAddress gateway(192, 168, 1, 1);

IPAddress subnet(255, 255, 0, 0);
IPAddress primaryDNS(8, 8, 8, 8); // optional
IPAddress secondaryDNS(8, 8, 4, 4); // optional

Important: you need to use an available IP address in your local network and the corresponding gateway.

setup()

In the setup() you need to call the WiFi.config() method to assign the configurations to your ESP32.

// Configures static IP address
if (!WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS)) {
  Serial.println("STA Failed to configure");
}

Note: the primaryDNS and secondaryDNS parameters are optional and you can remove them.

Testing

After uploading the code to your board, open the Arduino IDE Serial Monitor at the baud rate 115200, restart your ESP32 board and the IP address defined earlier should be assigned to your board.

As you can see, it prints the IP address 192.168.1.184.

You can take this example and add it to all your Wi-Fi sketches to assign a fixed IP address to your ESP32.

Assigning IP Address with MAC Address

If you’ve tried to assign a fixed IP address to the ESP32 using the previous example and it doesn’t work, we recommend assigning an IP address directly in your router settings through the ESP32 MAC Address.

Add your network credentials (SSID and password). Then, upload the next code to your ESP32:

/*********
  Rui Santos
  Complete project details at https://randomnerdtutorials.com  
*********/

// Load Wi-Fi library
#include <WiFi.h>

// Replace with your network credentials
const char* ssid     = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

// Set web server port number to 80
WiFiServer server(80);

void setup() {
  Serial.begin(115200);
  
  // Connect to Wi-Fi network with SSID and password
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  
  // Print local IP address and start web server
  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  server.begin();

  // Print ESP MAC Address
  Serial.println("MAC address: ");
  Serial.println(WiFi.macAddress());
}

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

View raw code

In the setup(), after connecting to your network, it prints the ESP32 MAC Address in the Serial Monitor:

// Print ESP MAC Address
Serial.println("MAC address: ");
Serial.println(WiFi.macAddress());

In our case, the ESP32 MAC Address is B4:E6:2D:97:EE:F1. Copy the MAC Address, because you’ll need it in just a moment.

Router Settings

If you login into your router admin page, there should be a page/menu where you can assign an IP address to a network device. Each router has different menus and configurations. So, we can’t provide instructions on how do to it for all the routers available.

We recommend Googling “assign IP address to MAC address” followed by your router name. You should find some instructions that show how to assign the IP to a MAC address for your specific router.

In summary, if you go to your router configurations menu, you should be able to assign your desired IP address to your ESP32 MAC address (for example B4:E6:2D:97:EE:F1).

Wrapping Up

After following this tutorial you should be able to assign a fixed/static IP address to your ESP32.

We hope you’ve found this tutorial useful. If you like ESP32, you may also like:

Thanks for reading.



Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »
Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »

Enjoyed this project? Stay updated by subscribing our newsletter!

32 thoughts on “ESP32 Static/Fixed IP Address”

  1. Bonjour. j’utilise avec succès le programme qui permet d’allumer. je voudrais savoir comment faire pour utiliser partout sur la france

    Reply
  2. Some people might want to access the device from outside their home network. The last time I did something like this I had to first setup the IP address, configure my laptop with that address and run the “whatsmyip” website to show what my external address is. Then I could go back and set the device to that IP and my laptop back to DHCP. Unless you have a better way?

    Reply
    • You can use one of the free DDNS providers to always access your local network by a DNS name
      like mylocalhome.duckdns.org which would always point to your current IP address…
      Find a list here
      ionos.com/digitalguide/server/tools/free-dynamic-dns-providers-an-overview/

      Reply
  3. I have used the No-IP solution for many years and I’m very happy with it.
    In the beginning I used the free version but now I’m using the paid version.
    It costs about $25 pr year.

    Reply
  4. Hi,

    Is it possible to have a fixed IP address with an ESP32 CAMERA ? When you open the camera web server it assigns a dynamic IP address automatically.

    Regards

    Reply
  5. Lol, I’ve seen it, but this is not for the “CameraWebServer” isn’t it ? I can’t make it work.
    Regards

    Reply
  6. Thanks for another very helpful post. It worked first time EXCEPT it seemed to have brake my calls to the NTP server. I had left out the DNS settings since they were optional, when I put these in (copying the addresses from my router) all was good again. Unless I missed something it might be helpful to mention the consequences of omitting the primary and secondary DNS addresses. Thanks

    Reply
  7. Hello Rui and Sara
    I have added a Static IP address to your tutorial ESP32 Email Alert Based on Temperature.
    I am able to access the web page see the temperature and change it.
    But can’t send email. I get a connecting to SMTP server… error.

    If I keep the original dynamic ip tutorial every thing works fine.
    Any clue ?

    Reply
  8. As others have found, leaving out the ‘optional’ DNS parameters from the WiFi.config statement has some odd effects.
    When those parameters are missing in my project
    I found I could still access the ESP32 as a web server, BUT the ESP32 was unable to send email, connect to ThingSpeak or access NTP
    So it seems those DNS parameters are not 100% optional for some reason – and that should be reflected in the main body of this article rather than left to the comment section

    Reply
  9. Hi Rui and Sara,

    It stuck me in the past for several times that I couldn’t combine “Fixed Static IP-address” with getting time from a NTP-server.
    Now I did another try with your nice clean examples and combined this sketch with the relevant code from your sketch under the title ESP32 Epoch Time (see: https://randomnerdtutorials.com/epoch-unix-time-esp32-arduino/).
    And again failing reading time resulting in repeatedly printing 0 epoch seconds.

    Is there a solution for this?

    Thnx for all the good work, you provide us with.
    Kind regards,

    Jop

    Reply
  10. I want to have about 20 to 25 esp32’s checking weights, temperature, and humidity in my bee hives. The esp’s are assigned IP’s via my router 192.168.1.201 thru 220 using the MAC address. This all works and can hook to esp’s and see the IP’s and can poll the IP’s via of browser, but at times the units will quit answering and will have to be restarted. I have a Raspberry Pi polling the info for spread sheet display every 5min. I can get up to 9 units answering and the ones missing time out in 15sec in the R Pi. Why can’t I get this system to work continuously?

    Reply
    • Hi.
      I don’t know. What happens right before they stop answering?
      It may be an issue with your programs or an issue with the wi-fi network itself. Or even related to the power supply.
      Regards,
      Sara

      Reply
      • I have just started with these “small” computers about a year ago so I am new to these programing languages. Retired after 40+yrs as a control system electrical engineer, so my use of the correct jargon for these units may not be the way others talk about them.
        My network starts with an ausus RT-AC88U as the router and 2 RT-AC68U’s as a mesh in my house. Attached via of cable are AP of 3 older routers changed to an access points. The 88u has been setup to assign IP’s based on the MAC add of the Esp32’s. The 32’s are loaded with the sketches and accessed via their IP 192.168.4.1 and given an SSID and PW and I get the MAC as part of the info on the browser page that they broadcasted. The AC88 gives them a random IP at that time. and they work. After loading my sketch to several 32’s (1 to 5), I go into the 88U and put MAC’s in and force an IP of 192.168.1.201 thru XXX). This forces a new IP to the units that have had a random IP already assigned. The 32’s via of a restart?? take on the IP that so I know which esp32 is on which of the hives. I could see the IP’s on some of my computers (win10 main desk top PC1, win10 on a dell laptop PC2, and a Rasp Pi). The Rasp Pi is polling data from 15 to (haven’t figured the upper limit yet 48 maybe) esp’s every 5min. Rasp Pi would poll but would get a timeout on IP’s that I could see on PC1 and maybe on PC2 and in some cases were being polled OK but would drop out. Out of frustration, and my note to you the other day, I rebooted the AC88U. This has now allow the system to function for several days and polling 15 esp (3 are at hives being access by a remote AP1 using ethernet to 115vac adapter on to 250ft of #12 back to ethernet at the hives to the AP1 which are WIFI’d to the esp32’s. The other units are wifi’d to AP2 in my houses and testing and building weather proof boxes. The “congestion” in the router due to random IP’s and shift to the table of IP’s and a reboot may have solved the problem for the time being.

        Reply
        • The ESP32 is pretty notorious for dropping of the WiFi and being unable to reconnect unless physically rebooted
          I had similar problems with my project which initially used DHCP, later recommended to switch to Fixed IP to fix it – better(?) but still does/did it
          So now included in my Wi-FI connect process, I do an ESP.restart() after a number of failed connection attempts.
          For interest I log that in EEprom, and send myself an email on reboot, just so I have a knowledge of that happening
          I get that email at least once every 2/3 days – and this is just a single unit let alone 42 of them !

          Reply
          • I have noted that if power goes off from my main power company, that the esp32’s start asking the AP to Router to get back on the system (SSID) before the router is up and running again. In this case with the sign in library esp software I am using the esp’s go back to the factory IP (192.168.4.1) and I have to sign into each and give them my ssid and pw. I put a random number generator to force a wait of 30 to 60 sec before asking to get on the network. This creates a delay when wanting to check a unit with the com port and 60sec (60000) isn’t long enough. I have bought a Time delay after energization (TDAE) relay to supply 115vac to “wall warts” that feed each esp32. Will set it for a long time (5min?) to allow the network to get up running before the esp32’s start asking to be on line. Still will leave the random delay in the esp32’s so all are not asking for and IP at the same time??.
            There is a “new” esp32 that claims to be more stable (CH9102X). Got 10 and load my sketch using the same arduino interface as the older units. They appear to work OK at the initial SW install. One thing that is quirky is each of the 10 set a new port number 13 through 22 instead of remaining port 10 (the older esp32’s). They “forced” the new port and you don’t know it till you load the sketch and it won’t finish. Unless you note it as to the eps32, if you load several units and go back to a unit, which port do you pick in the list of ports??. They also loaded a new port in order they were plugged in and was depending on the MAC addresses and the next day on a PC startup they appeared to keep the some port. Not sure why the manufacture is doing it. May several units via the usb com ports will allow them to be hook up to each other or as a network of some kind?

  11. As to the units loosing the ssid and pw or dropping of the WIFI network, I may try to figure out how to time x mins to not allow too long of time without seeing a request from the Rasp Pi. Say the Rasp Pi is asking for data ever 5 mins then if not “see” arequested in say 15 mins force a reboot??

    Reply
  12. Hi Sara,

    For some reason it seems not possible to combine Static/Fixed IP-address with getting the time from a NTP-server.

    Kind regards,

    Jop

    Reply
  13. My experience with the ESP32, like that of Robert FOLKES above, is that setting the primary and secondary DNS in the call to WiFiConfig() is maybe not so optional. Not setting those parameters seems to have broken NTP for me as well. But this code does not break the time functions:

    Serial.println(“Initializing Wi-Fi IP config…”);
    if (!WiFi.config(local_IP, gateway, subnet, primarydns, secondarydns)) {
    Serial.println(“STA Failed to configure”);
    }

    Reply
  14. Hello,
    I have tried to reserve an IP in the router settings for my esp32 camera modul based on it’s MAC address but for some reason the esp won’t accept that address and gets anothe IP. This method worked for my esp8266 boards, though.
    What can cause that?

    Thank you in advance!

    Reply

Leave a Comment

Download Our Free eBooks and Resources

Get instant access to our FREE eBooks, Resources, and Exclusive Electronics Projects by entering your email address below.