HTTP Connection

Hi all.
I am using the following code to send data on my Heroku app. Everything is connected and works fine most of the times, however, there are times that the connection freezes right after the message "connected". Does anyone have an idea why it freezes and doesn't proceed to send the data to the app or why the connection stays open?
Is there a way to overcome this issue?

if (client.connect(serverName, 80)) { //starts client connection, checks for connection
Serial.println("connected");
client.println(postData);
<<<

#include <SPI.h>
#include <Ethernet.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

char serverName[] = "application.herokuapp.com";
EthernetClient client;

long soundSensor;
String data = "GET /api/device/deviceName/sensor/sensorName/report?value=";

void setup(){
  Serial.begin(9600); 
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    while(true);
  }
}

void loop(){
  sendGET();
  delay(12000);
} 

//////////////////////////

void sendGET() //client function to send/receive GET request data.
{
  soundSensor = random(0,50);
  String postData = data + soundSensor + " "+"HTTP/1.1";
  
  if (client.connect(serverName, 80)) {  //starts client connection, checks for connection
    Serial.println("connected");
    client.println(postData);
    client.println("Host: application.herokuapp.com");
    client.println("Connection: close");  //close 1.1 persistent connection  
    client.println(); //end of get request
  } 
  else {
    Serial.println("connection failed"); //error message if no client connect
    Serial.println();
  }

  while(client.connected() && !client.available()) delay(1); //waits for data
  while (client.connected() || client.available()) { //connected or data available
    char c = client.read(); //gets byte from ethernet buffer
    Serial.print(c); //prints byte to serial monitor 
  }

  Serial.println();
  Serial.println("disconnecting.");
  Serial.println("==================");
  Serial.println();
  client.stop(); //stop client
}

If you use a domain name for the serverName in the connect function call, the success return value is 1. There are other non-zero values returned that are a fail indication that have to do with the resolution of the domain name. Try changing to this:

  if (client.connect(serverName, 80) == 1) {  //starts client connection, checks for connection

I'm not saying that is the only problem you are having, but it could be one of them.

Cheers for the tip!
However, it didn't do the trick! Something further that I could try?
Thanks again

Is the last message on the serial monitor "connected"? If it is, then you may have a stalled server or failed connection. The fix is a timeout to close the connection from the client end if these fails happen. Here is my example sketch in the playground that has the timeout feature:
http://playground.arduino.cc/Code/WebClient

Here is the response read with the timeout code from that example:

// connectLoop controls the hardware fail timeout
  int connectLoop = 0;

  while(client.connected())
  {
    while(client.available())
    {
      char inChar = client.read();
      Serial.write(inChar);
      // set connectLoop to zero if a packet arrives
      connectLoop = 0;
    }

    connectLoop++;

    // if more than 10000 milliseconds since the last packet
    if(connectLoop > 10000)
    {
      // then close the connection from this end.
      Serial.println();
      Serial.println(F("Timeout"));
      client.stop();
    }
    // this is a delay for the connectLoop timing
    delay(1);
  }

  Serial.println();

  Serial.println(F("disconnecting."));
  // close client end
  client.stop();

I tried your suggestion, and it looks a bit better now, thanks for the tip :wink:
I don't know if this is the best way though, I was also thinking to use another protocol, perhaps MQQT. Looks a bit better...

If you are looking for speed, think about using UDP. That is what I use. It requires a bit of programming to insure the receiver is getting the packet (receiver sends a response to the sender), but I found it simpler than trying to maintain a connection.

Hi,

On the topic of using UDP for speed, I am building a novel data acquisition system for a school project. I want to develop a server on the Arduino that will send data to another server on the PC every 10 seconds. My sensors update global variables continually on the Arduino and then every 10seconds I want to quickly open a server connection send the latest values of my variables in a struct (+- 20 bytes), close the connection and continue polling from the sensors. I was hoping the process could take less than 100ms. I have not found latency examples for such connections, but I was thinking using UDP might increase my chances of achieving such requirements.

Would anyone agree?
Is 100ms unrealistic? (It is basically to ensure readings from sensors are not lost)
If UDP is the way to go, can anyone maybe provide an example of checking for successful data transfers?
I have not attempted to start building because it will take me a very long time since I am quite inexperienced, and I would like to get the architecture right.

any advice would be appreciated.

*edit
Why I want the sensor polling and client listening functions separate is to ensure if the server goes down I am still logging data and can save on the SD card what I need to.
ps. I wonder when the first asynchronous processing capable Arduino will be released.

100ms is no problem for me, but this is on a localnet with very light traffic.

The UdPNtpClient is a good example of a UDP client. Sends a request packet and gets a response packet from a NTP "server".

I used TCP initially, but it was more time consuming establishing and maintaining the connection.

Just my opinion...

Great thank you,

I am definitely hosting on a localnet with light traffic. And I also know I can send the data at once as a packet. I will post results when I have achieved something.

I would use MQTT instead of UDP, because with UDP you have to implement all the handshaking (= ensuring successful transmission) and other protocol/non-data stuff yourself. With MQTT you can simply use higher QOS-Flags and concentragte on the data aquisition. An Example - with low QOS-Flags - you'll find on the blog of my company: Noser Blog Lightweight Network Communication - Noser Blog

(if you have questions concerning the Blog post - write them in here, as I am the author of that blog post.)

Best

riesens