Wednesday, 28 September 2016

ESP8266 upgrade woes

While hacking strings and character arrays around is pretty normal in the microcontroller world, when you're sending serial data as text, it's also a laborious pain to code up. Which is probably why most Arduino examples using the ESP8266 wifi module use the esp8266.h library.

Which is great.
Except it doesn't work with our firmware.

Once again, we're up against the idea of library abstraction.
While hiding everything away and making it accessible through a few functions makes your main code look neat, that only holds true for as long as the library works! And when you've built a project based on a library that doesn't work, it's often more hassle trying to untangle someone else's code than it would have been to build your own from the ground up.

Anyway, we struggled with the esp8266.h library for a couple of reasons: First up, our wifi SSID is 18 characters long. The esp8266.h library has buffers for 16 character strings. It's a quick fix, once you know where to look - but infuriating for a long while, when the command

AT+CWJAP = "SSIDquitealongname","password"

was being sent to the wifi module as

AT+CWJAP = "SSIDquitealongnamepassword","password".

No wonder we couldn't connect to the router! (the reason, presumably, being that our SSID character array did not contain a \0 trailing character to indicate the end of a string, so the code/library/mcu ran on into the next memory space, until it found the \0 byte at the end of our password. However, there's no guarantee that the SSID and password strings would be in continuous sections of memory space - it could just have easily been a load of random garbage!

To fix this, we had to change the esp8266.h file and increase the buffer size


And then in the esp8266.cpp file, because we didn't bother working out which functions were used to handle the SSID/password combination, wherever there was a character array of 16 characters, we increased the buffer size to 20.



This at least allowed us to connect to the router successfully and to obtain an IP address.
But even then, we had to do a bit more hackery. See, the ESP8266 library expects certain responses from the wifi module. One of these responses is that when the AT+CIFSR instruction is sent, the response includes the character pattern STAIP followed by the IP address

Our (updated) wifi modules don't do this. They simply split out the IP address followed by OK.
So instead of looking for a response of STAIP, we had to know the beginning range of our IP address, and look for that instead.


In fact, we found the esp8266 library full of little things like this - expected responses and strings either chopped up or entirely discarded, depending on what the firmware expected to receive (rather than what the actual response was).

In short, it looks like we're going to have to abandon the esp8266 library and write something ourselves. And if you've updated your firmware using the same files as we did a little while back (so your firmware boots up looking like the screenshot below) you might have to do the same!