Sunday, 16 November 2014

Connecting hardware to a smart device using a cheap ESP8266 wifi module

These ESP8266 wifi modules are great.
They're cheap, and simple to work with. For simple tasks.

Try to get too clever with them, and they crap out and lock up and need a full power-cycle to sort out. But keep your data to short little packets, and they're pretty solid, robust little devices.

After getting one working by sending AT commands over serial, we decided to take it a stage further: to build a self contained little module that you could just give power to, and it would hook up to a home router/network.

We've recently got re-acquainted with the old Nokia 5110 displays, so it made sense to build something around that for our unit. Originally we planned to have the wifi module list all available APs (access points) and allow the user to scroll through a list of them onscreen.

This idea worked fine, at the BuildBrighton Hackspace, where only three or four wifi access points are accessible from inside a big tin shed that acts like a large Faraday cage! Trying the same approach at home, where there can be ten or more available wifi hotspots at any one time, and the module couldn't cope.

We're assuming that the list of available wifi connections exceeded some string/character limit, and the wifi module simply fills up it's buffers trying to query every one in range - whatever the reason, using the AT+CWLAP command sometimes causes the wifi module to lock up.

What we needed was some way of entering an SSID and password, using the Nokia screen to display progress. Our imagined device would have only a few buttons, and a phone-text-style method of data entry could get a bit clumsy. It didn't take Steve long to suggest a menu-based interface and a rotary encoder for selecting letters/numbers/symbols from a pre-determined list of characters - a bit like when you used to put your initials on the high score table on the original Space Invaders arcade machines.

At first, a menu-based interface seemed like overkill - Steve loves everything to be aesthetically pleasing, we just like stuff to work! But his persistence paid dividends: despite making the firmware much more complicated than it was, the end result is an interface which is simple and intuitive to use. And more importantly, one that works!

(what's with the nasty jump in the video? Well, of course, I'm not going to publish my real wifi SSID and password on here - so I paused the video, entered the real username/password, and set the video recording again. Honestly, some people think you have to be an idiot to be in the Nerd Club!)

Surprisingly, the wifi modules retain their last connection details. We were anticipating having to store and retrieve SSID details to/from eeprom - but it turns out to be unnecessary. If you power down the wifi module, it will try to connect to the same source as last time, using the same SSID and password as before.

This makes our firmware quite a bit easier than we were expecting (once we got over Steve's extra complexity for the menu system). On boot up, we simply query our IP address, using the AT+CIFSR command, every 5-8 seconds. Once a connection has been established, we'll see an ip address in response to this command. If we get "error" or an empty string four times in succession, we move on to the "enter SSID "screen and prompt the user for their SSID and password.

Once these have been entered using the rotary encoder, we try again, four times. Setting the connection details using the AT+CWJAP command always returns OK - even if the password is incorrect and the connection failed. So we simply set the SSID/password combination, then query for a valid IP address, just as if the device had first switched on. If, after four attempts, there is no connection, we assume the connection details are incorrect, and prompt the user for their password again.

Once the wifi module has an IP address, we simply start it up as a server, using AT+CIPMUX=1 (to allow multiple clients to connect to it over the network) and then AT+CIPSERVER=1,port_number to start listening to incoming connections.

All in all, we're quite pleased with how far this has come.
The last stage is to get it all into a nice little enclosure and look like a "proper" wifi module - not just a homebrew circuit on a bit of home-etched PCB!