Getting started with the esp8266 and Arduino
The esp8266 is a relatively new wifi module that plays well with any microcontroller. Until recently, the CC3000-based modules had dominated, but at $35/each, they just haven’t been a viable option for a lot of use cases. In this post, I’ll show you the easiest way to get started with the esp8266 and I’ll show you how to update firmware as you go.
The esp8266 comes in many form-factors, but the 01 is the most common and is available from $5-15 each, and it’s the variant I’ll be using here. Before getting started, please note that this module expects 3.3v. If you hook it up to 5v, it will go up in smoke. One easy way to get the correct voltage is to grab a cheap LD33V voltage regulator and give yourself a 3.3v rail.
esp8266 Hello, World!
The first thing I like to do when getting a new toy is make the lights to blink & get some kind of output moving around. The esp8266 acts as a serial device, and you speak to it through AT commands. It’s fairly simple once you get the basics out of the way. Once you know how to deal with AT devices, you’ll be ready to play with XBees ;)
If you’ve already been playing with Arduino, you might have a FTDI cable already. If so, it is probably 5v. You’ll need to drop the supply down to 3.3v with a voltage regulator. Alternatively, I found these little ‘VisiPort2’ FTDI modules that are super cheap (on tindie) and have both 5v and 3.3v mode. I bought a couple of them and have been using them nonstop. I’ll be using one of these for the rest of the post.
To begin, you’re going to need to add a pull-up resistor connecting the VCC pin to CH_PD. I used a 3k ohm resistor and soldered directly to the top of the module. This resistor has to be there for pretty much anything you’re going to be doing, so it might as well be permanent. Next, connect VCC to your 3.3v supply and GND to ground. Next, connect TX from the module to RX on your FTDI module, and connect RX on the module to TX on the FTDI module. Now connect your FTDI cable to the computer and you should get a red LED on the module.
For this next part, I’m going to assume you know how to locate your FTDI serial device on your computer. If you don’t know what this means, leave a comment and I’ll help you find it. Assuming you’re all connected and good to go, open your terminal app of choice (I use iTerm for Mac) and enter something that looks like this, only substitute my serial device’s name for your own:
bash
$ screen /dev/tty.usbserial-A7045L3R 115200
If you get errors, make sure your FTDI drivers and everything are installed correctly and make sure you’re trying to talk to the right device. Also, depending on where you bought your module, it might have a different firmware intalled, which might have your esp8266 on a different baud rate. Mine came with a version that expected 115200, but you might have to try at 57600 or 9600. Those seem to be the most common rates with random new units.
If you get taken to a blank screen without messages/warnings/etc., then you should be good to go. At this blank screen, you don’t get a backspace key and anything you enter goes straight to the esp8266 module. If you send it junk or make a typo, just hit enter… it’ll complain back with “ERROR” but just ignore that. In the examples below, all of our commands are lines that start with AT, and everything else is response that comes from the esp8266. At your blank screen, type the following and hit return:
AT
You should immediatly get the following response:
```
OK ```
Woohoo! Now let’s look at wireless access points around us:
``` AT+CWLAP +CWLAP:(0,”“,0) +CWLAP:(4,”BJB”,-91) +CWLAP:(3,”NETGEAR47”,-93) +CWLAP:(3,”mbmbryan”,-42) +CWLAP:(4,”KANG”,-93)
OK ```
Let’s connect to mbmbryan, he sounds like a pretty swell guy and I bet his internet isn’t at all OMG THE WORST THING IN THE WORLD COME ON TIME WARNER GET YOUR CRAP TOGETHER.
``` AT+CWJAP=”mbmbryan”,”swellpassword”
OK AT+CIFSR 192.168.1.140 ```
So, my esp8266 is connected to mbmbryan wifi point! Let’s ping it:
bash
$ ping 192.168.1.140
PING 192.168.1.140 (192.168.1.140): 56 data bytes
64 bytes from 192.168.1.140: icmp_seq=0 ttl=255 time=60.985 ms
64 bytes from 192.168.1.140: icmp_seq=1 ttl=255 time=82.209 ms
64 bytes from 192.168.1.140: icmp_seq=2 ttl=255 time=102.019 ms
64 bytes from 192.168.1.140: icmp_seq=3 ttl=255 time=20.033 ms
64 bytes from 192.168.1.140: icmp_seq=4 ttl=255 time=40.464 ms
You can find the entire AT Command Set for the esp8266 here. Note that some commands are only available in newer firmware that you may not have installed.
actually using the esp8266
If your modules speak at 115200, you’re going to have a bad time unless you upgrade the firmware and knock that down a bit. The Arduino’s hardware rx/tx pins can handle 115200, but the software serial options to let you use alternate pins just can’t keep up reliably. So, if you want to keep it at 115200, you end up connecting and disconnecting the esp8266 every time you upload new code, and if you use the hardware rx/tx pins, you lose serial for debugging (you basically end up using software serial for Arduino debugging and hardware serial to talk to the 8266.) It’s super, super obnoxious.
However you choose to connect, all of the business with the esp8266 happens over a serial stream, which has no real beginning or end. You basically watch for available data on the serial port, read it in, and then figure out what to do with it.
- Understand the comunication flow. For example, when your device turns on, it’s going to need to go through the process of initializing the esp8266 module & connecting to the network. It will fail to connect randomly, so you have to be ready for that… use delays to give enough time for the serial buffer to collect some data so you can read it and respond.
- Use delays and make your own timeouts so you don’t get stuck in while(true) loops. Let’s say you’re reading in the body of a web request. You probably won’t know in advance exactly how big your response body is, and some header info is going to come along with it. You can deal with this by creating a buffer bigger than your request would be, then by reading data in for a full second and then stopping (with a timeout). As long as the request doesn’t take more than a second, you’ll have the full response in your data buffer.
- Read in ALL of the data before you start figuring out what to do with it. These things don’t have a ton of power and they work at a pretty high baud rate. If you get garbled output while playing, look to see how much stuff you have going on in the area where you’re reading in the output. Even something as simple as echoing it to screen while filling a buffer with the output was enough to bust larger requests in my testing.
- Reuse data buffers instead of making new ones all over the place. Once you read your response data in, it’s going to be tempting to chop off all of the leading junk. The best way I found to do this wasn’t to copy the good part into a new buffer, but to find the position where the good data starts and then shift it to the front of the char buffer & truncate the leftovers.
flashing the firmware
First, we need to put the module into firmware mode. To do this, connect the GPIO0 pin to GND. It’d be nice if it did some little blinky light sequence to confirm that it was in the right ode, but that isn’t going to happen. Next, download a copy of ‘esptool.py’ and make sure you have a working version of Python. Also download the latest firmware. To update firmware:
``` bash $ ./esptool.py -p /dev/tty.usbserial-A7045L3R write_flash 0x000000 esp8266.9.2.2.bin Connecting… Erasing flash… Writing at 0x0007ec00… (100 %)
Leaving… ```
The new firmware does a few things that you’ll want to be aware of right away. It bumps the rate down to 9600 and it expects you to enter CR+LF commands when talking to it. If you’re issuing soft_serial.println(“AT”)
style commands, it should still work fine, but you might need to manually enter those characters when you talk directly to the esp8266. Using screen on iTerm on a Mac, this means hitting Return after the command, then Ctrl + J.
``` AT
OK AT+GMR 0018000902
OK ```
To change the baud rate:
``` AT+CIOBAUD? +CIOBAUD:9600
OK AT+CIOBAUD=57600 BAUD->57600
OK ```
playing from here
Now you can re-connect your screen session at 57600. Pretty much anything under 115200 will work for software serial on arduino, so now you can connect the esp8266 anywhere on the Arduino. If you run into problems or if you notice any mistakes I made, please leave a comment below. Happy making :)