Investigating the ESP8266–Serial Killing

The ESP8266 is a potentially revolutionary new, small WIFI module costing under £3 ($4). Revolutionary because it will allow small microcontrollers to interface with the web without a) a costly ETHERNET card, b) a more costly traditional WIFI unit and c) without a costly (in terms of storage) library for Ethernet – which can take up half of, say an Arduino UNO’s FLASH memory.

The ESP8266 units work serially – i.e. you talk to them via serial in and they talk back via serial out. They require +3.3v and ground. Regardless of whether you are using a 5V processor or 3v3, the serial output will work with both – but you may consider a level shifter to talk from the processor to the WIFI board if the former uses 5v. This can be as simple as a resistive divider. I am using just in fact a series resistor – but then – my one and only board doesn’t work properly.

Initial translations and blogs out there suggest you need serial in and out – and SOME of tem suggest you also need to take a pin called  CH_PD to +3.3v. The problem is that there are identical looking boards some of which have that pin and NEED it connecting high – others don’t have that pin.  Check out here and here.

So – most of the common code you see will instruct you that the units need 115,200 baud data – and that you start the ball rolling with a reset command. They usually show the use of the Arduino serial port – sending out the command – and an option I’d never used before to analyse the result.. i.e. Serial.find()

So – armed with my new chip I went off and tried this – everyone in the web is using an Arduino with only one serial port – I prefer the Atmega1284 which is the same but better and has 2 serial ports – so when you see me refer to Serial1.find() you’ll realise I’m talking about the second serial port.

So to start the ball rolling you send this…


And you get (or I get) this rubbish back if you care to look at it.


Eh? What’s this – that’s not what I SAW – it’s what pasted into this blog. What I SAW was this..


  ets Jan  8 2013,rst cause:4, boot mode:(3,7)tail 12
chksum 0xe0
ho 0 tail 12 room 4
load 0x3ffe8000, len 3168, room 12
tail 4
chksum 0x93
load 0x3ffe8c60, len 4956, room 4
tail 8
chksum 0xbd
csum 0xbd


How can this be? Why can’t I paste the lot?  This happened over and over – the copy and paste from the COM window to Windows Live Writer would not work – I ignored it – software bug.

But herein lies the rub…here’s the code I used…

Serial1.begin(115200); // for debugging

Serial1.println(“AT+RST”); // reset and test if module is ready
while (my>millis()) { if (Serial1.available()>0){  Serial.print((char); my=millis()+2000; } }

Why on EARTH would the result be spit up like that above…

So – here’s what everyone else is using with a variation, I’m looking for (OK) – others look for “ready” – bear with me..… we’ll not repeat the initialisation code here.

Serial1.println(“AT+RST”); // reset and test if module is ready
if (Serial1.find(“OK”)) Serial.println(“Got OK”);

I’d never used this before.. send the data out and wait 5 seconds OR return if you get the sequence OK.

But – what of the REST of the result.. all that crap that comes after ok? SURELY the find() function must wait SOME time and get rid of it – or is it  going to be sitting there waiting to ambush future checks?

And it gets worse.. because the ABOVE works! But this which others are using, doesn’t.

Serial1.println(“AT+RST”); // reset and test if module is ready
if (Serial1.find(“ready”)) Serial.println(“Got ready”);

How can that be – everyone else couldn’t possibly be wrong – how can they find “ready”?  So I made this combination..

Serial1.println(“AT+RST”); // restet and test if module is redy
if (Serial.find(“OK”)) Serial.println(“Got OK”);

while (my>millis()) { if (Serial1.available()>0){  Serial.print((char); my=millis()+2000; } }

So this time I’d trap OK – and then look to see if there was anything left… and little surprise there. All the stuff following OK came flying into view!!

So I tried this – as the data all comes within a second or so – surely a delay after sending would ensure the whole lot was in the buffer ready for checking?

Serial1.println(“AT+RST”); // reset and test if module is ready
if (Serial1.find(“OK”)) Serial.println(“Got OK”);

while (my>millis()) { if (Serial1.available()>0){  Serial.print((char); my=millis()+2000; } }

Erm, NO!!

Got OK

ets Jan  8 2013,rst cause:4, boot mode:(3,7

Exactly – by now I was thinking of taking up woodwork… the OK was trapped but not only was some of the stuff left in the buffer – but the text “ready” was missing off the end!! A light bulb turned on… Could some of this  have to do with fact that the Serial buffer in Arduino is only 64 bytes long?? There’s more than 64 bytes here…  So presumably by waiting, I’d LOST the remainder.

Then I twigged – if you’re waiting for “ready” you might never get it if the buffer fills up and does not discard what’s there… and that would account for the result above – how on EARTH are others getting this to work?

Then I remembered something about increasing the default buffer size for serial.

In HardwareSerial.cpp – which is located at  hardware/cores/standard  or in my case as I’m using the 1284 chip and have a special setup for it the file is located under my documents at hardware\mighty-1284p\cores\standard

Sure enough – I increased the size of the SERIAL_BUFFER_SIZE from 64 to 512 bytes (I have 16K Ram on the 1284) and the LOST DATA problem above went away.

But it STILL would not find “ready” – at which point I thought – you know – I’ve invested 512 bytes of RAM and this is getting WAY too messy – I’ve never used .find() before – so it won’t be missed  – I could only assume there must be a special character in there somewhere stopping me finding “ready”

And sure enough – it would find OK but not reset or ANY word after that OK area – maybe a NULL in there somewhere??  I could have checked but life is short.  There had to be a better way. SO I wrote my own… I wanted something that would search for a phrase, waiting a certain length of time – but also waiting after anything ELSE came through until the buffer was truly empty..

Serial1.println(“AT+RST”); // reset and test if module is ready
if (SerialFinder(Serial1,”ready”,3000,300)) Serial.println(“GOT IT!!”);

Spot on!  Now, that still does not account for why my WIFI module won’t work  properly – that may well need another module purchasing to compare with – but I hope that helps others who may well be struggling with this very issue. Here is the function below – just drop it in your code or in a library somewhere  – do what you will with it. It’s simple enough… feed it the string – it will return true or false whether it finds the string or not – but not until the timeout. You could add a parameter to kill the timeout once the string is found – but then – what about anything coming in after then and you can’t just flush the buffer – info may not have yet finished coming in. Seems to me the right option would be to just make the delay “sensible”.  You can of course change from Serial1 to Serial etc (multiple serial does not work if you’re using a humble UNO but the mega has either 2 or 2 UARTS and I DEFINITELY recommend having one for your project and one for monitoring/programming) anyway – here it is.

boolean SerialFinder(HardwareSerial &refSer, char *str,unsigned long howlong,unsigned long timeout)
   boolean gotit=false;
   unsigned long mytime;
   char *strtemp;
   char incoming;
   strtemp=str; mytime=millis()+howlong;
   while ((mytime>millis()) || refSer.available()) // if timer demands or there is something there
    if (refSer.available())
       Serial.print(incoming); // for debug
       if (incoming==*strtemp) { strtemp++; if (*strtemp==0) {strtemp=str; gotit=true; } } else strtemp=str;
  return gotit;

And so I start again from scratch but at least this time knowing my searches work… and so it begins..

Serial1.begin(115200);// talking to WIFI
Serial.begin(115200); // for monitoring
Serial.println(“Initiating with AT+RST”);
Serial1.println(“AT+RST”); // restart module
if (SerialFinder(Serial1,”ready”,2500,200)) Serial.println(“Good”); else Serial.println(“Nope!”);

1284P and SD Cards

Just what is it with the Arduino people – they seem to have it in for the 1284p – one of the best chips out there. WHY is it a good chip? Well, it runs all Arduino projects – but you get 128K of FLASH and 16K of RAM – is that a good enough reason? AND they do a DIP version so it’s a doddle to do prototyping with it – and its’ cheap – and has lots of pins etc.

BUT – some of the libraries pretend the chip doesn’t exist.. SD is one of them –  I just updated the SD library and I happened to try a little test program to put something in SD on the normal Ethernet card… Nothing… I made sure I specified the select line (I chose output 27 – the Ethernet select line is output 4 on these chips normally)…. nothing.. then I remembered I’d updated the library – went on a search and found THIS. See code below – but I suggest ALSO adding for the 1284 – so see latter of the two updates.. this might apply to other libraries if you have any hassle…

Go into this file: C:\Program Files (x86)\arduino-1.0.1\libraries\SD\utility\Sd2PinMap.h
Change this line: #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
to: #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega1284P__)

Go into this file: C:\Program Files (x86)\arduino-1.0.1\libraries\SD\utility\Sd2PinMap.h
Change this line: #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
to: #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega1284__)