Adafruit CC3000 client.read() hangs within While loop

I am using the Adafruit CC3000 wifi shield with the Arduino Mega 2560 R3 to access a remote webserver. The code reads 16 values provided by a php file and then moves on. The values are float but read as char and then converted on Arduino. Most times, the connection and data read are successful. Within a several minutes (it varies), however, the code hangs up AFTER successfully reading ALL values. At this point I have to reset. I've tried putting timers on that section of the code, but everything hangs so the timers don't function.

I have just updated the firmware to the TI CC3000; it is currently version 1.28. I'm also using the latest Adafruit CC3000 library downloaded from here: GitHub - adafruit/Adafruit_CC3000_Library: Library code for Adafruit's CC3000 WiFi breakouts &c. The updates have not changed the outcome.

It seems to me either the client.read() or client.available() function is hanging up, but I have relative little experience with programming to dig into the libraries much.

Here's the Arduino code:

#include <Adafruit_CC3000.h>
#include <SPI.h>

#define WLAN_SSID             "xxxxxxx" 
#define WLAN_PASS             "xxxxxxx"
#define WLAN_SECURITY         WLAN_SEC_WPA2
#define ADAFRUIT_CC3000_IRQ   3
#define ADAFRUIT_CC3000_VBAT  5
#define ADAFRUIT_CC3000_CS    10   
       
Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT, SPI_CLOCK_DIV2);

String repository = "/gromon/";
uint32_t ip = cc3000.IP2U32(xxx,xxx,xxx,xxx);
int port = 80;

void setup(void)
{

  Serial.begin(115200);
  
  if (!cc3000.begin())
  {
    Serial.println("Can't initiate wifi board...");
    while(1);
  }

  if(!cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY))
  {
     Serial.println("Can't connect to WiFi AP!");
  }
  Serial.println("Connected to WiFi AP...");
    
  Serial.println(F("Check DHCP..."));
  while (!cc3000.checkDHCP())
  {
    delay(100);
  }
  
}


void loop(void)
{
    Adafruit_CC3000_Client client = cc3000.connectTCP(ip, port);
    char thresholdsettings[16][4];
    
    if (client.connected()) 
    {
        client.print("GET ");
        client.print(repository);
        client.print("readenvironparams.php?");
        client.println(" HTTP/1.1");
        client.println("Host: www.example.com");
        client.println(F(""));
        Serial.println(" Connected to readenvironparams.php. Awaiting data...");
    }
    else 
    {
      Serial.println(F(" Connection failed"));    
    }
    
    while (client.connected()) 
    {
           while (client.available() > 0) 
           {
                char c = client.read();
                
                if(c == '>')
                {
                       Serial.print(c);
                       
                       for (int i = 0; i < 17; i++)
                       { 
                           for(int q = 0; q < 5; q++)
                           {
                               c = client.read();
                               
                               if(c == '!')
                               {
                                 q=5;
                               }
                               else
                               {
                                 thresholdsettings[i][q] = c;
                                 Serial.print(thresholdsettings[i][q]);
                               }
                           }
                           Serial.print(" ");
                       }
                }                         //The failure happens about here just after successfully reading the last value provided by the PHP file.
                Serial.print(c);
            }
    }
    client.println("Connection: close");
    client.close();

    delay(30000);
}

This is the PHP file being used:

<?php

$link = include('conec.php');
$tblname = 'environparams';

$result = mysqli_query($link, "SELECT * FROM $tblname");			
 
if (!$result) {
  	echo "Failed to access db";
  	exit;
}

$row = mysqli_fetch_array($result);

echo ">" . $row['tempFthresholdlow'] . "!";
echo $row['tempFthresholdhigh'] . "!";
echo $row['humiditythresholdlow'] . "!";
echo $row['humiditythresholdhigh'] . "!";
echo $row['phthresholdlow'] . "!";
echo $row['phthresholdhigh'] . "!";
echo $row['nutrientsthresholdlow'] . "!";
echo $row['nutrientsthresholdhigh'] . "!";
echo $row['h2olevelthresholdlow'] . "!";
echo $row['h2olevelthresholdhigh'] . "!";
echo $row['co2thresholdlow'] . "!";
echo $row['co2thresholdhigh'] . "!";
echo $row['dissolvedo2thresholdlow'] . "!";
echo $row['dissolvedo2thresholdhigh'] . "!";
echo $row['temph2othresholdlow'] . "!";
echo $row['temph2othresholdhigh'] . "!";


//close mysql connection
mysqli_close($link);	
?>

Here is the Serial output from the code above. The first entry is a success (reads through to value "85" and then prints "0"); the second is the failure (it reads to expected value "85", prints nothing more and completely hangs.

Connected to readenvironparams.php. Awaiting data...
HTTP/1.1 200 OK
Date: Thu, 18 Sep 2014 20:24:57 GMT
Server: Apache
Vary: Accept-Encoding
Transfer-Encoding: chunked
Content-Type: text/html

3a

50 200 20 95 6.2 7.4 10 40 10.5 14 600 1500 50 100 50 85
0

Connected to readenvironparams.php. Awaiting data...
HTTP/1.1 200 OK
Date: Thu, 18 Sep 2014 20:25:24 GMT
Server: Apache
Vary: Accept-Encoding
Content-Length: 58
Content-Type: text/html

50 200 20 95 6.2 7.4 10 40 10.5 14 600 1500 50 100 50 85

Has anyone else run into this? Any ideas/solutions, elegant or otherwise?

A tremendous thanks for your time in advance!

String repository = "/gromon/";

Pissing away resources on the Arduino is never a good idea. There is no reason NOT to make that a char *, instead, and save memory.

There is no reason not to be using the F() macro to keep this (and other) literals out of SRAM:
Serial.println(F("Can't initiate wifi board..."));

    char thresholdsettings[16][4];

This should be global.

           while (client.available() > 0) 
           {
                char c = client.read();
                
                if(c == '>')
                {
                       Serial.print(c);
                       
                       for (int i = 0; i < 17; i++)
                       { 
                           for(int q = 0; q < 5; q++)
                           {
                               c = client.read();

Each time there is at least one character to read, read all 85 of them. Does that really seem like a good idea?

                                 thresholdsettings[i][q] = c;

I don't think all 85 characters are going to fit in you 64 element array.

Once you correct these issues, let us know if you still have a problem.

Thanks for your input, Paul.

I have edited the test code to make the thresholdsettings array global, prints now use flash instead of SRAM, and - for test purposes - have removed the string variable altogether. The trouble remains.

Regarding the while & for loops used to read the data from the PHP file you ask:

Each time there is at least one character to read, read all 85 of them. Does that really seem like a good idea?

To me? Yes it does. I don't know of a better way. Suggestions? I am trying to read 16 floating point values (up to 4 bytes long, each, including decimal point) from the PHP file. There will always be 16 values and they will never be more than 4 bytes.

To me? Yes it does.

Really? One character arrives, so you think you can read 85 characters?

I am trying to read 16 floating point values

0 to 16 is 17 values, in case you failed to take your shoes off to count.
0 to 4 is 5 values.

You should read only what is actually available. Adjust the values of i and q as you read each character. Do NOT use any for loops.

Hi,

I am having the similar problem. I am using wifi but after a while the client.available no longer returns true and my code is no longer able to receive anything from my server.

I have no idea how this happens and my code is very simple, tested with no memory leak.

Have you fixed this issue?

One thing you probably need to do is ensure every operation on the network times out
automatically - its possible for a connection to get into a stuck state, if so you need to
take the initiative and close your end of the connection and retry if things
are taking too long, not just expect the other end to close the connection for you.

Practice defensive programming.