ESP8266: Setting a simple HTTP webserver

The objective of this post is to explain how to set a HTTP webserver on a ESP8266 and how to make some requests to it using a web browser.

Introduction

The objective of this post is to explain how to set an HTTP webserver on a ESP8266 and how to make some requests to it using a web browser.

We assume the use of the ESP8266 libraries for the Arduino IDE. You can check here how to configure the Arduino IDE to support the ESP8266.

 

The code

First of all, we include the ESP8266WiFi library, which will make available the functionality needed for the ESP8266 to connect to a WiFi network. You can check a more detailed explanation on how to connect to a WiFi network from the ESP8266 on this previous post.

Then, we include the ESP8266WebServer library, which will make available the class ESP8266WebServer that we will use during this post. Naturally, this class has some methods available that will help us setting up a server and handle incoming HTTP requests without needing to worry about low level implementation details. You can check the implementation of the library here.

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>

Next, we declare a global object variable from the previously mentioned class, so we will be able to access it in our functions.

As argument for the constructor of this class, we will pass the port where the server will be listening to. Since 80 is the default port for HTTP [1], we will use this value, so we will not need to specify it in the URL when accessing to our ESP8266 server using a browser.

ESP8266WebServer server(80);

Since we need to pre-configure our HTTP server before actually running it, we will do most of the coding in the setup function.

First of all, we open a serial connection for debugging.

Serial.begin(115200);

Then, we will need to connect to the WiFi network, as shown with the code below. If you need a detailed explanation on how to connect to a WiFi network with the ESP8266, check here.

WiFi.begin(“Network name”, “Password”);

while (WiFi.status() != WL_CONNECTED) {   //Wait for connection

delay(500);
Serial.println(“Waiting to connect…”);

}

Since we are not going to do any domain name resolution, we need to know the IP where the ESP8266 is listening to incoming requests, which will be the local IP assigned in the WiFi network.

To get this value, we just call the localIP method on the WiFi global variable and then print it to the serial port, so we will know which URL to call on our web browser.

Serial.println(WiFi.localIP());

Then, we will start to specify which code to execute when an HTTP request is performed to each path. To do so, we call the on method on our previously declared server global object.

The more elegant method consists on defining a handling function somewhere in our code and passing it to the on function, alongside the URL that will trigger the execution of that function. This is exemplified below.

server.on(“/”, handleRootPath);

So, the code mentioned bellow indicates that when an HTTP request is received on the root (“/”) path, it will trigger the execution of the handleRootPath function. Note that we don’t specify the IP or port where the ESP8266 is listening, but only the path of the URL from that point onward.

For the sake of simplicity, let’s assume that our handleRootPath only answers with the text “Hello World” to the incoming HTTP request. So, to define an answer to a request, we call the send method on our server object.

Although the method can be called with a different set of arguments, its simplest form consists on receiving the HTTP response code, the content type and the content. Check the code below.

void handleRootPath() {

server.send(200, “text/plain”, “Hello world”);

}

In this case, we are sending the code 200, which corresponds to the “OK” response [2]. Then, we are specifying the content type as “text/plain“, since we are only responding with a simple “Hello world”, and finally the actual response text.

Naturally, this function needs to be declared outside the setup function.

We can also specify the handling function when calling the on method. In this case, we don’t need to declare a separate function and we can do everything in the setup function, as demonstrated bellow.

server.on(“/other”, [](){

server.send(200, “text/plain”, “Other URL”);

});

In this case, if we receive an HTTP request in the path “/other”, we will answer with a “Other URL” sentence.

Now, to start our server, we call the begin method on the server object. This is the last line of code we need to include in our setup function.

server.begin();

Finally, to handle the actual incoming of HTTP requests, we need to call the handleClient method on the server object, on the main loop function.

void loop() {

server.handleClient();

}

The complete code can be seen bellow.

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>

ESP8266WebServer server(80);

void setup() {

Serial.begin(115200);
WiFi.begin(“Network name”, “Password”);  //Connect to the WiFi network

while (WiFi.status() != WL_CONNECTED) {  //Wait for connection

delay(500);
Serial.println(“Waiting to connect…”);

}

Serial.print(“IP address: “);
Serial.println(WiFi.localIP());  //Print the local IP

server.on(“/other”, [](){      //Define the handling function for the path

server.send(200, “text/plain”, “Other URL”);

});

server.on(“/”, handleRootPath);      //Associate the handler function to the path
server.begin();                                       //Start the server
Serial.println(“Server listening”);

}

void loop() {

server.handleClient();         //Handling of incoming requests

}

void handleRootPath() {            //Handler for the rooth path

server.send(200, “text/plain”, “Hello world”);

}

 

Testing the code

To test the code we just need to open our browser and make an HTTP request to the IP of the ESP8266, on a path we defined early. The format is shown bellow:

http://serverIP:port/path

Since, as stated before, we are listening on the 80 port, the browser will assume it by default, so we don’t need to specify it:

http://serverIP/path

So, we substitute the serverIP by the IP printed on the serial console, and we make a request as shown in figure 1.

http-server-esp8266-root

Figure 1 – HTTP request via browser on the root path (Google Chrome).

In this case, only the IP is shown because the browser removed the “/” from the root path. Also, the http:// was removed by the browser. Although some browsers perform the request when we only specify the IP, others assume that we want to search something in a search engine. So, the safest way is to always specify the http:// before the IP.

The example from figure 2 shows a request on the path “/other” that we also defined.

esp8266-http-webserver

Figure 2 – HTTP request via browser on the “/other” path (Firefox).

Finally, note that if we specify a path not defined, the ESP will return a message indicating that the resource was not found, as we can see in figure 3, where we sent an HTTP request to the path “/notdefined”.

esp8266-http-server-path-not-defined

Figure 3 – HTTP request via browser on a path not defined.

Important: The IP that will be printed by the ESP8266 will be its private IP on the network. It won’t be possible for a client outside the network to contact it on that IP (and thus, the URL will not work). In order for a client to be able to contact the ESP8266 from outside its network, it would need to use the external IP of the network and the router would need to be configured to forward the requests on its public IP for that port to the private IP of the ESP8266. Since port forwarding depends on the router used, explaining how to do it is outside of the scope of this post.

 

Related posts

 

References

[1] http://searchnetworking.techtarget.com/definition/port-80

[2] http://www.restapitutorial.com/httpstatuscodes.html

 

Technical details

ESP8266 libraries: v2.3.0

Advertisements
This entry was posted in ESP8266, IoT and tagged , , , , , , , , , , . Bookmark the permalink.

21 Responses to ESP8266: Setting a simple HTTP webserver

  1. Pingback: ESP8266 HTTP server: Serving HTML, Javascript and CSS | techtutorialsx

  2. Pingback: ESP8266 Webserver: Getting query parameters | techtutorialsx

  3. Pingback: ESP8266 Webserver: Receiving GET requests from Python | techtutorialsx

  4. Pingback: ESP8266 Webserver: Controlling a LED through WiFi | techtutorialsx

  5. Pingback: ESP8266 Webserver: Resolving an address with mDNS | techtutorialsx

  6. mamacker says:

    Have you considered the Watchdog on the Esp8266? I have several of these things but they always seem to halt. (Daily) I wonder if you’ve figured out how to employ the watchdog so they reboot themselves. Thanks for the content!

    Liked by 2 people

    • antepher says:

      Hi! I haven’t yet played with the watchdog, but from what I’ve seen in the API there are some functions to enable / disable it:
      https://github.com/esp8266/Arduino/blob/4897e0006b5b0123a2fa31f67b14a3fff65ce561/cores/esp8266/Esp.cpp

      If I find out how to make it work, I will make a post explaining it.

      Thanks for the feedback 🙂

      Liked by 2 people

    • antepher says:

      Hi again! I’ve been playing a little bit with the watchdogs of the ESP8266 and shared the results here:
      https://techtutorialsx.wordpress.com/2017/01/21/esp8266-watchdog-functions/

      As it seems, the ESP has 2 watchdogs: a software one and a hardware one. The ESP libraries for the Arduino IDE give us some control on the software watchdog. For the hardware watchdog, I haven’t found any way to control it.

      Nevertheless, both the hardware and software watchdogs are enabled by default, so it’s strange that they don’t reset your devices when they halt. Do you have any error log that you can share in the github page of the libraries? It’s probably the best way to try to find the root cause and solve it.

      Liked by 1 person

      • mamacker says:

        Thanks for looking! That’s funny, it definitely locks up on me for hours, until I reset the device. I’ll see about posting it somewhere. The device I built simply lets my kids see their BTC balance, on an oled, all running on a esp8266 feather. So it’s just making http calls… and it locks up daily.

        Liked by 2 people

        • antepher says:

          You’re welcome 🙂 It sounds a very cool project!

          Well, I remember that once I had some problems while doing socket communication with a Java program. My program seemed to hang but in reality the sockets were being left half opened, so I wasn’t able to do any more connections after a certain point. Is that a possible case for your program or is it really crashing/locking at a deeper level?

          I also have once experienced problems when doing many HTTP requests in a row, without a delay between them. It also caused some malfunctions.

          Other things that you can try to solve the problem:
          – Making sure you have the latest version of the ESP libraries.
          – Changing the type of ESP board if you only tested in the same model. The problem you are experiencing may be a hardware issue. You have some different models at eBay, from the NodeMCU to the ESP01.

          Hope it helps, if you are able to solve the issue please share with us.

          Liked by 2 people

  7. ARJ says:

    Humm that ESP seems ereally nice . . .

    Liked by 1 person

  8. Pingback: ESP8266 Webserver: Accessing the body of a HTTP request | techtutorialsx

  9. Pingback: ESP8266: Setting an access point | techtutorialsx

  10. I encountered a strange phenomenon. When I started this described program; my ESP8266 first connected to the IP-address: 192-168.4.2 which is NOT the default range of my WiFiNetwork (192.168.2.xxx). And when I reset this chip then it founds a good adres: 192.168.2.4
    And I found in my Wifi Networklist that this chip pronounce itsself as “ESP_863074”. And in LookatLAN (a Windowsprogram thats pinning the arrea) I found this chip on this 2 IP-adresses. Also it is accessible on this both addresses.

    Liked by 1 person

    • antepher says:

      Hi! That’s really a strange behavior, never happened to me yet, or at least I haven’t noticed. Does it happen to any other devices on your network or just the ESP8266?

      I think it may be related to the router, since its the router that assigns the IP to the device on the network. But is just a guess.

      Let us know if you discover the cause 🙂

      Like

  11. Pingback: ESP8266: Adding Swagger UI to REST API | techtutorialsx

  12. rodo says:

    To associate an IP to a domain, download the library DNSServer.h. Then,

    dnsServer.start(DNS_PORT, “www.example.com”, my_IP);

    See more,
    sketches/examples —- DNSServer —– DNSServer (sketch)

    Liked by 1 person

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s