Arduino locking up in Tank Level/Pumping/Logging project

My Arduino is freezing/locking up, sometimes after running for a few hours, sometimes quickly (under a minute). The quick lockups seem to always occur following a reboot from a previous lockup. The freezing will prevent it from making any further readings and decisions and inputs will not function.

The project:
I am using an Arduino Uno with Ethernet Shield to monitor the water levels in two 150 gallon tanks using ultrasonic sensors to determine which one has enough water to pump out and be used. One of the tanks will be hooked up to City water in the end result so I really only check to make sure the other one does not get empty.

Potential Freezing Issues I am researching:

  • I thought I might be running out of SRAM due to all of the variables and especially the char arrays. I was about to convert everything to PROGMEM but then I found a quick snippet to display free memory and turns out I am only using about 800 bytes of the 2000 so that should be ok.

  • I also looked into string concatenation errors but I am not using the String library, sticking to char arrays and strcat().

  • Some people have Magnetism issues from relays but ours are fairly far away from the board so not sure if that is the issue, also there is no correlation to when lockups happen and the relays are being used.

  • This Arduino has been uploaded to and reset a LOT over the past two weeks, is there any residual effect on the Flash memory from this that could be causing lockups? We are getting another board this week so that will rule this out as a possibiliy

  • Ethernet Shield freezing? http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1248929726/all. I am not sure it is just the shield.

Any help on this would be appreciated!

Anything that causes lockups would be a great help, this is my first real micro-controller and C project (I have a Python and web development background) so I am unfamiliar with a lot of the usual hangups.

Here is a link to the code (I blanked out the urls it is posting to and anything else identifiable):

I am not sure whether this matters, but I notice that you don't ever read anything from the ethernet client. I wonder what the library does when the buffer is full. It's a longshot, but you might consider reading what it has received, even if you just throw it away.

wildbill:
I am not sure whether this matters, but I notice that you don't ever read anything from the ethernet client. I wonder what the library does when the buffer is full. It's a longshot, but you might consider reading what it has received, even if you just throw it away.

Thank you for pointing this out! I have overlooked it, it probably does matter.

I will try out using client.flush() every time I make a request, just to keep it clear.

I will try out using client.flush() every time I make a request, just to keep it clear.

I'd think it important, at least at the beginning to do more than just ignore what the server has to say. Perhaps there is a clue-by-four waiting to whack you, if only you'd read what the server has to say.

I ran the logging system over with with client.flush(); being called every 15 minutes and it froze after around 8 hours.

In this forum, http://forum.freetronics.com/viewtopic.php?f=4&t=176&start=30 , Sleurhutje has client.flush() BEFORE client.stop() so I am going to try that next. I do not know if order is important.

He also goes on to say to never use flush even though he has it in his code.

Has anyone had success using Flush over long periods of time? Or have any other ideas?

Another thing you might try is to use wireshark and see what packet traffic there was on your network at the time of the crash. I have had trouble in the past with large broadcast packets that my wifi shield's library couldn't handle.

I will definitely play around with wireshark.

If large packets are detected is there any way to reject them with code?

Yes, but in that particular instance, it needed a change to the library.

Did you find the problem?

I am encountering with the same problems.

My problem appears to have gone away, my network logger has been running for over a day now.

I did two things:

  1. I put it on a brand new Arduino + Ethernet Shield

  2. In my networking function I moved client.flush() to be BEFORE client.stop(), with a slight delay involved, like this:

  client.flush();
  delay(10);
  client.stop();

I previously had flush after stop, and before that I didn't have flush at all.

i know this isn't the most conclusive end result and it has only been logging for a day so if anything happens or I discover something more conclusive I will post it here.

Thank you, especially wildbill, for your ideas on this!

I will try this. thanks.

would you mind posting your whole function that handles with the http?

Here is all of my network code:

#include <Ethernet.h>

byte mac[] = { mac };
const char serverName[22] = "subdomain.domain.com";

EthernetClient client;

void logData(char* n, char* d, int tank1, int tank2, int fhz){  //name, desc, tank1 level, tank2 level
  if (client.connect(serverName, 80)){
  char bigstring[128];
  char buffer[12];
  bigstring[0] = 0;
  strcat(bigstring, "GET /logger?t=");
  strcat(bigstring, n);
  strcat(bigstring, "&d=");
  strcat(bigstring, d);
  strcat(bigstring, "&t1=");
  strcat(bigstring, itoa(tank1, buffer, 10));
  strcat(bigstring, "&t2=");
  strcat(bigstring, itoa(tank2, buffer, 10));
  strcat(bigstring, "&fl=");
  strcat(bigstring, itoa(fhz, buffer, 10));
  strcat(bigstring, "&fr=");
  strcat(bigstring, itoa(freeRam(), buffer, 10));
  strcat(bigstring, "&loc=");
  strcat(bigstring, itoa(clientLocationID, buffer, 10));
  strcat(bigstring, " HTTP/1.1");
  
  Serial.println(bigstring);
  client.println(bigstring);
  client.println("Host:subdomain.domain.com");
  client.println();
  client.flush();
  delay(10);
  client.stop();
  }
  else{
    Serial.println("failed");
  }
}

void setup(){
  Serial.begin(9600); 
  
  if (Ethernet.begin(mac) == 0) {
    Serial.print("failed");
    // no point in carrying on, so do nothing forevermore:
    while(true);
  }
  // give the Ethernet shield a second to initialize:
  delay(1000);
  
  logData("Boot", "", 0, 0, 0);
}

To log a value whenever an "event" occurs I just call logData(), for example:

logData("Pumping", "Update", getRecycledPercent(), getCityPercent(), getFlowHz());