WiFly / Code stalls after a few sends

I'm sending temperature information from my Arduino via the WiFly shield to a Google Spreadsheets like in this tutorial:
http://www.s2ptech.com/2012/04/send-data-from-arduino-to-google-docs.html#.T80OE45DuS1

The problem is that after a few sends the actions simply stalls. Resetting helps but again after a few send actions (4-8) it stalls again. The LED at P104 blinks green.

The code are as follows:

#include "WiFly.h"
#include "Credentials.h"

char formkey[]="dHF2eFlCQjhYbnFmRjNLQWlnN29fUlE6MQ"; //Key for google spreadsheet
byte server[]={ 209,85,229,101}; //Google IP

Client client(server, 80);

//Server server(80);

//Store values for temp
int temp_in_kelvin;
int celsius;

void setup() {
  WiFly.begin();

  if (!WiFly.join(ssid, passphrase)) {
    while (1) {
      // Hang on failure.
    }
  }

  Serial.begin(9600);
  Serial.print("IP: ");
  Serial.println(WiFly.ip());
  
}

void loop() {
  
  //reads the input and converts it to Kelvin degrees
  temp_in_kelvin = analogRead(1) * 0.004882812 * 100;
  
  //Converts Kelvin to Celsius minus 2.5 degrees error
  celsius = temp_in_kelvin - 2.5 - 273.15;
  
  String data;
  data+="";
  data+="entry.0.single=";
  data+= celsius;
  data+="&submit=Submit";
  
  if (client.connect()) {
    Serial.println("connected");


    client.print("POST /formResponse?formkey=");
    client.print(formkey);
    client.println("&ifq HTTP/1.1");
    client.println("Host: spreadsheets.google.com");
    client.println("Content-Type: application/x-www-form-urlencoded");
    client.println("Connection: close");
    client.print("Content-Length: ");
    client.println(data.length());
    client.println();
    client.print(data);
    client.println();


    Serial.print("POST /formResponse?formkey=");
    Serial.print(formkey);
    Serial.println("&ifq HTTP/1.1");
    Serial.println("Host: spreadsheets.google.com");
    Serial.println("Content-Type: application/x-www-form-urlencoded");
    Serial.println("Connection: close");
    Serial.print("Content-Length: ");
    Serial.println(data.length());
    Serial.println();
    Serial.print(data);
    Serial.println();


  }
  delay(1000);
  if (!client.connected()) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();
  }
  //Serial.print("Temp: ");
  //Serial.println(celsius);
  Serial.flush();
  delay(10000);
}

Any ideas what might be wrong?

I would try adding:

client.stop();
delay(1000);

at the end of your if(client.connect()){..}, this severs the connection after you are done and allows a new one to start the next time through your loop.

-Wg

I just tried that fix. Didn't help.

The error is pretty consistent now. It sends 4 temp readings to the spreadsheet before stalling.

The last serial print reads:

connected
POST /formResponse?formkey=dHF2eFlCQjhYbnFmRjNLQWlnN29fUlE6MQ&ifq HTTP/1.1
Host: spreadsheets.google.com
Content-Type: application/x-www-form-urlencoded
Connection: close
Content-Length: 31
*try.0.sin
Connection: close
disconnecting.

And it's the same every time. I think the *try.0.sin is somehow key. Normally that line would be:

entry.0.single=24&submit=Submit

Don't use the String class, your memory gets clobbered by using this class. Also you have a lot of strings in your code. Try to use the F() macro everywhere you supply a string constant to a Stream class object (client and Serial). This conserves some memory too by getting the strings directly from the flash.

I tried changing the code to this:

#include "WiFly.h"
#include "Credentials.h"

char formkey[]="dHF2eFlCQjhYbnFmRjNLQWlnN29fUlE6MQ"; //Key for google spreadsheet
byte server[]={ 209,85,229,101}; //Google IP

Client client(server, 80);

//Server server(80);

//Store values for temp
int temp_in_kelvin;
int celsius;

void setup() {
  WiFly.begin();

  if (!WiFly.join(ssid, passphrase)) {
    while (1) {
      // Hang on failure.
    }
  }

  Serial.begin(9600);
  Serial.print("IP: ");
  Serial.println(WiFly.ip());
  
}

void loop() {
  
  //reads the input and converts it to Kelvin degrees
  temp_in_kelvin = analogRead(1) * 0.004882812 * 100;
  
  //Converts Kelvin to Celsius minus 2.5 degrees error
  celsius = temp_in_kelvin - 2.5 - 273.15;
  
  String data;
  data+="";
  data+="entry.0.single=";
  data+= celsius;
  data+="&submit=Submit";
  
  if (client.connect()) {
    Serial.println(F("connected"));


    client.print(F("POST /formResponse?formkey="));
    client.print(formkey);
    client.println(F("&ifq HTTP/1.1"));
    client.println(F("Host: spreadsheets.google.com"));
    client.println(F("Content-Type: application/x-www-form-urlencoded"));
    client.println(F("Connection: close"));
    client.print(F("Content-Length: "));
    client.println(data.length());
    client.println();
    client.print(data);
    client.println();

    
    Serial.print(F("POST /formResponse?formkey="));
    Serial.print(formkey);
    Serial.println(F("&ifq HTTP/1.1"));
    Serial.println(F("Host: spreadsheets.google.com"));
    Serial.println(F("Content-Type: application/x-www-form-urlencoded"));
    Serial.println(F("Connection: close"));
    Serial.print(F("Content-Length: "));
    Serial.println(data.length());
    Serial.println();
    Serial.print(data);
    Serial.println();
    
    client.stop();
    delay(1000);
    
  }
  delay(1000);
  if (!client.connected()) {
    Serial.println();
    Serial.println(F("disconnecting."));
    client.stop();
  }
  //Serial.print("Temp: ");
  //Serial.println(celsius);
  Serial.flush();
  delay(10000);
}

Now it switches between 2 to 9 sends before stalling. Did I do the F() part wrong?

No, but you're still using the String class.

What do you mean by "stalling"? Does it restart or just freezing? An out of memory situation usually results in a reset and not a freezing. If it's freezing I would search in the WiFly library. There are lots of situations it waits forever if the return value is not what it expects. I patched my version to include timeouts for every routine. With the patched version I have an uptime of weeks and no freeze (till now :slight_smile: ).

It freezes.

Will try and look at the library. Any tips/clues? Not very experienced in hacking the libraries :slight_smile:

I started by inserting lots of Serial.print()s in my code to locate the problematic parts. Then I went into the library and replaced all dead loops with versions with timeouts. If you're interested, I can post my version of the library but be prepared to change your code as I changed the API.

I had a friend come by today and he tried to help me fix the library. Didn't work.

Can I get yours? To see the differences.

I put it on my Arduino page:

http://www.linotux.ch/arduino/

I haven't had the time to make example code, so you have to study the code to get the idea how to use it, although it's not that much of a difference to the original WiFly code, just more possibilities to set timeouts.