Wifi Weather Station Keeps Freezing, even w/ Watchdog

I have been running a Wifi Weather Station (temp and hum posted to server over wifi) for a few months. I had an issue with the watchdog under the stock bootloader, so I burned Optiboot on the board (Pro Mini), and it worked for 3 weeks, then froze. I reset it, and it froze in a few days. Then I reset it and it froze in a week and a half.

I don’t understand how this can happen as long as the watchdog is there. I don’t know where to begin to troubleshoot. I’ll post the full code below, which is taken from SparkFun’s library.

I set the watchdog to 8 seconds. Then I created a subroutine called ‘dogDelay’ which resets the watchdog every second of the delay.

The problem is that it takes so long to fail that I can’t realistically reproduce the error. This is a standalone project, so I can’t used Serial.prints to troubleshoot.

Thanks in advance for any help.

// SPI and the pair of SFE_CC3000 include statements are required
// for using the CC300 shield as a client device.
#include <SPI.h>
#include <SFE_CC3000.h>
#include <SFE_CC3000_Client.h>
// Progmem allows us to store big strings in flash using F().
// We'll sacrifice some flash for extra DRAM space.
#include <Progmem.h>
#include "DHT.h"
#include <avr/wdt.h>

////////////////////////////////////
// CC3000 Shield Pins & Variables //
////////////////////////////////////
// Don't change these unless you're using a breakout board.
#define CC3000_INT      3   // Needs to be an interrupt pin (D2/D3)
#define CC3000_EN       5   // Can be any digital pin
#define CC3000_CS       10  // Preferred is pin 10 on Uno
#define IP_ADDR_LEN     4   // Length of IP address in bytes

////////////////////
// WiFi Constants //
////////////////////
char ap_ssid[] = "SSID";                // SSID of network
char ap_password[] = "password";        // Password of network
unsigned int ap_security = WLAN_SEC_WPA2; // Security of network
// ap_security can be any of: WLAN_SEC_UNSEC, WLAN_SEC_WEP, 
//  WLAN_SEC_WPA, or WLAN_SEC_WPA2
unsigned int timeout = 30000;             // Milliseconds
char server[] = "www.server.com";      // Remote host site

// Initialize the CC3000 objects (shield and client):
SFE_CC3000 wifi = SFE_CC3000(CC3000_INT, CC3000_EN, CC3000_CS);
SFE_CC3000_Client client = SFE_CC3000_Client(wifi);


//////////////////////
// Input Pins, Misc //
//////////////////////
#define LED A1
#define SIGNALPIN A3
#define DHTPIN 7 
#define DHTTYPE DHT22

// DHT instance
DHT dht(DHTPIN, DHTTYPE);

void setup()
{
  Serial.begin(115200);

  // Setup Input Pins:
  pinMode(LED, OUTPUT);
  digitalWrite(LED, LOW);
  pinMode(SIGNALPIN, OUTPUT);
  digitalWrite(SIGNALPIN, LOW);
  dht.begin();

  // Set Up WiFi:
  setupWiFi();
  wdt_enable(WDTO_8S);
  wdt_reset();
}

void loop()
{
  // Make a TCP connection to remote host
  if ( !client.connect("www.server.com", 80) )
  {
    // Error: 4 - Could not make a TCP connection
    Serial.println(F("Error: 4"));
  }
  wdt_reset();
  float hum = dht.readHumidity();
  float tempC = dht.readTemperature();  
  // now convert to Fahrenheit
  float tempF = (tempC * 9.0 / 5.0) + 32.0;
  Serial.print(tempF); Serial.println(" degrees F");
  Serial.println(hum);
  char ctempF[7];
  char chum[7];
  dtostrf(tempF, 3, 1, ctempF);
  dtostrf(hum, 3, 1, chum);
  String stempF = String(ctempF);
  String shum = String(chum);
  String data = "temp=" + stempF + "&hum=" + shum;
  Serial.println(data);
//  data = "temp=71.1&bright=289"; // just testing
  if (client.connect("www.server.com", 80) == 1) { 
      Serial.println("Connected");
      client.println("POST /server/data/add.php HTTP/1.1"); 
      client.println("Host: www.server.com"); // SERVER ADDRESS HERE TOO
      client.println("Content-Type: application/x-www-form-urlencoded"); 
      client.print("Content-Length: "); 
      client.println(data.length()); 
      client.println(); 
      client.print(data);
      client.println("Connection: close");
      client.println(); 
    } 
  else {
    Serial.println("Connection failed.");
  }
  wdt_reset();
  while(client.connected()) {
  while(client.available()) {
    char ch = client.read();
    Serial.write(ch);
  }
}
//  if (client.connected()) { 
      client.stop();	// DISCONNECT FROM THE SERVER
//	}
  digitalWrite(LED, HIGH);
  dogDelay(2);
  digitalWrite(LED, LOW);
  blinkDelay(300); // WAIT BEFORE SENDING AGAIN  
}

void setupWiFi()
{
  ConnectionInfo connection_info;
  int i;

  // Initialize CC3000 (configure SPI communications)
  if ( wifi.init() )
  {
    Serial.println(F("CC3000 Ready!"));
  }
  else
  {
    // Error: 0 - Something went wrong during CC3000 init!
    Serial.println(F("Error: 0"));
  }

  // Connect using DHCP
  Serial.print(F("Connecting to: "));
  Serial.println(ap_ssid);
  if(!wifi.connect(ap_ssid, ap_security, ap_password, timeout))
  {
    // Error: 1 - Could not connect to AP
    Serial.println(F("Error: 1"));
  }

  // Gather connection details and print IP address
  if ( !wifi.getConnectionInfo(connection_info) ) 
  {
    // Error: 2 - Could not obtain connection details
    Serial.println(F("Error: 2"));
  }
  else
  {
    Serial.print(F("My IP: "));
    for (i = 0; i < IP_ADDR_LEN; i++)
    {
      Serial.print(connection_info.ip_address[i]);
      if ( i < IP_ADDR_LEN - 1 )
      {
        Serial.print(".");
      }
    }
    Serial.println();
  }
}

void dogDelay(int delaySecs) {
	for ( int i = 0; i < delaySecs; i++) {
		wdt_reset();
		delay(1000);
	}
	wdt_reset();
}

void blinkDelay(int totSec) {
  int intervals = totSec / 10;
  for (int i = 0; i < intervals; i++) {
    digitalWrite(SIGNALPIN, HIGH);
    dogDelay(1);
    digitalWrite(SIGNALPIN, LOW);
    dogDelay(9);
  }
}

Hi pekasus

You connect to the server at the start of loop():

  if ( !client.connect("www.server.com", 80) )
  {
    // Error: 4 - Could not make a TCP connection
    Serial.println(F("Error: 4"));
  }

Later, you connect again without disconnecting first:

  if (client.connect("www.server.com", 80) == 1) {

Could that be causing a memory leak?

Also, later in loop() ...

  while (client.connected()) {
    while (client.available()) {
      char ch = client.read();
      Serial.write(ch);
    }
  }

When will the outer while loop end? Does the server force a disconnect?

Regards

Ray

Thanks, Ray.

I will remove the first

if ( !client.connect("www.server.com", 80) )

as I think that is just leftover from when I was testing the code. I don't see any purpose for it now that I don't have a serial connection.

As for the while (client.connected())
I added that bc the arduino was disconnecting before it had a chance to send the data to the server. I hope this isn't a problem bc then I'll have to figure out how to keep the connection open long enough to send the data.

I'll run this and see how it works.

Thanks for your help.

Also, later in loop() ...

  while (client.connected()) {

while (client.available()) {
      char ch = client.read();
      Serial.write(ch);
    }
  }




When will the outer while loop end? Does the server force a disconnect?

Yes. When it is finished sending packets, it will close the connection from its end, then you close the connection on your end.

This is "Perfect World" code with comments and the correct disconnect. It has no timeout to prevent an endless loop if the connection breaks or the server stalls.

  // while server is still sending packets
  while (client.connected()) {
    // get the next packet
    while (client.available()) {
      char ch = client.read();
      Serial.write(ch);
    }
  }
  // now close the client end
  client.stop();
  Serial.println("\r\nDisconnected");

Surfer Tim: I am using a watchdog, so if it gets stuck in the while loop for more than 8 seconds, the system should reboot, so it shouldn't be able to get stuck.

Do you think opening the connection twice (as was pointed out) could be the cause of the eventual hang?

I also enabled the watchdog so that it begins before setupWiFi();. I think this could be causing it to hang outside of the the watchdog's protection.

Now the watchdog starts before the setup wifi call, so everything is under the watchdog protection, and it still froze.

I am using the optiboot bootloader, so it shouldn't be in an endless reset loop.

What else could be the problem? Even if the network is causing an issue, it should still timeout and reset.