Mini Server with Command Queue Memory Issue

The Problem

Previously in my post, “Arduino + ESP8266 Mini Server with Command Que“, I showed how I overcame the problem of missing incoming messages from the ESP8266 by implementing a command queue system.  As with most engineering issues I have worked on… once you solve one problem you make another.

The command queue system worked great until I started stuffing the queue entries with a lot of data. I wanted a much more elaborate HTML page which ended up being + 800 characters long.  That pretty much got me into a bunch of memory problems that took me a long time to debug.

The Behavior

Everything was working great….. for a while.  Then I added a form to my HTML code.  The first time it served up the HTML, everything was great.  The next time, nothing would be sent back out.  Every time my program tried to send out the long HTML string saved in the corresponding queue entry, there was nothing coming out.  I thought I had broken my code someplace in the loop and spent a long time trying to back track.  Eventually I found out that if I cut my HTML size down, things were ok again.  The only difference was the length of the string.  I am not 100% sure, but that sounds like a classic memory corruption issue and I know using a lot of String objects in Arduino code is risky on memory.

The Plan

I spent a lot of time trying to figure out how to change from using an array of Strings to and array of  char arrays.  Ended up being a dead end.  Instead I stepped back and thought about how to actually address the real problem… wasting memory.

Instead of storing the entire command string in the queue, I am only going to store the type of command that needs to be sent  and any critical info (ie: the +IPD channel from the ESP8266).  When the queue pointer gets to the command entry, I will then formulate the string and send to the Serial1 port.  This should dramatically reduce the amount of memory I am wasting.

The Implementation

It took a lot of debugging and testing and revising.  Ran into an issue with multi-part command, but here is the relevant part.  I first have some #defines for the different types of commands to make the switch statement easier….

#define HTML_REQUEST 1
#define FAVICON_REQUEST 2

In the module to enter commands into the queue…

...
 if (InLine.indexOf("GET / ") != -1) {
 CommandQue[QueIn++]=HTML_REQUEST;
 NumberServed++;
 }
 if (InLine.indexOf("POST / ") != -1) {
 CommandQue[QueIn++]=HTML_REQUEST;
 NumberLEDRequest++;
 }
 if (InLine.indexOf("favicon.ico") != -1) { 
 CommandQue[QueIn++]=FAVICON_REQUEST;
 NumberIconReqs++;
...

Previously I will filling in an entire really long string when there was an HTML request that could be taking 100’s of bytes in memory multiplied by how many requests came in.  Now I am using only 1 byte in memory for each request.

Then in the module process the command…

 switch (CommandQue[QueOut]){
 case HTML_REQUEST:
 float CIPSendTime;
 //*** Build the HTML code ***
 //Note: Need this first since HTTP Header needs length of content
 HTMLCode = "<HTML>"
 "<HEAD><TITLE>Pete's Mini8266 Server</TITLE>"
 "<BODY><H1>Welcome to Pete's ESP8266 \"hacking\" project</H1>"
 "<form action=\"\" method=\"post\">"
 "<fieldset>"
 "<legend>Red LED State</legend>"
 "<input type=\"radio\" name=\"RedLEDState\" value=\"RED_ON\"> ON"
 "<input type=\"radio\" name=\"RedLEDState\" value=\"RED_OFF\" checked=\"checked\"> OFF<br>"
 "</fieldset>"
 "<fieldset>"
 "<legend>Green LED State</legend>"
...  Finish off the rest of the HTML code ...
Serial1.println("AT+CIPSEND=" + String(CommandQueIPD_CH[QueOut]) + ","+ String(HTTPHeader.length()+2));
...

Now there is only one long string and is sent and memory freed right away.

There is a lot more hacking to be able to match up the IPD channel with the string and continue queuing up request between multi-step commands but too long and detailed to explain.  The really messy code is available here:

https://drive.google.com/file/d/0B1a0nPfCQQvKbThLeFM5MW44dFU/view?usp=sharing

Save to your local drive and then you can open it in a text editor if you don’t have the Arduino ID.

The coding is REALLY sloppy for now.  Will go back to clean up once I get everything I want working.

The Testing

I have been hitting the mini-server from multiple clients with more than a 6 line web page and things seem to be working well.  I do get random ESP8266 resets but my recovery code has been able to re-init and get everything working again each time.

The Next Step

Going to move on and show how I am using an HTML form and the “post” mechanism to control LED’s on my board from a web page.

Advertisements

2 thoughts on “Mini Server with Command Queue Memory Issue

  1. Pingback: LED’s Control Through ESP8266 + Arduino Web Page | PetesTechProjects

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s