CC3000 client.read() seems to hang

Adafruit Ethernet, Motor, Proto, Wave, Datalogger, GPS Shields - etc!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
cosutton3
 
Posts: 3
Joined: Thu Sep 18, 2014 4:44 pm

CC3000 client.read() seems to hang

Post by cosutton3 »

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 read is successful. Within a several minutes (it varies), however, the code hangs up AFTER successfully reading ALL values. At this point I have to reset the board(s). 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.com/adafruit/Adafruit_CC3000_Library. 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. Has anyone else run into this? Any ideas/solutions, elegant or otherwise?
A tremendous thanks for your time in advance!

Here's the Arduino code:

Code: Select all

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

#define WLAN_SSID             "BANNED" 
#define WLAN_PASS             "BANNED"
#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:

Code: Select all

<?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


I've just noticed that when arduino prints a preceding "3a" to serial monitor before the expected data values, the program continues to run. If the "3a" isn't printed to the Serial monitor, the program predictably hangs up. I don't know where the "3a" comes from.

User avatar
adafruit_support_mike
 
Posts: 67485
Joined: Thu Feb 11, 2010 2:51 pm

Re: CC3000 client.read() seems to hang

Post by adafruit_support_mike »

Try adding a call to cc3000.checkConnected() before calling cc3000.connectTCP().

Wireless connections are inherently more vulnerable to noise and interference than hardwired connections, so it's normal for a wifi connection to drop once in a while. You need to make sure the link-layer connection is good before making a network/transport layer connection.

User avatar
cosutton3
 
Posts: 3
Joined: Thu Sep 18, 2014 4:44 pm

Re: CC3000 client.read() seems to hang

Post by cosutton3 »

Thanks Mike! I appreciate the response. I just tried wrapping my loop() code in an if(cc3000.checkConnected()), but the outcome remains the same. Furthermore, I'm not sure this applies because I consistently receive data from the remote server just before the hang-up.

I'm outside my comfort zone now, but could this relate to rx buffer size?

User avatar
adafruit_support_mike
 
Posts: 67485
Joined: Thu Feb 11, 2010 2:51 pm

Re: CC3000 client.read() seems to hang

Post by adafruit_support_mike »

I think it's a buffering problem, but not a buffer size problem.

The innermost loop where you read the data from the server doesn't actually check the buffer to see if data is available:

Code: Select all

    for(int q = 0; q < 5; q++)
    {
        c = client.read();
        [ . . . ]
    }
If you read faster than data arrives in the buffer, the data you've read will fall out of sync with what the logic thinks has been read. You can do two things to improve that.

First, check the buffer in your inner loop:

Code: Select all

    int q = 0;
    while ( q < 5 ) {
        if ( client.available() > 0 ) {
            c = client.read();
            q++;
            [  . . . ]
        }
    }
Second, tweak the part of your code that finds the beginning of a line so it discards characters until it sees the one it wants:

Code: Select all

    char c = 0;
    while ( c != '>' ) {
        if ( client.available() > 0 ) {
            c = client.read();
        }
    }
    Serial.print( c );
    [ . . . ]
The first one will keep the code in sync with the incoming data. The second one will keep data moving through the buffer if something unexpected happens.

User avatar
cosutton3
 
Posts: 3
Joined: Thu Sep 18, 2014 4:44 pm

Re: CC3000 client.read() seems to hang

Post by cosutton3 »

Hi Mike. This is excellent. Thanks very much for taking the time to assist.

User avatar
adafruit_support_mike
 
Posts: 67485
Joined: Thu Feb 11, 2010 2:51 pm

Re: CC3000 client.read() seems to hang

Post by adafruit_support_mike »

That's why we're here. ;-)

User avatar
Marcio_Araujo
 
Posts: 1
Joined: Fri Nov 06, 2015 8:20 am

Re: CC3000 client.read() seems to hang

Post by Marcio_Araujo »

Hi Mike, I have almost the same problem: Let's to the code below:

Code: Select all

if (cc3000.checkConnected())
  {
   ...(code)...
linha10:
    while(client.connected())
    {
      Serial.println(F("I get a problem!"));
      client.flush();
      client.close();
      client.stop();
    }
    if (clientconnect(server, 80))
    {
      delay(100);
      client.fastrprint("POST /etc/etc HTTP/1.1\r\n");
      client.fastrprint("Host: "); client.fastrprint(server);
      ...(code)...
      lastRead = millis();
      while (client.connected() && ((millis() - lastRead) < IDLE_TIMEOUT_MS)) // Ok, no problem.
      {
        while (client.available() && ((millis() - lastRead) < IDLE_TIMEOUT_MS)) // Here starts the problem...
        {
          wdt_enable(WDTO_8S);
          char c = client.read();
          wdt_disable();
          if (c == '<' ) // '<' is my begining character
          { 
            startRead = true;
            Serial.print(c);
          }
          else if (startRead)
          {
            if (c != '>') //'<' is my final character -  if c = the characters in the middle of the message.
            {
              if (stringPos == 0 && c != '1') // I do this if the server responds nonsense 
              {
                goto linha10; //above
              }
              inString[stringPos] = c;
              stringPos ++;
              Serial.print(c);
            }
            else // if c = '>' final character
            {
              startRead = false;
              Serial.println(c);
              while(client.connected()) // it's is very importante, use while because the server hangs a lot.
              {
                Serial.println(F("Ok I finish without problem."));
                client.flush();
                client.close();
                client.stop();
                delay(100);
              }
            } //end of else
          } //end of else if(startRead)
          if(c != '>') // Now I began to invent out of desperation
          {
            Serial.print(F("available: "));
05       Serial.println(client.available());
            if(client.available() >= 1 || client.available() <= 63) // I try a lot of things, but don't win nothing yet
            {
            }
            else // I'm not getting into this Condition
            {
              goto linha05;
              resetFunc();
            }
          }//end of if
        }//end of while (client.available() && ((millis() - lastRead) < IDLE_TIMEOUT_MS)) 
        delay(10);
      }//end of while (client.connected() && ((millis() - lastRead) < IDLE_TIMEOUT_MS)) 
So, lets go:
In line 05: When the response is diferente of 1 to 63 the next line "if(client.available() >= 1 || client.available() <= 63)" hangs.

I already use while(client.available()), while(!client.available()), if(!client.available()) and nothing.

Do you know if the server respond something like '\n' or '\r' or NULL and thats why is locking the condiction?

I would like to know if we may use other function to know if the server is available.

Thanks in advance.

Márcio BANNED

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino Shields from Adafruit”