Ethernet sheild freezes after random period of time

Hi! I am having problem with my ethernet shield. Below is the program, I am running.

#include <Ethernet.h>
#include <SPI.h>
#include <SoftwareSerial.h>
SoftwareSerial Zigbee(2,3); // RX, TX
byte schoolIP;
String store_data = "";
char sdata;
boolean mainloop_receive = true;
boolean subloop_receive = true;
char rdata;
String received_data = "";

byte mac[] = {0x90, 0xA2, 0xDA, 0x0D, 0xEB, 0x61}; //mac address of ethernet shield

IPAddress ip(192,168,0,103); //set static ip address

EthernetServer server(8052); //set at port 8051

void setup()
{
  digitalWrite(resetPin, HIGH);
  pinMode(resetPin, OUTPUT);
  Serial.begin(9600); // Open serial communications and wait for port to open:
  while(!Serial)
  {
    ; //wait for serial port to connect.
  }
  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  Serial.print("Server is at ");
  Serial.println(Ethernet.localIP());
  Zigbee.begin(19200); //set pin 2,3 at baud rate of 19200
  server.begin();
}

void loop()
{
  EthernetClient client = server.available();
  if(client)
  {
    while (client.connected())
    {
      sdata = client.read();  //sdata read data
      store_data += sdata;    //store data
      if (sdata == '\n')      //check for next line
      {
        if(store_data == "\n")//check for next line
        {
          while(mainloop_receive) //loop for receiving data
          {
          if(subloop_receive)  //print only once when receiving data
            {
             Serial.println("AT+SCAST, ");
             Zigbee.println("AT+SCAST, ");    //send space to Zigbee
             subloop_receive = !subloop_receive; //set to false
            }
            else
            {
             while(Zigbee.available())
             {
             rdata =(char)Zigbee.read(); //rdata read data from Zigbee
             received_data += rdata;     //store rdata
             if (rdata == '\n')          //check for next line
             { 
             if(received_data.substring(25,26) == "=")
             //if this line is not included, the program will print additional data
             {
             int rdata1 = received_data.indexOf('=');    //locate equal sign
             int rdata2 = received_data.lastIndexOf('\n');   //locate next line
            [u] Serial.println(received_data.substring(rdata1+1, rdata2));
             //Serial print data in between equal and next line
             client.print(received_data.substring(rdata1+1, rdata2));[/u]
             mainloop_receive = !mainloop_receive; //stop while loop
             }
             received_data = ""; //clear received_data
             }
             }
            }
          }
        }
        else
        {
        Serial.print(store_data); //print out store_data
        Zigbee.print("AT+SCAST,");
        Zigbee.println(store_data); //send store_data to Zigbee
        }
      }
    }
  }
  delay(1); //give time for client to receive data
  client.stop(); //stop client
  mainloop_receive = true;
  subloop_receive = true;
  store_data = ""; //clear store_data
}

When the program runs for a certain period, the program will hang at the part which I have highlighted.
Do anyone knows which part went wrong?

I am unable to Serial.print and client.print the underline part. I'm not sure what went wrong.

Please enclose your code in [ code ] [ /code ] tags. You can go back and edit your post to add them.

String store_data = "";
String received_data = "";

The String class is well-known for memory fragmentation which tends to lead to a mysterious crash. Recommend you use only C strings for reliability.

What is the longest string you ever expect to receive over ethernet, and what's the longest you ever expect to receive from Zigbee?

The String class is well-known for memory fragmentation which tends to lead to a mysterious crash.

So how does that cause fragmentation? Can you explain your "well-known" assumption?

zoomkat:

The String class is well-known for memory fragmentation which tends to lead to a mysterious crash.

So how does that cause fragmentation? Can you explain your "well-known" assumption?

http://forum.arduino.cc/index.php?topic=109867.0

AWOL:
The per-string overhead of using the String class is only seven or eight bytes per instance; the danger in using it lies in potential memory fragmentation after multiple String operations.

http://forum.arduino.cc/index.php?topic=74546.0

dc42:
Personally, I'd avoid using String because of the variable memory usage and memory fragmentation that it causes

http://forum.arduino.cc/index.php?topic=179360.0

PaulS:
Why are you using Strings? Strings consume a lot of resources and fragment the limited memory that you have.

http://forum.arduino.cc/index.php?topic=176028.0

PeterH:
On versions up to 1.0.4 the String class also exposed a bug in the Arduino's heap management code which caused memory corruption; this is fixed in later versions but the String class still exposes the risk of memory fragmentation. The String class is simply not a good idea in an Arduino environment and I suggest you forget it exists

tylernt , most of your quotes are pre 1.0.5 issues concerning failure to free used memory space. The rest are just idle speculation. Do you believe that finding fossil sea shells in mountainous areas is proof positive of the "great flood"?

zoomkat:
tylernt , most of your quotes are pre 1.0.5 issues concerning failure to free used memory space.

I am not referring to the IDE's heap bug in pre-1.0.5. I'm referring to the fragmentation that still occurs with String post-1.0.4. Nick Gammon's page is from Tue 13 Aug 2013 -- IDE 1.0.5 was released in May. PeterH's post is from July 07, 2013 and quite clearly calls out the fragmentation problem that still remains post-1.0.4.

The rest are just idle speculation.

Okay. Would you care to speculate on why yougotodie's sketch runs for a while and then hangs?

Do you believe that finding fossil sea shells in mountainous areas is proof positive of the "great flood"?

There's no need for personal attacks.

Okay. Would you care to speculate on why yougotodie's sketch runs for a while and then hangs?

Could be bad code. I think one can have memory issues using Strings or c-strings. I follow the suspect String issues, and for the most part, corrections in coding and prudent use of memory allocation appear to fix the problems.

There's no need for personal attacks.

Not a personal attack, just curious how you come to your technical conclusions. I personally challenge what often appears to me to just be repeated dogma which may no longer have a basis in fact.

I personally challenge what often appears to me to just be repeated dogma which may no longer have a basis in fact.

I have no religious objections to the String class; I understand it can be used safely and successfully for certain use cases. However in this particular case yougotodie is repeatedly concatenating characters, which Nick points out is dangerous.

By the way, I also noticed this on Nick's page:

This example fragmented memory (one block). However since the string class (as opposed to the String class) allocates memory in larger chunks the fragmentation should be more controlled. That is there would not be (or should not be) lots of tiny fragments of memory used. You can reduce this fragmentation by using the "reserve" function.

If the stock String library had this 'reserve' feature, I'd have no problem recommending newbies use String as long as they also use the 'reserve' feature appropriately: the String class is quite a bit more friendly than C strings.

Code that generates large c-strings or Strings will eventually have identical problems. Trying to combine "asdfgh" and "123456" into buff[6] may cause code to fail when buff is actually used. My best guess is that the String functions are just convenient shell operations performing the typical c-string operations.

zoomkat:
Trying to combine "asdfgh" and "123456" into buff[6] may cause code to fail when buff is actually used.

Well sure, you can break any otherwise good feature by using it wrong. :wink:

My best guess is that the String functions are just convenient shell operations performing the typical c-string operations.

I don't know the internal workings of the String class, but I do know my objection to it is based on dynamic memory reallocation, which is problematic in general on AVRs, completely aside from Strings. Yes, you can get around the issues by always releasing dynamic memory in reverse order of allocation, but requires you to know what you're doing and that defeats the major advantage String: making things easy for newbies.

A String-like wrapper for C strings that does not include dynamic memory reallocation would be cool. For example, I find

store_data += sdata; //store data

to be much "nicer" than calling strcat(). If store_data was scoped just like any other variable, and refused to allow you to += beyond the end (or started "wrapping" or bumping characters off the front like a FIFO ringbuffer), that would be awesome.

Hi people, thanks for your responses. My problem sounds exactly the same as this guy. The program will just run for certain period and freezes at this part.

int rdata1 = received_data.indexOf('='); //locate equal sign
int rdata2 = received_data.lastIndexOf('\n'); //locate next line
Serial.println(received_data.substring(rdata1+1, rdata2));
//Serial print data in between equal and next line
client.print(received_data.substring(rdata1+1, rdata2));

If I put Serial.println(received_data); before those lines, I can manage to see my data there. The problem started after a random period and after filtering. The data seems to be empty when I Serial.println(received_data.substring(rdata1+1, rdata2));.

So basically the program can run the above lines smoothly until a period whereby the program is still able to print the data and not able to filter and print the filtered data.

What is the longest string you ever expect to receive over ethernet, and what's the longest you ever expect to receive from Zigbee?

Perhaps you can switch to the "the Standard Template Library 'string' class" (note the lowercase 's'). Nick's page says "You can reduce this fragmentation by using the 'reserve' function. For example: inputLine.reserve (100); // reserve 100 bytes". If you use the STL string class and reserve string lengths that you never, ever exceed in your program, you should be able to eliminate the crash (and without spending a lot of time changing the rest of your code).

Download link:

More info and links on Nick's page.

The longest string I receive over the ethernet is 6numbers. The longest string i receive from the zigbee is around 35letters or less. I will try that reserve function.

Another question to add on. Does Arduino uno have default timeout? I feel that my other program is not running as fast as Arduino ethernet, that maybe the problem of not receiving the data. Because I have tested and also proven that if my other program run at a slower pace, my program will freeze eventually. (100% freeze)

I have tried using delays and it is not the best solution as the problem still will appear at some random period again.
I have also tried using reset pin but it will slow down my overall program.

You might try ensuring the store_data String is emptied like below in your else statement.

        else
        {
        Serial.print(store_data); //print out store_data
        Zigbee.print("AT+SCAST,");
        Zigbee.println(store_data); //send store_data to Zigbee
        String store_data = "";
        }

Hi zoomkat, I tried moving String store_data = ""; to the bottom of the programming code but the program still freezes after some random period.

The String class is problematic in the Arduino environment, because of its reliance on dynamic memory allocation. The problem can cause exactly the sort of symptoms you're getting here. I suggest you get rid of it and use simple c-strings instead. That may fix the problem, but if not then at least you will be able to rule that possibility out.

Another possible issue is that this code will attempt to read from the network connection regardless of whether there is anything available to read:

    while (client.connected())
    {
      sdata = client.read();  //sdata read data

It would be better to only read when client.available() returns a positive value.

I have noticed some unusual logic to do with mainloop_receive, subloop_receive and the Zigbee receive loop. I haven't looked into those to see whether the basic logic of handling network connections and data makes sense, and perhaps it will work OK, but mixing the two sets of control together like this doesn't feel particularly safe.