[SOLVED] System crash, Overloaded SRAM?

Hi,

I am developing an embedded system interfaced trough a web server. I have an Arduino Mega 2560 and a WIZnet5100 ethernet shield. Currently I am powering an 16x2 LCD, DS1307 RTC, 16digit keypad and one IR sensor (E18-D80NK). My html is on a 4GB SD card, its only minimal code to display 4 variables, no css currently, only some javascript and xml.

When I upload my sketch, the bootloader confirms a successful upload of a sketch size: 30,658 bytes

However, the setup does not complete since I have no response from my LCD nor the serial monitor

When I uncomment the web server code and ethernet libraries, the application runs successfully.
I have measured the SRAM with the following function:

int freeRam () 
{
  extern int __heap_start, *__brkval; 
  int v; 
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 
}

And have called the function in numerous places in the code, the result is as follows:
With the ethernet shield libraries and web server code activated: no response since setup does not complete.
With the libraries and web server code deactivated: 6900 -7000 (bytes I assume)
With the ethernet shield libraries and web server code activated but with a different code structure, one using more while loops, less functions and variables. ( not sufficient for any purpose ): 5500-5600 bytes

I am terribly afraid that I am out of memory, I still need to add 5 IR sensors, 10 variables, 5 functions, 3 Web pages (on the SD-card)

I would love some advice since I am not an experienced developer, programmer, electronics major.
I will attach my code for reference. I have tried reducing the global variables, using the F() function on strings, reducing some datatypes to bytes...

Please assist where possible,
Thank you in advance.

#include <LiquidCrystal.h>
#include <Keypad.h>
#include <Wire.h>
#include "RTClib.h"
#include <SPI.h>
#include <Ethernet.h>
#include <SD.h>

#define REQ_BUF_SZ   60

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(169, 254, 84, 200); 
IPAddress subnet(255, 255, 0, 0);
EthernetServer server(80);  // create a server at port 80

File webFile;
char HTTP_req[REQ_BUF_SZ] = {0}; // buffered HTTP request stored as null terminated string
char req_index = 0;              // index into HTTP_req buffer

LiquidCrystal lcd(38, 36, 34, 32, 30, 28);
RTC_DS1307 RTC;

const byte numRows = 4;
const byte numCols = 4;

char keymap[numRows][numCols]= 
{
{'1', '2', '3', 'A'}, 
{'4', '5', '6', 'B'},  
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};

byte rowPins[numRows] = {35, 33, 31, 29}; 
byte colPins[numCols] = {43, 41, 39, 37};

  
Keypad keypad = Keypad( makeKeymap(keymap), rowPins, colPins, numRows, numCols );

const int IR1 = 26;

byte SavedNew = 0;
int SavedOld = 0;
int SavedAcc = 0;
char inData[4];
byte index;
byte amount;  
int WIP;

char key = keypad.getKey();


boolean TxtConValue = false;
boolean ArrivalValue = true;
boolean started = false;
boolean ended = false;
boolean lastState = 0;

void setup()
{
  Wire.begin();
  RTC.begin();
  server.begin();
  Ethernet.begin(mac, ip, subnet);
  Wire.begin();
  RTC.begin();
  
  Serial.println(freeRam());
  
  Serial.begin(9600);
  
   // initialize SD card
    Serial.println(F("Initializing SD card..."));
    if (!SD.begin(4)) {
        Serial.println(F("*ERROR - SD card initialization failed!"));
        return;    // init failed
    }
    Serial.println(F("SUCCESS - SD card initialized."));
    // check for file
    if (!SD.exists("KPDLCD.htm")) {
        Serial.println(F("ERROR - Can't find KPDLCD.htm file!"));
        return;  // can't find file
    }
    Serial.println(F("SUCCESS - Found KPDLCD.htm file."));
  
  pinMode(IR1,INPUT_PULLUP);
  
  // disable Ethernet chip
    pinMode(10, OUTPUT);
    digitalWrite(10, HIGH);
  
  lcd.begin(16,2);
  lcd.noAutoscroll();
  lcd.print("Arrival Amount:");
  lcd.setCursor(0,1);
  lcd.print("Enter->");
  Serial.println(F("Enter Arrival Amount"));
 
  keypad.setDebounceTime(25);  

if (! RTC.isrunning()) {
    Serial.println(F("RTC is NOT running!"));
    // following line sets the RTC to the date & time this sketch was compiled
    //RTC.adjust(DateTime(__DATE__, __TIME__));
    }

}


//Save Arrival Amount

int ArrivalAmount()
{ 
    
 if(ArrivalValue == true)
{ 
  char key = keypad.getKey();
  if (key != NO_KEY)
  {
    lcd.print(key);
    if(started == false && key != '*')
    {
    TxtArrivalAmount();
    key = 0;
    }
    else 
    {
      if (key == '*')
         {
          started = true;
          index = 0 ;
          inData[index] = '\0'; 
         }
     else if(key == 'A')
         {
          TxtArrivalAmount();
          key = 0;
         } 
     else if(key == '#')
          {
            ended = true;
          }
     else if(started)
          {
            inData[index] = key;
            index++;
            inData[index] = '\0';
          }      
    }   
  if(started && ended)
  {
    
   amount = atoi(inData);
    
   Serial.print(amount); 
   started = false;
   ended = false;
   index = 0;
   inData[index] = '\0';
   TxtConValue = true;   
  }
 } 
  return amount; 
}

}

//Save Accumulated Amount

  void AccumulatedAmount()
  {
      SavedAcc = SavedNew + SavedOld ;
      SavedOld = SavedAcc ;   
  }

//TextDisplay - Confrim Amount
      
  void  TxtConfirmAmount()
     {
       if(TxtConValue == true )
       {
         SavedNew = ArrivalAmount();
         lcd.clear();
         lcd.print("Confirm Input");
         lcd.setCursor(0,1);
         lcd.print("Amount = ");
         lcd.print(SavedNew);
         Serial.println();
         Serial.println(F("Awaiting Confirmation"));
         TxtConValue = false;
         ArrivalValue = false; 
         key = 0;    
       }   
       else
       ConfirmValue();
    }
      
      
   void ConfirmValue()
  {  
    if(ArrivalValue == false)
    {
    DateTime now = RTC.now();
    key = keypad.getKey();
    if(key == 'D')      
    { 
      AccumulatedAmount();
      Serial.print(F("Value Confirmed: "));
      Serial.println(SavedNew);
      Serial.print(F("Accumulated Value: "));
      Serial.println(SavedAcc);
      
      //Print Time
      Serial.print(now.year(), DEC);
      Serial.print('/');
      Serial.print(now.month(), DEC);
      Serial.print('/');
      Serial.print(now.day(), DEC);
      Serial.print(' ');
      Serial.print(now.hour(), DEC);
      Serial.print(':');
      Serial.print(now.minute(), DEC);
      Serial.print(':');
      Serial.print(now.second(), DEC);
      Serial.println();
      
      key = 0;
      ArrivalValue = true;
      TxtArrivalAmount();
      return; 
    } 
    else if (key == 'A')
    {  
      ArrivalValue = true;
      SavedNew = 0; 
      key = 0;
      TxtArrivalAmount();  
      return;  
    }
   }
 }   

//TextDisplay - Arrival Amount 

  void  TxtArrivalAmount()  
     {
        lcd.clear();
        lcd.print("Arrival Amount:");
        lcd.setCursor(0,1);
        lcd.print("Enter->");
        lcd.setCursor(7,1);
        Serial.println("Enter Arrival Amount");  
      }
      
 void GetWIP()
{
  if(digitalRead(IR1) == 0 && lastState == 0)
  {   
     if(SavedAcc > 0)
     {
       WIP = --SavedAcc;
       Serial.print("object detected");
       Serial.print("WIP: ");
       Serial.println(WIP);
       lastState = 1;
     }
     else
     {
     WIP = 0 ;  
     Serial.print(F("object detected"));
     Serial.print("WIP: ");
     Serial.println(WIP);
     lastState = 1;  
     }   
  }   
  else if(digitalRead(IR1) == 0 && lastState == 1)
  {}
  else if(digitalRead(IR1) == 1 && lastState == 1)
  {
  lastState = 0;
  } 
}      
   
  
  void loop()
  { 
   EthernetClient client = server.available();  // try to get client

    if (client) {  // got client?
        boolean currentLineIsBlank = true;
        while (client.connected()) {
            if (client.available()) {   // client data available to read
                char c = client.read(); // read 1 byte (character) from client
                // buffer first part of HTTP request in HTTP_req array (string)
                // leave last element in array as 0 to null terminate string (REQ_BUF_SZ - 1)
                if (req_index < (REQ_BUF_SZ - 1)) {
                    HTTP_req[req_index] = c;          // save HTTP request character
                    req_index++;
                }
                // last line of client request is blank and ends with \n
                // respond to client only after last line received
                if (c == '\n' && currentLineIsBlank) {
                    // send a standard http response header
                    client.println("HTTP/1.1 200 OK");
                    // remainder of header follows below, depending on if
                    // web page or XML page is requested
                    // Ajax request - send XML file
                    if (StrContains(HTTP_req, "ajax_inputs")) {
                        // send rest of HTTP header
                        client.println("Content-Type: text/xml");
                        client.println("Connection: keep-alive");
                        client.println();
                        // send XML file containing input states
                        XML_response(client);
                    }
                    else {  // web page request
                        // send rest of HTTP header
                        client.println("Content-Type: text/html");
                        client.println("Connection: keep-alive");
                        client.println();
                        // send web page
                        webFile = SD.open("KPDLCD.htm");        // open web page file
                        if (webFile) {
                            while(webFile.available()) {
                                client.write(webFile.read()); // send web page to client
                            }
                            webFile.close();
                        }
                    }
                    // display received HTTP request on serial port
                    Serial.print(HTTP_req);
                    // reset buffer index and all buffer elements to 0
                    req_index = 0;
                    StrClear(HTTP_req, REQ_BUF_SZ);
                    break;
                }
                // every line of text received from the client ends with \r\n
                if (c == '\n') {
                    // last character on line of received text
                    // starting new line with next character read
                    currentLineIsBlank = true;
                } 
                else if (c != '\r') {
                    // a text character was received from client
                    currentLineIsBlank = false;
                }
            } // end if (client.available())
        } // end while (client.connected())
        delay(1);      // give the web browser time to receive the data
        client.stop(); // close the connection
    } // end if (client)
}  
  
   
// send the XML file with switch statuses and analog value
void XML_response(EthernetClient cl)
{
 
ArrivalAmount();
TxtConfirmAmount();
GetWIP();

cl.print("<?xml version = \"1.0\" ?>");
cl.print("<inputs>");

cl.print("<Saved>");
cl.print(SavedNew);
cl.println("</Saved>");

cl.print("<Accumulated>");
cl.print(SavedAcc);
cl.println("</Accumulated>");

cl.print("<WIP>");
cl.print(WIP);   
cl.println("</WIP>");

DateTime now = RTC.now();

cl.print("<time>");
cl.print(now.year(), DEC);
cl.println("</time>");

cl.print("<time>");
cl.print(now.month(), DEC);
cl.println("</time>");

cl.print("<time>");
cl.print(now.day(), DEC);
cl.println("</time>");

cl.print("<time>");
cl.print(now.hour(), DEC);
cl.println("</time>");

cl.print("<time>");
cl.print(now.minute(), DEC);
cl.println("</time>");

cl.print("<time>");
cl.print(now.second(), DEC);
cl.println("</time>");

cl.print("</inputs>");
}  

// sets every element of str to 0 (clears array)
void StrClear(char *str, char length)
{
    for (int i = 0; i < length; i++) {
        str[i] = 0;
    }
}

// searches for the string sfind in the string str
// returns 1 if string found
// returns 0 if string not found
char StrContains(char *str, char *sfind)
{
    char found = 0;
    char index = 0;
    char len;

    len = strlen(str);
    
    if (strlen(sfind) > len) {
        return 0;
    }
    while (index < len) {
        if (str[index] == sfind[found]) {
            found++;
            if (strlen(sfind) == found) {
                return 1;
            }
        }
        else {
            found = 0;
        }
        index++;
    }

    return 0;   
}

Try this for the start of your setup function. Let's try to get you to the point where you find out how much SRAM you have remaining. What is the last message you see on the serial monitor?

void setup()
{
  // start serial
  Serial.begin(9600);

  // disable SD SPI
  pinMode(4,OUTPUT);
  digitalWrite(4,HIGH);

  Serial.println(F("Starting wire"));
  Wire.begin();

  Serial.println(F("Starting RTC"));
  RTC.begin();

  Serial.println(F("Starting ethernet"));
  Ethernet.begin(mac, ip);

  Serial.println(F("Starting server"));
  server.begin();
  
  // removed the duplicate wire and rtc begin calls from here

  Serial.print(F("SRAM remaining: "));
  Serial.println(freeRam());

Thank you SurferTim for pointing out the illogical flow of my setup function. Tiding it up seemed to have fixed the problem. Late night, early morning logical thinking.

Serial monitor reports I have 5820 bytes left after setup and 5750 left during full operation.

Can you post the working code to check available Scram? I believe I am out as well, and am considering purchasing a 23K256 chip.