5
votes

I'm using an Arduino Uno with Ethernet Shield.

After sending many HTTP requests, client.println(...), the client starts to fail when connecting. The time to failure appears to be random, and the sequence readout from the loop can vary anywhere between ~1000 and ~7000.

The error is not to do with the Ethernet Transmit Buffer overflowing (Following this advice)

Here is the code that is failing:

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

// Network constants
byte mac[] = {0x00, 0x23, 0xdf, 0x82, 0xd4, 0x01};
byte ip[] = {/*REDACTED*/};
byte server[] = {/*REDACTED*/};
int port = /*REDACTED*/;
Client client(server, port);

// State
int sequence;

void setup(){
    Ethernet.begin(mac, ip);
    Serial.begin(9600);
    sequence = 0;

    delay(1000);
}

void loop(){
    httpPut("/topic/:test/publish?sessionId=SESenanhygrp");
    Serial.println(sequence++);
}

void httpPut(char* url){
    if (!client.connect()) {
        Serial.println("EXCEPTION: during HTTP PUT. Could not connect");
        return;
    }

    client.print("PUT");
    client.print(" ");
    client.print(url);
    client.println(" HTTP/1.0");
    client.println();

    while(!client.available()){
        delay(1);
    }

    while(client.available()) {
        char c = client.read();
        Serial.print(c);
    }

    while(client.connected()){
        Serial.println("Waiting for server to disconnect");
    }

    client.stop();
}

The error occurs in the following segment

if (!client.connect()) {
    Serial.println("EXCEPTION: during HTTP PUT. Could not connect");
    return;
}
2
At the point when the client is failing to connect, I'd do two things: (1) check the server logs for any evidence of the server receiving the failing connection requests; (2) use netstat on the server to establish whether previous connections have been closed or are lingering.NPE
In addition to above, 3) I would check if the stack is overflowing. 4) Is there is a memory leak that occurs after thousands of cycles.Jeff
The server logs did not indicate any problems. Memory is always a problem when using Arduinos, but the above code should be quite 'memory safe'ChrisSSocha
How did you download the library from tinker?Francesco Boi

2 Answers

1
votes

There is a bug in the Arduino Ethernet library in v22 (as discussed in Linux/Windows V0022/1.0 Ethernet problem SOLVED).

The solution for me was to use the Ethernet2 library (by Peter from tinker.it). The code needed minor tinkering, but everything appears to be working fine now. I've managed to get over 40000+ HTTP messages sent without any problems. (Occasionally single messages cannot be sent, but this error rate is less than 4%.)

0
votes

I would slow down the communication rate by increasing time 10x between the messages. Then if you don't get an error between 1000 and 7000 messages, it would probably mean that you are talking too fast to your little Arduino and it's buffer gets an overflow which communication library unfortunately can not recover from. I would also monitor Arduino free bytes in a buffer over serial port after each message. You can also test for this behavior by sending messages as fast as you can from PC, and see if that will freeze your Arduino after a while. If it does, you might consider to deny messages until buffer is above some limit.