ESP8266 - getting started

I picked up a couple of ESP8266 modules - an inexpensive little SoC with WiFi - from AliExpress but ran into a couple of weird issues when trying to get them up and running. A lot of documentation is a little confusing, since it usually begins with flashing an image even though when you power it most likely starts up an open WiFi access point you can connect to. 

Anyway here are the issues I ran into, in order - coincidentally they capture a pretty simple workflow for getting started on the ESP8266.

Issue 0 - uhh ... what do I connect to where?

Update: I didn't know this at the time, but you can simply install the USB to UART bridge drivers from Silicon Labs and connect to the board via USB - on my laptop it appears as /dev/SLAB_USBtoUART. Using this method you can skip this whole section. 

There's dozens of different ESP8266 boards, each with their own little configurations, layouts and labels. Since I bought unbranded boards from AliExpress I didn't really know the search terms to take me to a nice simple diagram of what needs to be connected to each pin of my TTL cable. Anyway my boards look like this:

They connect to my TTL cable a little like this

Just in case it isn't clear from the picture - since I stupidly didn't match up all the colours - here's exactly what is connected to what:

<create table showing connections>

Even though there's a micro-USB connector this set of connections is sufficient to bring up the board and send some simple commands to it.

Issue 1 - connecting via serial (screen/OS X)

There's a very key bit of info for OS X users that's usually skipped over. When you attempt to connect to the ESP8266 using a USB TTL cable and screen you can be mistaken for thinking you've messed something up or you've got a dud chip, as it fails to respond to any input:

Sending an "AT" should result in the response "OK", but in this case the cursor just jumped to the left of the screen and nothing else happened. What's happened here is that GNU Screen on OS X is handling the Return key weirdly, sending only a CR character instead of CR+LF. I played around with the man page for a while but couldn't get it to play nice - eventually I downloaded CoolTerm which did the job nicely.

Issue 2 - firmware

After you've confirmed the chip is up and running by successfully issuing an "AT" you'll probably want to do something a little more useful with it. Since you likely don't speak AT (though a reference is here if you want to try) something simpler like Lua might be suitable. This will involve downloading a binary (or building it yourself, if you feel adventurous), and setting up a couple of things in python.

To save the bother of setting up dev tools for now, we'll use a service which will build a nice little NodeMCU image for you - http://nodemcu-build.com. Here's the build config I used:

Once it's complete you'll receive an email detailing the download link - I received two and opted to use the Integer one, which worked out nicely

To let us flash the ESP8266 we need to connect up the GPIO0 pin (which is labelled "D3" on my board) and reboot it so that it's in "flash" mode - here I've done this with the white cable.

Next we'll need to open up a terminal and setup pyserial and esptool, then download our image and flash it. Both pyserial and esptool can be retrieved via git - I'm just gonna be brief with this part as I've already spent a lot of time with screenshots and pictures already.

$ git clone https://github.com/pyserial/pyserial
Cloning into 'pyserial'...
remote: Counting objects: 4305, done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 4305 (delta 0), reused 0 (delta 0), pack-reused 4301
Receiving objects: 100% (4305/4305), 1.06 MiB | 1.01 MiB/s, done.
Resolving deltas: 100% (3207/3207), done.
Checking connectivity... done.
$ cd pyserial
$ sudo python setup.py install
Password:
running install
... lots of lines later ...
Installed /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pyserial-3.0.1-py2.7.egg
Processing dependencies for pyserial==3.0.1
Finished processing dependencies for pyserial==3.0.1
$ git clone https://github.com/themadinventor/esptool
Cloning into 'esptool'...
remote: Counting objects: 293, done.
remote: Total 293 (delta 0), reused 0 (delta 0), pack-reused 293
Receiving objects: 100% (293/293), 106.48 KiB | 0 bytes/s, done.
Resolving deltas: 100% (157/157), done.
Checking connectivity... done.
$ cd esptool

Now we can download our NodeMCU binary, double-check the path of our USB TTL device (since I always forget) and start flashing

$ curl -LO http://nodemcu-build.com/builds/nodemcu-master-7-modules-2016-01-18-22-47-15-integer.bin
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  388k  100  388k    0     0   247k      0  0:00:01  0:00:01 --:--:--  633k
$ ls /dev/tty.usbserial* 
/dev/tty.usbserial-A402O00H
$ python esptool.py --port /dev/tty.usbserial-A402O00H write_flash 0x00000 ./nodemcu-master-7-modules-2016-01-18-22-47-15-integer.bin 
Connecting...
Erasing flash...
Took 1.90s to erase flash block
Wrote 398336 bytes at 0x00000000 in 43.5 seconds (73.2 kbit/s)...

Leaving...
$ 

Now the board should be ready to reboot - if we go ahead and reboot it then connect using CoolTerm (changing to use 9600 baud instead of the 115200 we previously used) there should be a nice little Lua prompt waiting.

Issue 3 - what now?

So what cool things can we do now with our tiny little WiFi chip? Well firstly let's understand and tackle that pesky cannot find init.lua error message. After the NodeMCU firmware boots it searches for a file in the onboard eeprom called "init.lua" whose purpose is to allow you to run some lua code after boot, so you can setup a simple program or define some useful functions without having to get your hands dirty and rebuild the NodeMCU firmware and reflash.

So if we want to create a simple init.lua which prints out a little message on boot, here's what we can do.

$ git clone https://github.com/4refr0nt/luatool
$ cd luatool/luatool
$ echo 'print("check out my cool new ESP8266!")' > ./init.lua
$ ./luatool.py --port /dev/tty.usbserial-A402O00H --src init.lua --dest init.lua --verbose
Upload starting
Stage 1. Deleting old file from flash memory
->file.open("init.lua", "w") -> ok
->file.close() -> ok

Stage 2. Creating file in flash memory and write first line->file.remove("init.lua") -> ok

Stage 3. Start writing data to flash memory...->file.open("init.lua", "w+") -> ok

Stage 4. Flush data and closing file->file.writeline([==[print("check out my cool new ESP8266!")]==]) -> ok
->file.flush() -> ok
->file.close() -> ok
--->>> All done <<<---
$

Now any time you reboot your ESP8266 here's what you'll see instead of that error message:

There are a few nice examples at http://nodemcu.com, which you can either key in manually or upload as part of an init.lua file so that they always run on startup - just be careful you don't leave your ESP8266 in an infinite loop or else you'll have to reflash the firmware and start again. To save you the trouble, here are a couple of simple of examples, all of which involve connecting to a wifi network and serving some data.

The first is a simple hit counter, which records the number of requests it has served, and displays these on a simple page. Send the file using luatool similar to the previous example (changing --src parameter but ensuring --dest is still "init.lua"). Here's what you'll see after visiting the page - because Chrome attempts to fetch both the page and favicon.ico each hit is registered twice :)

Code: hitCount.lua

The second example allows you to switch the onboard LED on or off using a button on the page (which sends a POST request via AJAX). Because we're just dealing with raw TCP requests, I use a very inefficient/wrong way to decide whether or not we're handling a POST request - but since it's just a demonstration it's ok.

After loading the page and toggling the LED here's what we see:

Code (program): ledToggle.lua

Code (webpage): led.html

So there we have it - a simple introduction to connecting to an ESP8266 board, flashing with NodeMCU firmware and a couple of little pointers on how to use luatool to create a lua script which runs at startup. To find out more about the libraries available on NodeMCU check out their page on Read The Docs or for a little more info about the Lua programming language check out Programming in Lua 1st Edition

I seem to have written a few too many "Getting Started" guides, however I'll be spending a fair bit of time in the future on the ESP8266 as it offers plenty of opportunities for interesting work.