On Dec 4th 2014 I purchased a “ESP8266 Remote Serial Port WIFI Transceiver Wireless Module” from banggood.com, based on an ESP8266 reference design by http://espressif.com. Here are my initial experiences poking around with the device. (Usual caveat — this post is largely to help my own recollections. If it helps you too, that’s a bonus.)
Board & pin-outs
Photos of board, top and bottom. Pin labeling was initially ascertained from http://rayshobby.net/first-impression-on-the-esp8266-serial-to-wifi-module/
I used a cheap clone logic analyser (LA) to ascertain that my ESP8266 module exhibits an unusual two-step sequence of serial port speeds when reset.
According to my LA’s auto baudrate detection, the ESP8266 sends the following sequence of characters at 76923bps (yes, really!) during the first 110ms after reset:
\r\n ets Jan 8 2013,rst cause:2, boot mode:(3,7)\r\n\r\nload 0x40100000, len 25052, room 16 \r\ntail 12\r\nchksum 0x0b\r\nho 0 tail 12 room 4\r\nload 0x3ffe8000, len 3312, room 12 \r\ntail 4\r\nchksum 0x53\r\nload 0x3ffe8cf0, len 6576, room 4 \r\ntail 12\r\nchksum 0x0d\r\ncsum 0x0d\r\n
[Edit: I’ve since noticed this behaviour observed elsewhere too.]
Then between roughly 296ms and 354ms after reset, the following firmware announcement string appears at 9600bps:
The “ready” indicates that the device is now willing to accept AT commands. (The domain name in the banner hints at http://www.ai-thinker.com , which turns out to be a Chinese-language site with community forums dominated by discussion of ESP8266 and other small devices.)
It is unclear why the initial bootloader output occurs at 76923bps. But once the unit switches to 9600bps we are under the control of the firmware that interprets AT command sequences to configure and use the device as a WiFi access point and/or client.
Details of serial port test setup
For the preceding test, my LA and ESP8266 were configured as follows:
- VCC and GND to the ESP8266 from a 3.3V regulated supply
- UTXD on ESP8266 connected to CH1 of the LA
- CH_PD line of ESP8266 connected to VCC
- RST, GPIO0 and GPIO2 left floating
- GND of ESP8266 and LA tied together
- LA connected (via USB) to a Windows 7 machine running the Saleae Logic v1.1.30 UI, and configured to capture 1000ms @ 1MHz, rising edge trigger with ‘async serial’ protocol decoding. (First with auto-baud rate detection, then with decode baud rate fixed at 9600bps.)
Briefly power cycling the ESP8266 does not reliably produce the same bursts of traffic each time. But taking the RST line low (to GND) seems to do a reliable reset, and triggers the same initialisation output traffic on UTXD.
Configuring for WiFi
To configure the ESP8266 I connected it to a Prolific-based USB_Serial adapter, which was itself plugged into my PCBSD 9.1 desktop. Wired up to the ESP8266 as follows:
- UTXD to White wire (sending data to the PC)
- URXD to Red wire (receiving data from the PC)
- GND to GND (black wire)
Used the following to open a console at 9600 baud:
cu -l /dev/cuaU0 -s 9600
Touching RST to GND to reset the ESP8266 causes the following output from cu:
[gja@gjadesktop]:~ # cu -l /dev/cuaU0 -s 9600 Connected ��BX����<i<�� [Vendor:www.ai-thinker.com Version:0.9.2.4] ready
The initial garbage is the bootloader output at 76923bps, followed by the firmware banner and prompt at 9600bps.
Configuring the ESP8266 for basic WiFi
For each typed line, use ^M^J (ctrl-M ctrl-J) to generate the “\r\n” sequence required to terminate AT commands sent to the ESP8266.
When booted and immediately after RST:
AT+CWMODE? +CWMODE:2 OK
Trigger a soft reset:
AT+RST OK J� @�:&�;�;!B��RƇ�� [Vendor:www.ai-thinker.com Version:0.9.2.4] ready
Display IP of inbuilt access point:
AT+CIFSR 192.168.4.1 OK
Retrieve firmware version
AT+GMR 0018000902-AI03 OK
Check current WiFi mode:
AT+CWMODE? +CWMODE:2 OK
While the ESP8266 was in local AP mode, I used an old iPod Touch to join the ESP8266’s default SSID (“ESP_9CC7BA”). Then queried the ESP8266’s list of associated clients with this line:
AT+CWLIF 192.168.4.101,00:1e:c2:5a:43:6b OK
The ESP8266 correctly sees my iPod Touch and has assigned it (via internal DHCP server) the address 192.168.4.101 on the ESP8266’s WLAN.
Using the ESP8266 on my home WLAN
Turning the ESP8266 into a client on my home WLAN involves switching to CWMODE=3 then configuring the SSID to join (and required password) with CWJAP command:
AT+CWMODE=3 OK AT+CWJAP="OpenWrt","xxxxPasswordRemovedxxxx" Z=0� Gl��N ����ƫ��� [Vendor:www.ai-thinker.com Version:0.9.2.4] ready
The ESP8266 reboots, then we confirm which WLAN we’re connected to:
AT+CWJAP? +CWJAP:"OpenWrt" OK
Confirm that the ESP8266 has been assigned an IP address on my home WLAN:
AT+CIFSR 192.168.4.1 10.1.1.60 OK
Good — 10.1.1.60 is an address assigned to the ESP8266 client by my home network’s DHCP server.
Become a ‘server’ listening on port 80:
AT+CIPMODE=1 OK AT+CIPMUX=1 OK AT+CIPSERVER=1,80 OK
Point my desktop’s browser at http://10.1.1.60, and look at what pops out the serial port of the ESP8266:
Link +IPD,0,352:GET / HTTP/1.1 Host: 10.1.1.60 Connection: keep-alive Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 User-Agent: Mozilla/5.0 (X11; FreeBSD amd64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.117 Safari/537.36 DNT: 1 Accept-Encoding: gzip,deflate,sdch Accept-Language: en-GB,en-US;q=0.8,en;q=0.6 OK
Nice! That’s the query from the browser. (At this point the browser is
hanging waiting for some html reply.)
Try sending a specific number of bytes back:
AT+CIPSEND=0,5 > hello SEND OK
This results in a TCP packet going back to the browser carrying the payload “hello”, but the connection remains open. Need:
to close the connection, and force the browser to parse the returned ASCII.
Caveat#1 — above steps not always reliable. Needs more investigation.
Caveat#2…. seems that getting certain command sequences wrong can drop this ESP8266 clone into a continuous (or at least very repetitive) reboot sequence for no apparent reason!
Try connecting to remote server
Used ideas from https://github.com/espressif/esp8266_at/wiki/at_example_0020000903
to establish a single TCP connection to http://caia.swin.edu.au
AT+RST OK ��BP����<i<�� z��<)�r02[� [Vendor:www.ai-thinker.com Version:0.9.2.4] ready AT+CWJAP="OpenWrt","xxxxPasswordRemovedxxxx" OK AT+CWJAP? +CWJAP:"OpenWrt" OK AT+CIFSR 192.168.4.1 10.1.1.60 OK AT+CIPSTART="TCP","184.108.40.206",80 OK Linked AT+CIPSEND=6 > GET / SEND OK +IPD,1460:<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> [..and so forth, being the first 1460 bytes of the caia website's front page..]
However, this wasn’t entirely satisfactory. The HTML returned in response to a simple “GET /” request arrives much faster than can be spat out the ESP8266’s 9600bps serial interface. And the ESP8266’s simple TCP stack doesn’t have much buffer to absorb the packet burst from caia.swin.edu.au while waiting to send the results out the serial port. So the content (reply) arrived on the serial port in short 1460-byte bursts every 10-30 seconds or so. After a handful of packets, the connection ERROR’ed out without transferring the entire web page.
Future task: run tcpdump to watch the TCP connection’s behaviour on the wire, and confirm what limits exist for the ESP8266 to receive TCP/IP traffic across the WLAN interface that is destined towards whatever device is connected to the ESP8266’s serial port.