Hi,
I had a look over the forum to see if there was a similar issue, didn't see one the same as mine so here goes..
I am using the cc3000 breakout board to connect to my server to retrieve some information i.e. commands, Its running the webclient example. It runs perfectly and does everything I need it to, but every so often it will hang on "Connect to xx.x.xx.xxx".
I originally thought it may be a arduino memory issue but I have since found out that it is a connection issue.
I disabled my server and ran the code and was able to replicate the issue, Everything works (connecting, dhcp, get server ip address etc.) great up until it tries to connect to the server, which obviously wont work when the server is disabled.
So what I think I need is a way to timeout this part of the code. Im pretty sure its the connectTCP() function in the library, Is there a way to insert a timeout type function in there? So if its trying to connect for say 2 seconds it will stop and move onto the next part of the code.
Any info would be greatly appreicated,
Thanks
[Solved] CC3000 Hang
Moderators: adafruit_support_bill, adafruit
Please be positive and constructive with your questions and comments.
-
- Posts: 3
- Joined: Mon Dec 09, 2013 10:44 am
[Solved] CC3000 Hang
Last edited by nmck on Tue Dec 10, 2013 6:47 pm, edited 1 time in total.
- adafruit_support_rick
- Posts: 35092
- Joined: Tue Mar 15, 2011 11:42 am
Re: CC3000 Hang
I forwarded this to engineering
- PlastiBots
- Posts: 120
- Joined: Fri Mar 25, 2011 7:12 pm
Re: CC3000 Hang
I'll also add that I have a similar issue. I have a project that retrieves info from the server (based on the AF WiFi Robot). I added some timer code to print the duration to the serial window and let it run a number of times. Although the timing of the crash varies, it always does at some point. I've seen ranges from 25 minutes to 3 hours of run time. For these cases, I am doing nothing with the robot and the webserver json file contents are not changing - it's retrieving the same data with each call. However, when I use WiFi Bot Control to send commands (which causes the json file to be updated very quickly), the sketch seems to crash sooner (i.e within 1-2 minutes of driving the robot).
I can only speculate, but it seems that there is some disruption possibly between the sketch making the call to the server and reading the json file contents and WiFi Bot Control making calls to the server to update the (same) json file. However, I would expect, if this was the issue, that the crash would be immediate. I suppose it could be the WiFi connection.
It would be nice if there was a catch routine we could add that could be used to detect an issue, and allow for a re-connect. Of sorts.
I can only speculate, but it seems that there is some disruption possibly between the sketch making the call to the server and reading the json file contents and WiFi Bot Control making calls to the server to update the (same) json file. However, I would expect, if this was the issue, that the crash would be immediate. I suppose it could be the WiFi connection.
It would be nice if there was a catch routine we could add that could be used to detect an issue, and allow for a re-connect. Of sorts.
- tdicola
- Posts: 1074
- Joined: Thu Oct 17, 2013 9:11 pm
Re: CC3000 Hang
Do you mind posting the code for the webclient example that is hanging? There was an issue with servers that closed the connection too quickly causing the example to get stuck in a loop. This was fixed recently in the library by adding a timeout to receive data, but you might be using the older example code.
-
- Posts: 3
- Joined: Mon Dec 09, 2013 10:44 am
Re: CC3000 Hang
Here is is the webclient example code I am working from:
There is a timeout function in there for adjusting the response time but from what I can tell it doesn't reach that part of the code. This is why I suspect it is something to do with the connectTCP() function.
It may be because the port is open on the server so it does get through but there is nothing there, if I visit the address on my web browser (chrome) then it tries to load the page for about 10 seconds before saying "Oops! Google Chrome could not connect to xx.xx.xx.xx". So what would be useful is some similar functionality in the connectTCP() function where after some time it will move on.
Code: Select all
/***************************************************
This is an example for the Adafruit CC3000 Wifi Breakout & Shield
Designed specifically to work with the Adafruit WiFi products:
----> https://www.adafruit.com/products/1469
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried & Kevin Townsend for Adafruit Industries.
BSD license, all text above must be included in any redistribution
****************************************************/
/*
This example does a test of the TCP client capability:
* Initialization
* Optional: SSID scan
* AP connection
* DHCP printout
* DNS lookup
* Optional: Ping
* Connect to website and print out webpage contents
* Disconnect
SmartConfig is still beta and kind of works but is not fully vetted!
It might not work on all networks!
*/
#include <Adafruit_CC3000.h>
#include <ccspi.h>
#include <SPI.h>
#include <string.h>
#include "utility/debug.h"
// These are the interrupt and control pins
#define ADAFRUIT_CC3000_IRQ 3 // MUST be an interrupt pin!
// These can be any two pins
#define ADAFRUIT_CC3000_VBAT 5
#define ADAFRUIT_CC3000_CS 10
// Use hardware SPI for the remaining pins
// On an UNO, SCK = 13, MISO = 12, and MOSI = 11
Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT,
SPI_CLOCK_DIV2); // you can change this clock speed
#define WLAN_SSID "myNetwork" // cannot be longer than 32 characters!
#define WLAN_PASS "myPassword"
// Security can be WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA or WLAN_SEC_WPA2
#define WLAN_SECURITY WLAN_SEC_WPA2
#define IDLE_TIMEOUT_MS 3000 // Amount of time to wait (in milliseconds) with no data
// received before closing the connection. If you know the server
// you're accessing is quick to respond, you can reduce this value.
// What page to grab!
#define WEBSITE "www.adafruit.com"
#define WEBPAGE "/testwifi/index.html"
/**************************************************************************/
/*!
@brief Sets up the HW and the CC3000 module (called automatically
on startup)
*/
/**************************************************************************/
uint32_t ip;
void setup(void)
{
Serial.begin(115200);
Serial.println(F("Hello, CC3000!\n"));
Serial.print("Free RAM: "); Serial.println(getFreeRam(), DEC);
/* Initialise the module */
Serial.println(F("\nInitializing..."));
if (!cc3000.begin())
{
Serial.println(F("Couldn't begin()! Check your wiring?"));
while(1);
}
// Optional SSID scan
// listSSIDResults();
if (!cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY)) {
Serial.println(F("Failed!"));
while(1);
}
Serial.println(F("Connected!"));
/* Wait for DHCP to complete */
Serial.println(F("Request DHCP"));
while (!cc3000.checkDHCP())
{
delay(100); // ToDo: Insert a DHCP timeout!
}
/* Display the IP address DNS, Gateway, etc. */
while (! displayConnectionDetails()) {
delay(1000);
}
ip = 0;
// Try looking up the website's IP address
Serial.print(WEBSITE); Serial.print(F(" -> "));
while (ip == 0) {
if (! cc3000.getHostByName(WEBSITE, &ip)) {
Serial.println(F("Couldn't resolve!"));
}
delay(500);
}
cc3000.printIPdotsRev(ip);
// Optional: Do a ping test on the website
/*
Serial.print(F("\n\rPinging ")); cc3000.printIPdotsRev(ip); Serial.print("...");
replies = cc3000.ping(ip, 5);
Serial.print(replies); Serial.println(F(" replies"));
*/
/* Try connecting to the website.
Note: HTTP/1.1 protocol is used to keep the server from closing the connection before all data is read.
*/
Adafruit_CC3000_Client www = cc3000.connectTCP(ip, 80);
if (www.connected()) {
www.fastrprint(F("GET "));
www.fastrprint(WEBPAGE);
www.fastrprint(F(" HTTP/1.1\r\n"));
www.fastrprint(F("Host: ")); www.fastrprint(WEBSITE); www.fastrprint(F("\r\n"));
www.fastrprint(F("\r\n"));
www.println();
} else {
Serial.println(F("Connection failed"));
return;
}
Serial.println(F("-------------------------------------"));
/* Read data until either the connection is closed, or the idle timeout is reached. */
unsigned long lastRead = millis();
while (www.connected() && (millis() - lastRead < IDLE_TIMEOUT_MS)) {
while (www.available()) {
char c = www.read();
Serial.print(c);
lastRead = millis();
}
}
www.close();
Serial.println(F("-------------------------------------"));
/* You need to make sure to clean up after yourself or the CC3000 can freak out */
/* the next time your try to connect ... */
Serial.println(F("\n\nDisconnecting"));
cc3000.disconnect();
}
void loop(void)
{
delay(1000);
}
/**************************************************************************/
/*!
@brief Begins an SSID scan and prints out all the visible networks
*/
/**************************************************************************/
void listSSIDResults(void)
{
uint8_t valid, rssi, sec, index;
char ssidname[33];
index = cc3000.startSSIDscan();
Serial.print(F("Networks found: ")); Serial.println(index);
Serial.println(F("================================================"));
while (index) {
index--;
valid = cc3000.getNextSSID(&rssi, &sec, ssidname);
Serial.print(F("SSID Name : ")); Serial.print(ssidname);
Serial.println();
Serial.print(F("RSSI : "));
Serial.println(rssi);
Serial.print(F("Security Mode: "));
Serial.println(sec);
Serial.println();
}
Serial.println(F("================================================"));
cc3000.stopSSIDscan();
}
/**************************************************************************/
/*!
@brief Tries to read the IP address and other connection details
*/
/**************************************************************************/
bool displayConnectionDetails(void)
{
uint32_t ipAddress, netmask, gateway, dhcpserv, dnsserv;
if(!cc3000.getIPAddress(&ipAddress, &netmask, &gateway, &dhcpserv, &dnsserv))
{
Serial.println(F("Unable to retrieve the IP Address!\r\n"));
return false;
}
else
{
Serial.print(F("\nIP Addr: ")); cc3000.printIPdotsRev(ipAddress);
Serial.print(F("\nNetmask: ")); cc3000.printIPdotsRev(netmask);
Serial.print(F("\nGateway: ")); cc3000.printIPdotsRev(gateway);
Serial.print(F("\nDHCPsrv: ")); cc3000.printIPdotsRev(dhcpserv);
Serial.print(F("\nDNSserv: ")); cc3000.printIPdotsRev(dnsserv);
Serial.println();
return true;
}
}
It may be because the port is open on the server so it does get through but there is nothing there, if I visit the address on my web browser (chrome) then it tries to load the page for about 10 seconds before saying "Oops! Google Chrome could not connect to xx.xx.xx.xx". So what would be useful is some similar functionality in the connectTCP() function where after some time it will move on.
- tdicola
- Posts: 1074
- Joined: Thu Oct 17, 2013 9:11 pm
Re: CC3000 Hang
Ah thanks for confirming, yep that looks like the fixed example code. I was poking around a bit at the library source and it doesn't look like it's really possible to add a timeout without better support from TI. Here's a thread from TI support where they confirm the connect API (used internally by connectTCP) is blocking with a 1 minute timeout. It might be interesting to check if you see your sketch waiting a minute and then failing just to check that the 1 minute delay at least applies.
It does sound like there might be a way to reduce the timeout to 20 seconds though by calling their netapp_timeout_values API. You can get access to call this in your sketch by including "utility/netapp.h". I think you would want to do something like (untested):
It does sound like there might be a way to reduce the timeout to 20 seconds though by calling their netapp_timeout_values API. You can get access to call this in your sketch by including "utility/netapp.h". I think you would want to do something like (untested):
Code: Select all
unsigned long aucDHCP = 14400;
unsigned long aucARP = 3600;
unsigned long aucKeepalive = 10;
unsigned long aucInactivity = 20;
if (netapp_timeout_values(&aucDHCP, &aucARP, &aucKeepalive, &aucInactivity) != 0) {
Serial.println("Error setting inactivity timeout!");
}
-
- Posts: 3
- Joined: Mon Dec 09, 2013 10:44 am
Re: CC3000 Hang
Thanks tdicola! That seemed to do the trick, just what I was after.
As you mentioned the default timeout is 1 minute, however that doesn't seem to apply in the Arduino library. It needs to be explicitly called using netapp_timeout_values. The minimum timeout value is 20 seconds which works in the sketch.
Just for anyone wondering when the timeout occurs after 20 seconds the CC3000 returns "Connection error", the sketch then reacts as if there has been a failed connection (i.e. www.connected() returned false)
netapp_timeout_values may be a useful thing to add to the Adafruit library as it doesn't seem that the default values are initialized.
As you mentioned the default timeout is 1 minute, however that doesn't seem to apply in the Arduino library. It needs to be explicitly called using netapp_timeout_values. The minimum timeout value is 20 seconds which works in the sketch.
Just for anyone wondering when the timeout occurs after 20 seconds the CC3000 returns "Connection error", the sketch then reacts as if there has been a failed connection (i.e. www.connected() returned false)
netapp_timeout_values may be a useful thing to add to the Adafruit library as it doesn't seem that the default values are initialized.
- knack2
- Posts: 6
- Joined: Sat Dec 28, 2013 4:37 pm
Re: [Solved] CC3000 Hang
I believe I also have this same issue and see the posted code as a way to initialize the CC3000 timeouts but my questions is about where this would go in my sketch.
I initialize the CC3000 in the setup portion of the code and I have this code in my loop prior to the CC3000 routines to post to the website I am using but it hasn't seemed to help... my code still randomly hangs after some period of time. Everything compiles properly and seems to run but not sure if these timeouts are really being initialized.
I am just checking some basic sensors and printing to an LCD so not sure what else could be an issue.
Any help is appreciated.
I initialize the CC3000 in the setup portion of the code and I have this code in my loop prior to the CC3000 routines to post to the website I am using but it hasn't seemed to help... my code still randomly hangs after some period of time. Everything compiles properly and seems to run but not sure if these timeouts are really being initialized.
I am just checking some basic sensors and printing to an LCD so not sure what else could be an issue.
Any help is appreciated.
- tdicola
- Posts: 1074
- Joined: Thu Oct 17, 2013 9:11 pm
Re: [Solved] CC3000 Hang
Put the code in your setup function, after all the CC3000 setup code. I don't think it would hurt to have it in the loop, but try moving it out just to be sure.
Do you mind posting the code for the sketch? There might be something else that's causing the device to hang and it would help with troubleshooting.
Do you mind posting the code for the sketch? There might be something else that's causing the device to hang and it would help with troubleshooting.
- knack2
- Posts: 6
- Joined: Sat Dec 28, 2013 4:37 pm
Re: [Solved] CC3000 Hang
Code is below. Not sure my code is totally correct and I am definitely a novice but think I have the latest libraries at least.
Thanks so much for any insight.
Thanks so much for any insight.
Code: Select all
// Libraries
#include <Adafruit_CC3000.h>
#include <ccspi.h>
#include <SPI.h>
#include <string.h>
#include "utility/debug.h"
#include "DHT.h"
#include <stdlib.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP085.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#include <avr/WDT.h>
#include <RTClib.h>
#include <utility/netapp.h>
// Define CC3000 chip pins
#define ADAFRUIT_CC3000_IRQ 3
#define ADAFRUIT_CC3000_VBAT 47
#define ADAFRUIT_CC3000_CS 53
#if defined(__SAM3X8E__)
#undef __FlashStringHelper::F(string_literal)
#define F(string_literal) string_literal
#endif
#define cs 46
#define dc 49
#define rst 48 // you can also connect this to the Arduino reset
Adafruit_ST7735 tft = Adafruit_ST7735(cs, dc, rst);
float p = 3.1415926;
// DHT sensor
DHT dht;
// Create CC3000 instances
Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT,
SPI_CLOCK_DIV2); // you can change this clock speed
// BH1750 instance
int BH1750address = 0x23;
byte buff[2];
// BMP085 instance
Adafruit_BMP085 bmp = Adafruit_BMP085(10085);
// WLAN parameters
#define WLAN_SSID "MY_SSID"
#define WLAN_PASS "MY_PASS"
// Security can be WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA or WLAN_SEC_WPA2
#define WLAN_SECURITY WLAN_SEC_WPA2
#define IDLE_TIMEOUT_MS 3000
// Xively parameters
#define WEBSITE "api.xively.com"
#define API_key "MY_XIVELY_API"
#define feedID "MY_FEED_KEY"
uint32_t ip;
void setup(void)
{
byte buff[2];
if (!cc3000.begin())
{
while(1);
}
dht.setup(2);
if(!bmp.begin())
{
while(1);
}
tft.initR(INITR_BLACKTAB); // initialize a ST7735S chip, black tab
tft.setRotation(0);
// Connect to WiFi network
cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY);
/* Wait for DHCP to complete */
while (!cc3000.checkDHCP())
{
delay(200);
}
}
void loop(void)
{
tft.invertDisplay(false);
sensors_event_t event;
bmp.getEvent(&event);
int i;
uint16_t val=0;
BH1750_Init(BH1750address);
if(2==BH1750_Read(BH1750address))
{
val=((buff[0]<<8)|buff[1])/1.2;
}
// Get data & transform to integers
float h = dht.getHumidity();
float t = dht.getTemperature();
float tempf = dht.toFahrenheit(t);
float lux = val;
float baro = event.pressure;
float soil = analogRead(15);
float tempc;
bmp.getTemperature(&tempc);
int temperature = (int) tempf;
int humidity = (int) h;
int light = (int) lux;
int barometer = (int) baro;
int temperaturec = (int) tempc;
int soilmoisture = (int) soil;
// Prepare JSON for Xively & get length
int length = 0;
String data = "";
data = data + "\n" + "{\"version\":\"1.0.0\",\"datastreams\" : [ {\"id\" : \"Temperature_F\",\"current_value\" : \"" + String(temperature) + "\"},"
+ "{\"id\" : \"Humidity\",\"current_value\" : \"" + String(humidity) + "\"},"
+ "{\"id\" : \"Barometer\",\"current_value\" : \"" + String(barometer) + "\"},"
+ "{\"id\" : \"TemperatureC\",\"current_value\" : \"" + String(temperaturec) + "\"},"
+ "{\"id\" : \"SoilMoisture\",\"current_value\" : \"" + String(soilmoisture) + "\"},"
+ "{\"id\" : \"Luminosity\",\"current_value\" : \"" + String(light) + "\"}]}";
length = data.length();
tft.fillScreen(ST7735_BLACK);
tft.setTextColor(ST7735_WHITE);
tft.setTextSize(2);
tft.setCursor(0, 0);
tft.print("TempF Humi");
tft.setCursor(0, 20);
tft.setTextSize(2);
tft.setTextColor(ST7735_GREEN);
tft.print(tempf, 1);//tft.print(char(247));
tft.setTextColor(ST7735_WHITE);
tft.setTextSize(1);
tft.setTextColor(ST7735_GREEN);
tft.setTextSize(2);
tft.print(" ");tft.print(h, 1);//tft.println("%");
tft.setTextColor(ST7735_WHITE);
tft.setCursor(0, 40);
tft.println("TempC Soil");
tft.setTextColor(ST7735_GREEN);
tft.setTextSize(2);
tft.setCursor(0, 60);
tft.print(tempc, 1);tft.print(" ");
if(analogRead(3)>800)
{
tft.setTextColor(ST7735_RED);
}
else
{
tft.setTextColor(ST7735_GREEN);
}
tft.println(analogRead(3));
tft.setTextSize(1);
tft.setCursor(0, 80);
tft.setTextColor(ST7735_WHITE);
tft.print("Luminosity: ");
tft.setTextColor(ST7735_YELLOW);tft.print(val, DEC);
tft.setTextColor(ST7735_WHITE);
tft.println(" LUX");
tft.setCursor(0, 92);
tft.setTextColor(ST7735_WHITE);
tft.print("Barometer: ");
tft.setTextColor(ST7735_BLUE);
tft.print(event.pressure);
tft.setTextColor(ST7735_WHITE);
tft.println("hPa");
tft.setCursor(0, 100);
unsigned long aucDHCP = 14400;
unsigned long aucARP = 3600;
unsigned long aucKeepalive = 10;
unsigned long aucInactivity = 20;
if (netapp_timeout_values(&aucDHCP, &aucARP, &aucKeepalive, &aucInactivity) != 0) {
tft.fillScreen(ST7735_BLACK);
tft.setCursor(0, 100);
tft.setTextSize(2);
tft.println("Error setting inactivity timeout!");
}
// Get the website IP & print it
ip = 0;
while (ip == 0) {
if (! cc3000.getHostByName(WEBSITE, &ip)) {
}
delay(500);
}
cc3000.printIPdotsRev(ip);
// Send request
{
Adafruit_CC3000_Client client = cc3000.connectTCP(ip, 80);
if (client.connected()) {
client.println("PUT /v2/feeds/" + String(feedID) + ".json HTTP/1.0");
client.println("Host: api.xively.com");
client.println("X-ApiKey: " + String(API_key));
client.println("Content-Length: " + String(length));
client.print("Connection: close");
client.println();
client.print(data);
client.println();
} else {
tft.setCursor(140, 0);
tft.print(F("Connection Failed"));
return;
}
unsigned long lastRead = millis();
while (client.connected() && (millis() - lastRead < IDLE_TIMEOUT_MS)) {
while (client.available()) {
char c = client.read();
lastRead = millis();
}
}
client.close();
delay(5000);
}
tft.fillScreen(ST7735_BLACK);
tft.setTextColor(ST7735_WHITE);
tft.setTextSize(2);
tft.setCursor(0, 0);
tft.print("TempF Humi");
tft.setCursor(0, 20);
tft.setTextSize(2);
tft.setTextColor(ST7735_GREEN);
tft.print(tempf, 1);//tft.print(char(247));
tft.setTextColor(ST7735_WHITE);
tft.setTextSize(1);
tft.setTextColor(ST7735_GREEN);
tft.setTextSize(2);
tft.print(" ");tft.print(h, 1);//tft.println("%");
tft.setTextColor(ST7735_WHITE);
tft.setCursor(0, 40);
tft.println("TempC Soil");
tft.setTextColor(ST7735_GREEN);
tft.setTextSize(2);
tft.setCursor(0, 60);
tft.print(tempc, 1);tft.print(" ");
if(analogRead(3)>800)
{
tft.setTextColor(ST7735_RED);
}
else
{
tft.setTextColor(ST7735_GREEN);
}
tft.println(analogRead(3));
tft.setTextSize(1);
tft.setCursor(0, 80);
tft.setTextColor(ST7735_WHITE);
tft.print("Luminosity: ");
tft.setTextColor(ST7735_YELLOW);tft.print(val, DEC);
tft.setTextColor(ST7735_WHITE);
tft.println(" LUX");
tft.setCursor(0, 92);
tft.setTextColor(ST7735_WHITE);
tft.print("Barometer: ");
tft.setTextColor(ST7735_BLUE);
tft.print(event.pressure);
tft.setTextColor(ST7735_WHITE);
tft.println("hPa");
tft.setCursor(0, 100);
// Wait 10 seconds until next update
delay(5000);
digitalWrite(44, LOW);
}
int BH1750_Read(int address) //
{
int i=0;
Wire.beginTransmission(address);
Wire.requestFrom(address, 2);
while(Wire.available()) //
{
buff[i] = Wire.read(); // receive one byte
i++;
}
Wire.endTransmission();
return i;
}
void BH1750_Init(int address)
{
Wire.beginTransmission(address);
Wire.write(0x10);//1lx resolution 120ms
Wire.endTransmission();
}
- tdicola
- Posts: 1074
- Joined: Thu Oct 17, 2013 9:11 pm
Re: [Solved] CC3000 Hang
Thanks for posting the full code. Hrm, nothing immediately jumps out as an issue. If you add some Serial.println calls to output debug info like "Read sensor data", "Sent message to Xively", "Updated display", etc. at the appropriate spots, can you pinpoint where it might be getting hung up?
Please be positive and constructive with your questions and comments.