ESP8266: AT mode webserver tutorial

Teodor Costachioiu
Mar 15, 2017 · 5 min read
Image for post
Image for post

In today’s blog post I will show you how to implement a web server with ESP8266, using one WiFi3 Click and one USB-UART click from MikroElektronika. In this tutorial, I will use Tera Term to communicate with the WiFi3 click. Anyone can then adapt this tutorial to any microcontroller used to control the ESP8266.

This article is more than two years old and might contain obsolete information; it is still kept here for informational purposes.

The following connections were made for the WiFi3 click:

  • PWD (AN) pin is connected to Vcc via a 10k pull-up resistor. A reset button is connected between this pin and GND.
  • RST is connected to ground
  • EN pin is left floating
  • RX pin is connected to the TX pin of USB-UART click
  • TX pin is connected to the RX pin of USB-UART click

Please note that in the documentation on MikroElektronika website, the AN pin is marked as NC. This is wrong! On the click board, the marking is correct as being CH-PD.

When started, the board I have replied with:

þ( 
[Vendor:www.ai-thinker.com Version:0.9.2.4]

Response to AT+GMR command is:

0018000902-AI03

OK

Note that some garbage can be received before the “[Vendor…” text. This is normal, as ESP8266 starts first at 76923 bps, a baud rate that most terminal programs are not able to understand. So, just ignore this.

Connecting to WiFi and starting web server

The following procedure must be followed to connect to WiFi:

First, run AT+CWMODE=1 to configure the ESP8266 as a WiFi client.

Then run AT+CWJAP=”acess_point_name”,”wifi_password” to connect to an existing WiFi router. Note that it takes some time for ESP8266 to respond to this command, something over 5 seconds. Once connected you can get the IP allocated by the router with

One must configure the ESP8266 to accept multiple connections by running AT+CIPMUX=1. Then web server can be started on port 80, the standard HTTP port, by running AT+CIPSERVER=1,80.

AT+CWMODE=1

no change
AT+CWJAP="electronza","guest_pass"


OK
AT+CIFSR

192.168.1.5

OK
AT+CIPMUX=1


OK
AT+CIPSERVER=1,80


OK

At this moment the web server is ready to receive connections. To further analyze the traffic, I used a TCP sniffer called SmartSniff. So, with SmartSniff active and listening, I typed http://192.168.1.5 in my browser.

A typical web request intercepted with SmartSniff should look like:

GET / HTTP/1.1
Host: 192.168.1.5
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Connection: keep-alive
Upgrade-Insecure-Requests: 1

.

In Tera Term we will get:

+IPD,0,324:GET / HTTP/1.1
Host: 192.168.1.5
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Connection: keep-alive
Upgrade-Insecure-Requests: 1


OK

The syntax of the +IPD response is +IPD,<ID>,<len>[,<remote IP>,<remote port>]:<data>. So, from the above-received Http request we extract the following useful information:

  • link_id is 0.
  • the length of the received message is 324

When parsing the message, we have to look at the GET command. The rest doesn’t matter much in my tutorial. However, one can use this information to deliver browser-specific pages.

So, we get the request, now we have to respond to it. The message we wish to send back is:

HTTP/1.1 200 OK
Content-Type: text/html
Connection: close

<!DOCTYPE HTML>
<html>
ESP8266 web server example by <a href = https://medium.com/electronza/">https://medium.com/electronza/</a>
</html>

This message has 190 characters (including the <CR> and <LF> at the end of the message. So, we will run AT+CIPSEND=0,190.

Let’s take a look at the syntax AT+CIPSEND=[<link ID>,]<length>[,<remote IP>,<remote port>].

In Tera Term we will have an input prompt where we insert our message. When 190 characters are sent, the connection is closed and we get a SEND OK message. At the same time, the message content is sent to link_id = 0.

Finally, we have to run AT+CIPCLOSE to close the connection.

AT+CIPSEND=0,190

> HTTP/1.1 200 OK
Content-Type: text/html
Connection: close

<!DOCTYPE HTML>
<html>
ESP8266 web server example by <a href = "https://medium.com/electronza/">https://medium.com/electronza/</a>
</html>

SEND OK
AT+CIPCLOSE=0


OK

At this moment, in the web browser, we should see the text “ESP8266 webserver example by https://medium.com/electronza/“.

Wait, there’s more…

The web browser issued another request, this time for favicon.ico. As we don’t have a favicon, we should return a 404 response, following the above procedure:

GET /favicon.ico HTTP/1.1
Host: 192.168.1.5
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Connection: keep-alive

.

HTTP/1.1 404 Not Found
Content-type: text/html
Content-length: 135

<html><head><title>Not Found</title></head><body>
Sorry, the object you requested was not found.
</body><html>

In Tera Term we will have:

+IPD,1,245:GET /favicon.ico HTTP/1.1
Host: 192.168.1.5
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Connection: keep-alive


OK
AT+CIPSEND=1,188

> HTTP/1.1 404 Not Found
Content-type: text/html
Content-length: 135

<html><head><title>Not Found</title></head><body>
Sorry, the object you requested was not found.
</body><html>

SEND OK
AT+CIPCLOSE=1


OK

Note that the request and the response use link_id=1, altough is the same browser

Known issues

ESP8266 in AT mode is far from perfect. below is a list of problems I found so far:

Too much text is received

A typical web request can have about 400 characters. As there are five concurrent connections possible, one can receive a lot of text. Parsing that amount of text is difficult on microcontrollers with little RAM memory. Below is what happens when two devices try to access the web page at the same time:

Link+IPD,0,377:GET / HTTP/1.1
Host: 192.168.1.5
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 10_2_1 like Mac OS X) AppleWebKit/602.4.6 (KHTML, like Gecko) Version/10.0 Mobile/14D27 Safari/602.1
Accept-Language: en-us
DNT: 1
Accept-Encoding: gzip, deflate
OK
Link
+IPD,1,324:GET / HTTP/1.1
Host: 192.168.1.5
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Connection: keep-alive
Upgrade-Insecure-Requests: 1
OK

In total there were 749 characters recieved. As such, one must find a way to parse the text as it is received.

ESP8266 hangs when running AT+CIPCLOSE

There is a bug in the firmware that comes with WiFi3 click that causes ESP8266 to hang sometimes when running AT+CIPCLOSE=<link_id> command. It looks to me as a timing problem, as it doesn’t happen always. The only way to get rid of this is to upgrade the firmware to a more recent version.

AT+CIUPDATE bricks the ESP8266

A nasty surprise. OTA update bricks the device. Still, it can be salvaged using the firmware update tutorial I described in this blog post.

The bad news is that I couldn’t find the original firmware anymore. Also, you’ll need a 4Mb firmware. After many tries and failures, I’ve found a firmware image that works on http://www.electrodragon.com/w/ESP8266_AT-Command_firmware — it’s the ESP8266 AT 0.2 (at_v0.20_14_11_28) file.

When uploading the new firmware, use the following addresses:

  • boot_v1.1.bin — 0x0000
  • user1.bin — 0x1000
  • esp_init_data_default — 0x3fc000
  • blank.bin — 0x7e000
  • blank.bin — 0x3fe000

A complicated process, I had to try several times until I got my WiFi3 click to work again. Also note that this firmware version uses 115200 baud for serial communication.


Originally published at https://electronza.com on March 15, 2017. Moved to Medium on May 2, 2020.

Electronza

DIY electronics projects and more

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store