Persistant Problem with Strings

I posted this problem yesterday, and thought I had fixed the problem. I am building a program that uses rfid, a magnetic card reader, and ethernet to update a mysql database via mysql. In a function that loops through character array the variable becomes null when i add to the code. I believe, after some advice, that this is a memory allocation issue. In hopes of fixing the problem, i got rid of all the String variables which helped a bit and adjusted the code. Is there a way to discover how much memory the program is using or if there is something in my code that is causing the problem. Are there ways to address this problem or allocate more memory. Do I need a mega. I will paste the code below. The code did not seem that intensive but, I am not sure

Thanks,

Eric

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

// Set up the serial connection to the RFID reader module. In order to
// keep the Arduino TX and RX pins free for communication with a host,
// the sketch uses the SoftwareSerial library to implement serial
// communications on other pins.
#include <SoftwareSerial.h>



// The RFID module's TX pin needs to be connected to the Arduino. Module
// RX doesn't need to be connected to anything since we won't send
// commands to it, but SoftwareSerial requires us to define a pin for
// TX anyway so you can either connect module RX to Arduino TX or just
// leave them disconnected.

// If you have built the circuit exactly as described in Practical
// Arduino, use pins D2 / D3:
#define rxPin 6
#define txPin 7

// Create a software serial object for the connection to the RFID module
SoftwareSerial rfid = SoftwareSerial( rxPin, txPin );

// Set up outputs for the strike plate and status LEDs.
// If you have built the circuit exactly as described in Practical
// Arduino, use pins D12 and D13:
#define strikePlate 12
#define ledPin 13

// The tag database consists of two parts. The first part is an array of
// tag values with each tag taking up 5 bytes. The second is a list of
// names with one name for each tag (ie: group of 5 bytes).
char* allowedTags[] = {
  "1C00EFE643",         // Tag 1
  "04146E8BDD",         // Tag 2
  "0413BBBF23",         // Tag 3
   "1B001421DA",         // Tag 4
   "1B001461DA",         // Tag 5
   "1B001321DA",         // Tag 6
   "1B001221DA",         // Tag 7
   "1B002421Db",         // Tag 8
   "1B011421D1",         // Tag 9
   "1B101421D2",         // Tag 11
   "1B101421D2",         // Tag 12
   "1B101421D2",         // Tag 13
   "1B101421D2",         // Tag 14
};

// List of names to associate with the matching tag IDs
char* tagName[] = {
  "Jonathan Oxer",      // Tag 1
  "Hugh Blemings",      // Tag 2
  "Dexter D Dog",       // Tag 3
  "Set Paper Low",      // Tag 4
  "Jonathan Oxer",      // Tag 5
  "Hugh Blemings",      // Tag 6
  "Dexter D Dog",       // Tag 7
  "Paper Low8",          // Tag 8
  "Jonathan Oxer",      // Tag 9
  "Hugh Blemings",      // Tag 10
  "Dexter D Dog",       // Tag 11
  "Paper Low12",          // Tag 12
  "Paper Low13",          // Tag 13
  "Paper Low14",          // Tag 14
};

int cld1Pin = 4;            // Card status pin
int rdtPin = 2;             // Data pin
int reading = 0;            // Reading status
volatile int buffer[400];   // Buffer for data
volatile int i = 0;         // Buffer counter
volatile int bit = 0;       // global bit
char cardData[40];          // holds card info
int charCount = 0;          // counter for info
int DEBUG = 0;
unsigned int cnt=0;
char Card_Str[] = "11111111111111111111";
int scroll_pos=0;
int scroll_state=0;

// Check the number of tags defined
int numberOfTags = sizeof(allowedTags)/sizeof(allowedTags[0]);
char* states[]={
  "checked out",
  "Checked In ",
  "Supplies Low ", 
  "Supplies High "
};



int incomingByte = 0;    // To store incoming serial data

///////////////////////////////////////////////////////////////////////
//CONFIGURE ethernet
////////////////////////////////////////////////////////////////////////
  byte ip[] = { 192, 168, 0, 199 };   //ip address to assign the arduino
  byte server[] = {174,123,231,247}; //ip Address of the server you will connect to

  //The location to go to on the server
  //make sure to keep HTTP/1.0 at the end, this is telling it what type of file it is
  //String location = "/~bildr/examples/ethernet/ HTTP/1.0";
 
  //Rarly need to change this
  byte subnet[] = { 255, 255, 255, 0 };

  // if need to change the MAC address (Very Rare)
  byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

  Client client(server, 80); // port 80 is typical www page*/

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

char inString[32]; // string for incoming serial data
int stringPos = 0; // string index counter
boolean startRead = false; // is reading?

/**
 * Setup
 */
void setup() {
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);
  pinMode(strikePlate, OUTPUT);
  digitalWrite(strikePlate, LOW);

  Serial.begin(9600);   // Serial port for connection to host
  rfid.begin(9600);      // Serial port for connection to RFID module
  
   // The interrupts are key to reliable
  // reading of the clock and data feed
  attachInterrupt(0, changeBit, CHANGE);
  attachInterrupt(1, writeBit, FALLING);

  Serial.println("RFID reader starting up");
}

/**
 * Loop
 */

/**
 * Loop
 */
void loop() {
  byte i         = 0;
  byte val       = 0;
  byte checksum  = 0;
  byte bytesRead = 0;
  byte tempByte  = 0;
  byte tagBytes[6];    // "Unique" tags are only 5 bytes but we need an extra byte for the checksum
  char tagValue[10];
  int state=0;
  
    get_supplies2(1);
 
  
  // Read from the RFID module. Because this connection uses SoftwareSerial
  // there is no equivalent to the Serial.available() function, so at this
  // point the program blocks while waiting for a value from the module
  if((val = rfid.read()) == 2) {        // Check for header
    bytesRead = 0;
    while (bytesRead < 12) {            // Read 10 digit code + 2 digit checksum
      val = rfid.read();

      // Append the first 10 bytes (0 to 9) to the raw tag value
      if (bytesRead < 10)
      {
        tagValue[bytesRead] = val;
      }

      // Check if this is a header or stop byte before the 10 digit reading is complete
      if((val == 0x0D)||(val == 0x0A)||(val == 0x03)||(val == 0x02)) {
        break;                          // Stop reading
      }

      // Ascii/Hex conversion:
      if ((val >= '0') && (val <= '9')) {
        val = val - '0';
      }
      else if ((val >= 'A') && (val <= 'F')) {
        val = 10 + val - 'A';
      }

      // Every two hex-digits, add a byte to the code:
      if (bytesRead & 1 == 1) {
        // Make space for this hex-digit by shifting the previous digit 4 bits to the left
        tagBytes[bytesRead >> 1] = (val | (tempByte << 4));

        if (bytesRead >> 1 != 5) {                // If we're at the checksum byte,
          checksum ^= tagBytes[bytesRead >> 1];   // Calculate the checksum... (XOR)
        };
      } else {
        tempByte = val;                           // Store the first hex digit first
      };

      bytesRead++;                                // Ready to read next digit
    }

    // Send the result to the host connected via USB
    if (bytesRead == 12) {                        // 12 digit read is complete
      tagValue[10] = '\0';                        // Null-terminate the string

      Serial.print("Tag read: ");
      for (i=0; i<5; i++) {
        // Add a leading 0 to pad out values below 16
        if (tagBytes[i] < 16) {
          Serial.print("0");
        }
        Serial.print(tagBytes[i], HEX);
      }
      Serial.println();

      Serial.print("Checksum: ");
      Serial.print(tagBytes[5], HEX);
      Serial.println(tagBytes[5] == checksum ? " -- passed." : " -- error.");

      // Show the raw tag value
      //Serial.print("VALUE: ");
      //Serial.println(tagValue);

      // Search the tag database for this particular tag
      int tagId = findTag( tagValue );

      // if tag is found
      if( tagId > 0 )
       Serial.print("Authorized tag ID ");
        Serial.println(tagId);
        if(tagId<30){//equipment
            Serial.print("State:");
           Serial.println(state);
            Serial.println(states[state]);
            switch (state) {
              case 0: //checked out
              Serial.print(tagName[tagId - 1]);
             // Serial.println("Checked out, Scan ID to Check in");
              if(Scan_ID()==1){//id scan ok
                 if(senddata(tagId,2)==1){
                   Serial.print("Updated Record");
                 }
                 else{
                   Serial.print("Could not access server");
                 }
              }
              else{
                //Serial.println("ID Not valid or could not be read");
              }
              break;
            case 1://checked in check out
              Serial.print(tagName[tagId - 1]);
              Serial.println(" Checked in, Scan ID to Check Out");
              if(Scan_ID()==1){//id scan ok
                 if(senddata(tagId,1)==1){
               //    Serial.print("Updated Record");
                 }
                 else{
                   Serial.print("Could not access server");
                 }
              }
              else{
                Serial.println("ID Not valid or could not be read");
              }
              break;
              
            }//switch
        }//equip if
        else{  // supplies
        }
      {
        
      }// tag if
      Serial.println();     // Blank separator line in output
    }

    bytesRead = 0;
  }
  
 
}
int check_status(int tag) {//get tags status
     //The location to go to on the server
    //make sure to keep HTTP/1.0 at the end, this is telling it what type of file it is
   //Ethernet.begin(mac, ip);
   //String location = "/http://www.underthemountain.org/";
 // String location = String("/inventory/status.php?tag="+ String(tag) + " HTTP/1.0");
 // String pageValue = connectAndRead(location);
  digitalWrite(ledPin, HIGH);
  delay(500);
  return atoi("3");
  digitalWrite(ledPin, LOW);
}
/**
 * Get user status from the DB
 */
int CheckUser(){

   return 1;
}


/**
 * Search for a specific tag in the database
 */
int findTag( char tagValue[10] ) {
  for (int thisCard = 0; thisCard < numberOfTags; thisCard++) {
    // Check if the tag value matches this row in the tag database
    if(strcmp(tagValue, allowedTags[thisCard]) == 0)
    {
      // The row in the database starts at 0, so add 1 to the result so
      // that the card ID starts from 1 instead (0 represents "no match")
      return(thisCard + 1);
    }
  }
  // If we don't find the tag return a tag ID of 0 to show there was no match
  return(0);
}


int Scan_ID(){
  strncpy(Card_Str, "NEW", 20);
  unsigned int exit=0;
  unsigned int timeout = millis();
  unsigned int track=0;
  while(((millis()-timeout)< 10000) && exit==0){ // set this to your timeout value in milliseconds
    // Active when card present
    //Serial.println(millis()-timeout);
    while(digitalRead(cld1Pin) == LOW){
      reading = 1;
    }     
   
    // Active when read is complete
    // Reset the buffer
    if(reading == 1) {  
   
      if (DEBUG == 1) {
        printBuffer(track);
      }
      decode(track);
      track++;
      reading = 0;
      if (Card_Str[0]=='9'){
        Serial.println("valid:");
        if(CheckUser()==1){
          return 1;
        }
        else{
          return 0;
        }
        exit=1;
      }
      i = 0;
   
      int l;
      for (l = 0; l < 40; l = l + 1) {
        cardData[l] = '\n';
      }
   
      charCount = 0;
    }
  }
  timeout = 0;
  

 
}



unsigned int senddata(int tag,int state)
{

  
   //The location to go to on the server
   //make sure to keep HTTP/1.0 at the end, this is telling it what type of file it is
   //Ethernet.begin(mac, ip);
   //GET http://server.com/script.php?tag="
   //String location = "/http://www.underthemountain.org/";
 // String location =String("/inventory/update.php?tag="+ String(tag) + "&state="+ String(state)+ "&id="+ String(Card_Str) + " HTTP/1.0");
 // String pageValue = connectAndRead(location);
   digitalWrite(ledPin, HIGH);
  delay(500);
  digitalWrite(ledPin, LOW);
  
  return 3;
  
}



void get_supplies2(int pge){
    char sz[] = "Here; is some; sample;100;data;1.414;1020; wwwww;wwwwwwwwwww;data;1.414;1020;xxxx;yyyy;100;datadata;1.414;zzzzz;tap;dance;now;happy as a clam";
  
  // String location =String("/inventory/update.php?page="+String(pge));
   //String pageValue = connectAndRead(location);
   //char carray[pageValue.length()];
   //pageValue.toCharArray(carray, sizeof(carray));
   int scroll_state=1 ;
   int x=0;
   char *p = sz;
   char *str;
   int cnt=0;
   int xx=0;

   
    while (str = strtok_r(p, ";", &p)){ // delimiter is the semicolon
       //Serial.print("count:");
       //Serial.println(cnt);
       //Serial.println(str);
      if(cnt<4){//header info
        // Header[cnt]=pageValue.substring(loc,delim).toCharArray;
        Serial.print("header:");
        Serial.println(str);
       }
       else{//main info
         if(xx>=scroll_state){//print if at current scroll
            if(xx<=4){
              Serial.print(str);
              Serial.print(" | ");
            }
            else{
              Serial.println(str);
              xx=scroll_state;
            }//if
            
         }//if
         xx++;
       }//else
     //Serial.println("Cnt"+cnt);
     cnt++;    
  } 

}

// Flips the global bit
void changeBit(){
  if (bit == 0) {
    bit = 1;
  } else {
    bit = 0;
  }
}
 
// Writes the bit to the buffer
void writeBit(){
  buffer[i] = bit;
  i++;
}
 
// prints the buffer
void printBuffer(unsigned int trk ){
  int j;
  for (j = 0; j < 200; j = j + 1) {
    Serial.println(buffer[j]);
  }
}
 
int getStartSentinal(){
  int j;
  int queue[5];
  int sentinal = 0;
 
  for (j = 0; j < 400; j = j + 1) {
    queue[4] = queue[3];
    queue[3] = queue[2];
    queue[2] = queue[1];
    queue[1] = queue[0];
    queue[0] = buffer[j];
 
    if (DEBUG == 1) {
      Serial.print(queue[0]);
      Serial.print(queue[1]);
      Serial.print(queue[2]);
      Serial.print(queue[3]);
      Serial.println(queue[4]);
    }
 
    if (queue[0] == 0 && queue[1] == 1 && queue[2] == 0 && queue[3] == 1 && queue[4] == 1) {
      sentinal = j - 4;
      break;
    }
  }
 
  if (DEBUG == 1) {
    Serial.print("sentinal:");
    Serial.println(sentinal);
    Serial.println("");
  }
 
  return sentinal;
}
 
void decode(unsigned int trk) {
  int sentinal = getStartSentinal();
  int j;
  int i = 0;
  int k = 0;
  int thisByte[5];
 
  for (j = sentinal; j < 400 - sentinal; j = j + 1) {
    thisByte[i] = buffer[j];
    i++;
    if (i % 5 == 0) {
      i = 0;
      if (thisByte[0] == 0 && thisByte[1] == 0 && thisByte[2] == 0 && thisByte[3] == 0 && thisByte[4] == 0) {
        break;
      }
      printMyByte(thisByte);
    }
  }
 Serial.print("Track:");
 Serial.println(trk);
 //if(trk==0){
    Serial.print("Stripe_Data:");
    String Cardstr="";
    for (k = 0; k < charCount; k = k + 1) {
      Serial.print(cardData[k]);
      Card_Str[k]=cardData[k];
      //Serial.print(Cardstr);
    }
   // if(trk==0){
  //  }
    Serial.println("");
// }
 
}
 
void printMyByte(int thisByte[]) {
  int i;
  for (i = 0; i < 5; i = i + 1) {
    if (DEBUG == 1) {
      Serial.print(thisByte[i]);
    }
}
    if (DEBUG == 1) {
      Serial.print("\t");
      Serial.print(decodeByte(thisByte));
      Serial.println("");
    }
 
    cardData[charCount] = decodeByte(thisByte);
    charCount ++;
}
 
char decodeByte(int thisByte[]) {
    if (thisByte[0] == 0 && thisByte[1] == 0 && thisByte[2] == 0 && thisByte[3] == 0 && thisByte[4] == 1){
      return '0';
    }
    if (thisByte[0] == 1 && thisByte[1] == 0 && thisByte[2] == 0 && thisByte[3] == 0 && thisByte[4] == 0){
      return '1';
    }
 
    if (thisByte[0] == 0 && thisByte[1] == 1 && thisByte[2] == 0 && thisByte[3] == 0 && thisByte[4] == 0){
      return '2';
    }
 
    if (thisByte[0] == 1 && thisByte[1] == 1 && thisByte[2] == 0 && thisByte[3] == 0 && thisByte[4] == 1){
      return '3';
    }
 
    if (thisByte[0] == 0 && thisByte[1] == 0 && thisByte[2] == 1 && thisByte[3] == 0 && thisByte[4] == 0){
      return '4';
    }
 
    if (thisByte[0] == 1 && thisByte[1] == 0 && thisByte[2] == 1 && thisByte[3] == 0 && thisByte[4] == 1){
      return '5';
    }
 
    if (thisByte[0] == 0 && thisByte[1] == 1 && thisByte[2] == 1 && thisByte[3] == 0 && thisByte[4] == 1){
      return '6';
    }
 
    if (thisByte[0] == 1 && thisByte[1] == 1 && thisByte[2] == 1 && thisByte[3] == 0 && thisByte[4] == 0){
      return '7';
    }
 
    if (thisByte[0] == 0 && thisByte[1] == 0 && thisByte[2] == 0 && thisByte[3] == 1 && thisByte[4] == 0){
      return '8';
    }
 
    if (thisByte[0] == 1 && thisByte[1] == 0 && thisByte[2] == 0 && thisByte[3] == 1 && thisByte[4] == 1){
      return '9';
    }
 
    if (thisByte[0] == 0 && thisByte[1] == 1 && thisByte[2] == 0 && thisByte[3] == 1 && thisByte[4] == 1){
      //return ':';
    }
 
    if (thisByte[0] == 1 && thisByte[1] == 1 && thisByte[2] == 0 && thisByte[3] == 1 && thisByte[4] == 0){
      //return ';';
    }
 
    if (thisByte[0] == 0 && thisByte[1] == 0 && thisByte[2] == 1 && thisByte[3] == 1 && thisByte[4] == 1){
      //return '<';
    }
 
    if (thisByte[0] == 1 && thisByte[1] == 0 && thisByte[2] == 1 && thisByte[3] == 1 && thisByte[4] == 0){
      //return '=';
    }
 
    if (thisByte[0] == 0 && thisByte[1] == 1 && thisByte[2] == 1 && thisByte[3] == 1 && thisByte[4] == 0){
      //return '>';
    }
 
    if (thisByte[0] == 1 && thisByte[1] == 1 && thisByte[2] == 1 && thisByte[3] == 1 && thisByte[4] == 1){
      //return '?';
    }
}

int connectAndRead(String loc){
 //connect to the server

  Serial.println("connecting...");

  if (client.connect()) {
    Serial.println("connected");
    client.print("GET ");
    client.println(loc);
    client.println();

    //Connected - Read the page
    return readPage(); //go and read the output

  }else{
    return 0;
  }
}
int readPage(){
//read the page, and capture & return everything between '<' and '>'

  stringPos = 0;
  memset( &inString, 0, 32 ); //clear inString memory

  while(true){

    if (client.available()) {
      char c = client.read();

      if (c == '<' ) { //'<' is our begining character
        startRead = true; //Ready to start reading the part 
      }else if(startRead){

        if(c != '>'){ //'>' is our ending character
          inString[stringPos] = c;
          stringPos ++;
        }else{
          //got what we need here! We can disconnect now
          startRead = false;
          client.stop();
          client.flush();
          Serial.println("disconnecting.");
          return 1;

        }

      }
    }

  }

}

One thing you can do is to use the PROGMEM directives to store these tables of data:

// The tag database consists of two parts. The first part is an array of
// tag values with each tag taking up 5 bytes. The second is a list of
// names with one name for each tag (ie: group of 5 bytes).
char* allowedTags[] = {
  "1C00EFE643",         // Tag 1
  "04146E8BDD",         // Tag 2
  "0413BBBF23",         // Tag 3
   "1B001421DA",         // Tag 4
   "1B001461DA",         // Tag 5
   "1B001321DA",         // Tag 6
   "1B001221DA",         // Tag 7
   "1B002421Db",         // Tag 8
   "1B011421D1",         // Tag 9
   "1B101421D2",         // Tag 11
   "1B101421D2",         // Tag 12
   "1B101421D2",         // Tag 13
   "1B101421D2",         // Tag 14
};

// List of names to associate with the matching tag IDs
char* tagName[] = {
  "Jonathan Oxer",      // Tag 1
  "Hugh Blemings",      // Tag 2
  "Dexter D Dog",       // Tag 3
  "Set Paper Low",      // Tag 4
  "Jonathan Oxer",      // Tag 5
  "Hugh Blemings",      // Tag 6
  "Dexter D Dog",       // Tag 7
  "Paper Low8",          // Tag 8
  "Jonathan Oxer",      // Tag 9
  "Hugh Blemings",      // Tag 10
  "Dexter D Dog",       // Tag 11
  "Paper Low12",          // Tag 12
  "Paper Low13",          // Tag 13
  "Paper Low14",          // Tag 14
};

See: PROGMEM - Arduino Reference for details

Thanks again. I used that wherever I could(read only vars), and it helped but am still coming up short as I still need to add some code. I think the combination of using the ethernet library and software serial and using interrupts to process the card reader is too much despite the small program size. I was just a bit surprised because I have written much more complex programs without a problem. I used the function below and it was giving out values below 200. I tried to remove parts to see if there was a culprit, but everything seemed equally culpable for the loss. The blink program was giving out 1849. When it got below 200, string went away. I am now thinking I need to upgrade to Mega and a Ethernet board. I was using the pro-mini with the built in ethernet but...

int availableMemory() {
  uint8_t * heapptr, * stackptr;
  stackptr = (uint8_t *)malloc(4);
  heapptr = stackptr;
  free(stackptr);               
  stackptr = (uint8_t *)(SP);
  return stackptr - heapptr;
}

Every time you use a string in a print() or println(), that string uses up RAM. That's just the way the library works. You have quite a few println() scattered throughout your code. For example:

Serial.println("disconnecting.");

uses up 14 bytes of RAM.

All those static strings can be moved to progmem to free up RAM as well.

The tool you want to figure out how much memory is used by different things is probably "objdump."

Note that objdump (it may be called avr-objdump) does not tell you how much stack space a particular function may use, though, so be careful with the amount of local variables you use!

Wow. Thanks again; I thought I was toast. I see I have some more room to free up memory, and some new tools as well. I will get to work and post the new code.

Eric

Here is the update code. I could not find avr-objdump on my mac; I will continue to try to find out where this is and how to use.

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


// Set up the serial connection to the RFID reader module. In order to
// keep the Arduino TX and RX pins free for communication with a host,
// the sketch uses the SoftwareSerial library to implement serial
// communications on other pins.
#include <SoftwareSerial.h>



// The RFID module's TX pin needs to be connected to the Arduino. Module
// RX doesn't need to be connected to anything since we won't send
// commands to it, but SoftwareSerial requires us to define a pin for
// TX anyway so you can either connect module RX to Arduino TX or just
// leave them disconnected.

// If you have built the circuit exactly as described in Practical
// Arduino, use pins D2 / D3:
#define rxPin 6
#define txPin 7

// Create a software serial object for the connection to the RFID module
SoftwareSerial rfid = SoftwareSerial( rxPin, txPin );

// Set up outputs for the strike plate and status LEDs.
// If you have built the circuit exactly as described in Practical
// Arduino, use pins D12 and D13:
#define strikePlate 12
#define ledPin 13

// The tag database consists of two parts. The first part is an array of
// tag values with each tag taking up 5 bytes. The second is a list of
// names with one name for each tag (ie: group of 5 bytes).
PROGMEM char* allowedTags[] = {
  "1C00EFE643",         // Tag 1
  "04146E8BDD",         // Tag 2
  "0413BBBF23",         // Tag 3
   "1B001421DA",         // Tag 4
   "1B001461DA",         // Tag 5
   "1B001321DA",         // Tag 6
   "1B001221DA",         // Tag 7
   "1B002421Db",         // Tag 8
   "1B011421D1",         // Tag 9
   "1B101421D2",         // Tag 11
   "1B101421D2",         // Tag 12
   "1B101421D2",         // Tag 13
   "1B101421D2",         // Tag 14
};

// List of names to associate with the matching tag IDs
PROGMEM char* tagName[] = {
  "Jonathan Oxer",      // Tag 1
  "Hugh Blemings",      // Tag 2
  "Dexter D Dog",       // Tag 3
  "Set Paper Low",      // Tag 4
  "Jonathan Oxer",      // Tag 5
  "Hugh Blemings",      // Tag 6
  "Dexter D Dog",       // Tag 7
  "Paper Low8",          // Tag 8
  "Jonathan Oxer",      // Tag 9
  "Hugh Blemings",      // Tag 10
  "Dexter D Dog",       // Tag 11
  "Paper Low12",          // Tag 12
  "Paper Low13",          // Tag 13
  "Paper Low14",          // Tag 14
};

int cld1Pin = 4;            // Card status pin
int rdtPin = 2;             // Data pin
int reading = 0;            // Reading status
volatile int buffer[400];   // Buffer for data
volatile int i = 0;         // Buffer counter
volatile int bit = 0;       // global bit
char cardData[25];          // holds card info
int charCount = 0;          // counter for info
//int DEBUG = 0;
unsigned int cnt=0;
char Card_Str[] = "11111111111111111";
//int scroll_pos=0;
//int scroll_state=0;
//uint8_t * heapptr, * stackptr;




// Check the number of tags defined
PROGMEM int numberOfTags = sizeof(allowedTags)/sizeof(allowedTags[0]);
PROGMEM char* states[]={
  "checked out",
  "Checked In ",
  "Supplies Low ", 
  "Supplies High "
};



int incomingByte = 0;    // To store incoming serial data

///////////////////////////////////////////////////////////////////////
//CONFIGURE ethernet
////////////////////////////////////////////////////////////////////////
  PROGMEM byte ip[] = { 192, 168, 0, 199 };   //ip address to assign the arduino
  PROGMEM byte server[] = {174,123,231,247}; //ip Address of the server you will connect to

  //The location to go to on the server
  //make sure to keep HTTP/1.0 at the end, this is telling it what type of file it is
  //String location = "/~bildr/examples/ethernet/ HTTP/1.0";
 
  //Rarly need to change this
  PROGMEM byte subnet[] = { 255, 255, 255, 0 };

  // if need to change the MAC address (Very Rare)
  //byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

  Client client(server, 80); // port 80 is typical www page*/

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

char inString[32]; // string for incoming serial data
int stringPos = 0; // string index counter
boolean startRead = false; // is reading?

/**
 * Setup
 */
void setup() {
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);
  //pinMode(strikePlate, OUTPUT);
  Serial.begin(9600);   // Serial port for connection to host
  rfid.begin(9600);      // Serial port for connection to RFID module
  
   // The interrupts are key to reliable
  // reading of the clock and data feed
  attachInterrupt(0, changeBit, CHANGE);
  attachInterrupt(1, writeBit, FALLING);


}
/**
 * Loop
 */
void loop() {
   byte i         = 0;
   byte val       = 0;
   byte checksum  = 0;
   byte bytesRead = 0;
   byte tempByte  = 0;
   byte tagBytes[6];    // "Unique" tags are only 5 bytes but we need an extra byte for the checksum
   char tagValue[10];
   int state=0;
  

    get_supplies2(1);
  
  
  // Read from the RFID module. Because this connection uses SoftwareSerial
  // there is no equivalent to the Serial.available() function, so at this
  // point the program blocks while waiting for a value from the module
  if((val = rfid.read()) == 2) {        // Check for header
    bytesRead = 0;
    while (bytesRead < 12) {            // Read 10 digit code + 2 digit checksum
      val = rfid.read();

      // Append the first 10 bytes (0 to 9) to the raw tag value
      if (bytesRead < 10)
      {
        tagValue[bytesRead] = val;
      }

      // Check if this is a header or stop byte before the 10 digit reading is complete
      if((val == 0x0D)||(val == 0x0A)||(val == 0x03)||(val == 0x02)) {
        break;                          // Stop reading
      }

      // Ascii/Hex conversion:
      if ((val >= '0') && (val <= '9')) {
        val = val - '0';
      }
      else if ((val >= 'A') && (val <= 'F')) {
        val = 10 + val - 'A';
      }

      // Every two hex-digits, add a byte to the code:
      if (bytesRead & 1 == 1) {
        // Make space for this hex-digit by shifting the previous digit 4 bits to the left
        tagBytes[bytesRead >> 1] = (val | (tempByte << 4));

        if (bytesRead >> 1 != 5) {                // If we're at the checksum byte,
          checksum ^= tagBytes[bytesRead >> 1];   // Calculate the checksum... (XOR)
        };
      } else {
        tempByte = val;                           // Store the first hex digit first
      };

      bytesRead++;                                // Ready to read next digit
    }

    // Send the result to the host connected via USB
    if (bytesRead == 12) {                        // 12 digit read is complete
      tagValue[10] = '\0';                        // Null-terminate the string

      //Serial.print("Tag read: ");
      for (i=0; i<5; i++) {
        // Add a leading 0 to pad out values below 16
        if (tagBytes[i] < 16) {
          PROGMEM String zr =  "0";
          Serial.print(zr);
        }
        Serial.print(tagBytes[i], HEX);
      }
      //Serial.println();
     // Serial.print("Checksum: ");
      //Serial.print(tagBytes[5], HEX);
      PROGMEM String psd =  " -- passed.";
      PROGMEM String err =  " -- error.";
      Serial.println(tagBytes[5] == checksum ? psd :err  );

      // Show the raw tag value
      //Serial.print("VALUE: ");
      //Serial.println(tagValue);

      // Search the tag database for this particular tag
      int tagId = findTag( tagValue );

      // if tag is found
      if( tagId > 0 )
      PROGMEM String auth =  "Authorized tag ID ";
      PROGMEM String UpRec="Updated Record";
      PROGMEM String SrvEr="Could not access server";
      PROGMEM String ChkdOut=" Checked in, Scan ID to Check Out";
      PROGMEM String ChkdIn=" Checked Out, Scan ID to Check In";
      PROGMEM String NtVld=" ID Not valid or could not be read";
      // Serial.print(auth);
        Serial.println(tagId);
        if(tagId<30){//equipment
           //Serial.print("State:");
           //Serial.println(state);
            //Serial.println(states[state]);
           switch (state) {
              case 0: //checked out
              Serial.print(tagName[tagId - 1]);
             // Serial.println("Checked out, Scan ID to Check in");
              if(Scan_ID()==1){//id scan ok
                 if(senddata(tagId,2)==1){
                   Serial.print(UpRec);
                 }
                 else{
                   Serial.print(SrvEr);
                 }
              }
              else{
                Serial.println(NtVld);
              }
              break;
            case 1://checked in check out
              Serial.print(tagName[tagId - 1]);
              Serial.println(" Checked in, Scan ID to Check Out");
              if(Scan_ID()==1){//id scan ok
                 if(senddata(tagId,1)==1){
                      Serial.print(UpRec);
                 }
                 else{
                   Serial.print(SrvEr);
                 }
              }
              else{
                Serial.println(NtVld);
              }
              break;
              
            }//switch
        }//equip if
        else{  // supplies
        }
      {
        
      }// tag if
      Serial.println();     // Blank separator line in output
    }

    bytesRead = 0;
  }
  
 
}

int check_status(int tag) {//get tags status
     //The location to go to on the server
    //make sure to keep HTTP/1.0 at the end, this is telling it what type of file it is
   //Ethernet.begin(mac, ip);
   //String location = "/http://www.underthemountain.org/";
 // String location = String("/inventory/status.php?tag="+ String(tag) + " HTTP/1.0");
 // String pageValue = connectAndRead(location);
  
  return 3;

}
/**
 * Get user status from the DB
 */
int CheckUser(){

   return 1;
}


/**
 * Search for a specific tag in the database
 */
int findTag( char tagValue[10] ) {
  for (int thisCard = 0; thisCard < numberOfTags; thisCard++) {
    // Check if the tag value matches this row in the tag database
    if(strcmp(tagValue, allowedTags[thisCard]) == 0)
    {
      // The row in the database starts at 0, so add 1 to the result so
      // that the card ID starts from 1 instead (0 represents "no match")
      return(thisCard + 1);
    }
  }
  // If we don't find the tag return a tag ID of 0 to show there was no match
  return(0);
}


int Scan_ID(){
  boolean exit = false;
  unsigned int timeout = millis();
  boolean track=true;
  while(((millis()-timeout)< 10000) && exit){ // set this to your timeout value in milliseconds
    // Active when card present
    //Serial.println(millis()-timeout);
    while(digitalRead(cld1Pin) == LOW){
      reading = 1;
    }     
   
    // Active when read is complete
    // Reset the buffer
    if(reading == 1) {  
   
      /*if (DEBUG == 1) {
        printBuffer(track);
      }*/
      decode(track);
      track=false;
      reading = 0;
      if (Card_Str[0]=='9'){
        Serial.println("valid:");
        if(CheckUser()==1){
          return 1;
        }
        else{
          return 0;
        }
        exit=true;
      }
      i = 0;
   
      int l;
      for (l = 0; l < 40; l = l + 1) {
        cardData[l] = '\n';
      }
   
      charCount = 0;
    }
  }
  timeout = 0;
  

 
}



unsigned int senddata(int tag,int state)
{

  
   //The location to go to on the server
   //make sure to keep HTTP/1.0 at the end, this is telling it what type of file it is
   //Ethernet.begin(mac, ip);
   //GET http://server.com/script.php?tag="
   //String location = "/http://www.underthemountain.org/";
   // need to add dynamic
   PROGMEM char bigstring[40];  // enough room for all strings together
   PROGMEM char myString[] = "/inventory/update.php?tag=";
   PROGMEM char myString2[]= "&state=";
   PROGMEM char myString3[]="&id=";
   PROGMEM char myString4[]= " HTTP/1.0";
   char tge[4];
   itoa(tag,tge, 10);
   char ste[4];
   itoa(state,ste, 10);
  
  bigstring[0] = 0;          // start with a null string:
  strcat(bigstring, myString);   // add first string
  strcat(bigstring,tge);   // add first string
  strcat (bigstring, myString3);
  strcat(bigstring,ste);   // add first string
  strcat (bigstring, myString4);

   if(connectAndRead(bigstring)){
     Serial.print("ok");
   }
  
  return 3;
  
}
void get_supplies2(int pge){
   PROGMEM char sz[] = "Here; is some; sample;100;data;1.414;1020; wwwww;wwwwwwwwwww;data;1.414;1020;xxxx;yyyy;100;datadata;1.414;zzzzz;tap;dance;now;happy as a clam;;now;happy as a clam;now";
  
  // String location =String("/inventory/update.php?page="+String(pge));
   //String pageValue = connectAndRead(location);
   //char carray[pageValue.length()];
   //pageValue.toCharArray(carray, sizeof(carray));
   int scroll_state=1;
   int x=0;
   char *p = sz;
   char *str;
   int cnt=0;
   int xx=0;
 
   
   
    while (str = strtok_r(p, ";", &p)){ // delimiter is the semicolon
       //Serial.print("count:");
       //Serial.println(cnt);
       //Serial.println(str);
      if(cnt<4){//header info
        // Header[cnt]=pageValue.substring(loc,delim).toCharArray;
        Serial.print("header:");
        Serial.println(str);
       }
       else{//main info
         if(xx>=scroll_state){//print if at current scroll
            if(xx<=4){
              Serial.print(str);
              Serial.print(" | ");
            }
            else{
              Serial.println(str);
              xx=scroll_state;
            }//if
            
         }//if
         xx++;
       }//else
     //Serial.println("Cnt"+cnt);
     cnt++;    
  } 

}

// Flips the global bit
void changeBit(){
  if (bit == 0) {
    bit = 1;
  } else {
    bit = 0;
  }
}
 
// Writes the bit to the buffer
void writeBit(){
  buffer[i] = bit;
  i++;
}
 
// prints the buffer
/*void printBuffer(unsigned int trk ){
  int j;
  for (j = 0; j < 200; j = j + 1) {
    Serial.println(buffer[j]);
  }
}*/
 
int getStartSentinal(){
  int j;
  int queue[5];
  int sentinal = 0;
 
  for (j = 0; j < 400; j = j + 1) {
    queue[4] = queue[3];
    queue[3] = queue[2];
    queue[2] = queue[1];
    queue[1] = queue[0];
    queue[0] = buffer[j];
 
 /*   if (DEBUG == 1) {
      Serial.print(queue[0]);
      Serial.print(queue[1]);
      Serial.print(queue[2]);
      Serial.print(queue[3]);
      Serial.println(queue[4]);
    }*/
 
    if (queue[0] == 0 && queue[1] == 1 && queue[2] == 0 && queue[3] == 1 && queue[4] == 1) {
      sentinal = j - 4;
      break;
    }
  }
 
  /*if (DEBUG == 1) {
    Serial.print("sentinal:");
    Serial.println(sentinal);
    Serial.println("");
  }*/
 
  return sentinal;
}
 
void decode(boolean trk) {
  int sentinal = getStartSentinal();
  int j;
  int i = 0;
  int k = 0;
  int thisByte[5];
 
  for (j = sentinal; j < 400 - sentinal; j = j + 1) {
    thisByte[i] = buffer[j];
    i++;
    if (i % 5 == 0) {
      i = 0;
      if (thisByte[0] == 0 && thisByte[1] == 0 && thisByte[2] == 0 && thisByte[3] == 0 && thisByte[4] == 0) {
        break;
      }
      printMyByte(thisByte);
    }
  }
 Serial.print("Track:");
 Serial.println(trk);
 //if(trk==0){
    Serial.print("Stripe_Data:");
    String Cardstr="";
    for (k = 0; k < charCount; k = k + 1) {
      Serial.print(cardData[k]);
      Card_Str[k]=cardData[k];
      //Serial.print(Cardstr);
    }
   // if(trk==0){
  //  }
    Serial.println("");
// }
 
}
 
void printMyByte(int thisByte[]) {
  int i;
  for (i = 0; i < 5; i = i + 1) {
    //if (DEBUG == 1) {
      //Serial.print(thisByte[i]);
    //}
}
   /* if (DEBUG == 1) {
      Serial.print("\t");
      Serial.print(decodeByte(thisByte));
      Serial.println("");
    }*/
 
    cardData[charCount] = decodeByte(thisByte);
    charCount ++;
}
 
char decodeByte(int thisByte[]) {
    if (thisByte[0] == 0 && thisByte[1] == 0 && thisByte[2] == 0 && thisByte[3] == 0 && thisByte[4] == 1){
      return '0';
    }
    if (thisByte[0] == 1 && thisByte[1] == 0 && thisByte[2] == 0 && thisByte[3] == 0 && thisByte[4] == 0){
      return '1';
    }
 
    if (thisByte[0] == 0 && thisByte[1] == 1 && thisByte[2] == 0 && thisByte[3] == 0 && thisByte[4] == 0){
      return '2';
    }
 
    if (thisByte[0] == 1 && thisByte[1] == 1 && thisByte[2] == 0 && thisByte[3] == 0 && thisByte[4] == 1){
      return '3';
    }
 
    if (thisByte[0] == 0 && thisByte[1] == 0 && thisByte[2] == 1 && thisByte[3] == 0 && thisByte[4] == 0){
      return '4';
    }
 
    if (thisByte[0] == 1 && thisByte[1] == 0 && thisByte[2] == 1 && thisByte[3] == 0 && thisByte[4] == 1){
      return '5';
    }
 
    if (thisByte[0] == 0 && thisByte[1] == 1 && thisByte[2] == 1 && thisByte[3] == 0 && thisByte[4] == 1){
      return '6';
    }
 
    if (thisByte[0] == 1 && thisByte[1] == 1 && thisByte[2] == 1 && thisByte[3] == 0 && thisByte[4] == 0){
      return '7';
    }
 
    if (thisByte[0] == 0 && thisByte[1] == 0 && thisByte[2] == 0 && thisByte[3] == 1 && thisByte[4] == 0){
      return '8';
    }
 
    if (thisByte[0] == 1 && thisByte[1] == 0 && thisByte[2] == 0 && thisByte[3] == 1 && thisByte[4] == 1){
      return '9';
    }
}

boolean connectAndRead(char* loc){
 //connect to the server

  Serial.println("connecting...");

  if (client.connect()) {
    Serial.println("connected");
    client.print("GET ");
    client.println(loc);
    client.println();

    //Connected - Read the page
    return readPage(); //go and read the output

  }else{
    return false;
  }
}


int readPage(){
//read the page, and capture & return everything between '<' and '>'

  stringPos = 0;
  memset( &inString, 0, 32 ); //clear inString memory

  while(true){

    if (client.available()) {
      char c = client.read();

      if (c == '<' ) { //'<' is our begining character
        startRead = true; //Ready to start reading the part 
      }else if(startRead){

        if(c != '>'){ //'>' is our ending character
          inString[stringPos] = c;
          stringPos ++;
        }else{
          //got what we need here! We can disconnect now
          startRead = false;
          client.stop();
          client.flush();
          Serial.println("disconnecting.");
          return true;

        }

      }
    }

  }

}

On my Windows install, it lives in arduino-0022/hardware/tools/avr/bin/avr-objdump.exe
Also, regular Linux objdump seems to work alright (at least for the high-level stuff like size-of-sections), so if you have GCC for Mac installed, you may get an objdump from there. It may not support disassembly of AVR opcodes, though.

I found it. On a mac you have to "option click" and select show package contents and it is then in a similar path to the one you described. I got some output. However, I am not sure how this helps me analyze my program to see if there is problem that i gobbling up memory or i just need to upgrade my board.

Eric

/Users/ladew/Desktop/ew/Memfix6.cpp.elf:     file format elf32-avr

SYMBOL TABLE:
00800100 l    d  .data	00000000 .data
008003e9 g     O .data	00000002 __malloc_heap_start
008003ef  w    O .data	00000012 _ZTV6Client
00800401  w    O .data	00000012 _ZTV14HardwareSerial
008003eb g     O .data	00000002 __malloc_heap_end
00800414 g       .data	00000000 __data_end
008003ed g     O .data	00000002 _ZN6Client8_srcportE
00800414 g       .data	00000000 _edata
00800100 g       .data	00000000 __data_start
008003e7 g     O .data	00000002 __malloc_margin

I also did

/Users/ladew/Desktop/ew/Memfix6.cpp.elf:     file format elf32-avr

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .data         00000314  00800100  000020da  0000216e  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  1 .text         000020da  00000000  00000000  00000094  2**1
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  2 .bss          00000418  00800414  00800414  00002482  2**0
                  ALLOC
  3 .debug_aranges 00000858  00000000  00000000  00002482  2**0
                  CONTENTS, READONLY, DEBUGGING
  4 .debug_pubnames 00001527  00000000  00000000  00002cda  2**0
                  CONTENTS, READONLY, DEBUGGING
  5 .debug_info   0000cce9  00000000  00000000  00004201  2**0
                  CONTENTS, READONLY, DEBUGGING
  6 .debug_abbrev 0000293f  00000000  00000000  00010eea  2**0
                  CONTENTS, READONLY, DEBUGGING
  7 .debug_line   0000574c  00000000  00000000  00013829  2**0
                  CONTENTS, READONLY, DEBUGGING
  8 .debug_frame  00000e80  00000000  00000000  00018f78  2**2
                  CONTENTS, READONLY, DEBUGGING
  9 .debug_str    000030ae  00000000  00000000  00019df8  2**0
                  CONTENTS, READONLY, DEBUGGING
 10 .debug_loc    00004f14  00000000  00000000  0001cea6  2**0
                  CONTENTS, READONLY, DEBUGGING
 11 .debug_ranges 000008e8  00000000  00000000  00021dba  2**0
                  CONTENTS, READONLY, DEBUGGING