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.
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://electronza.com">https://electronza.com</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://electronza.com">https://electronza.com</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://electronza.com“.
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 received. As such, one must find a way to parse the text as it is received.
ESP8266 hangs when running AT+CIPCLOSE
A bug in the firmware that comes with WiFi3 click causes ESP8266 to hang sometimes when running AT+CIPCLOSE=<link_id> command. It looks to me like a timing problem, as it doesn’t always happen. The only way to eliminate 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.
0 Comments