Arduino hangs with sketches bigger than 19000 byte

I have an Arduino Duemilanoce with an ATMega 328P but it seems that my sketches are still limited to 19000 bytes. I’m using the ADABOOT bootloader from:
http://www.wulfden.org/TheShoppe/freeduino/ADABOOT.shtml, but i can’t imagine that it takes up 11kb, the hex file is only 6 kb big.

My sketches start to hang in the setup function, when i add a new function or expand an existing one. If a have a watchdog setup, it starts a reset loop, otherwise it just hangs at some point.

I tried to track the problem down and started commenting out code snippets. It seems unrelated to what code i comment out, and only depends on how long the code block is. for example this works:

void commands_printHelpSerial(){
  Serial.println("HELP:");
  Serial.println("valid commands are:");
  Serial.println("help");
  Serial.println("sensorData");
  Serial.println("sensorConfig");
  Serial.println("save");
  Serial.println("load");
  Serial.println("elroSwitch <ad> <dev> <on|off>");
  Serial.println("elroToggle <ad> <dev>");
/*  Serial.println("elroSend <raw>");
  Serial.println("nodeId <id>");
  Serial.println("setSensor <index> <id> <pin>");
  Serial.println("sensors <nr>");
  Serial.println("");
*/
}

Binary size: 18966 bytes

While this doesn’t

void commands_printHelpSerial(){
  Serial.println("HELP:");
  Serial.println("valid commands are:");
  Serial.println("help");
  Serial.println("sensorData");
  Serial.println("sensorConfig");
  Serial.println("save");
  Serial.println("load");
  Serial.println("elroSwitch <ad> <dev> <on|off>");
  Serial.println("elroToggle <ad> <dev>");
  Serial.println("elroSend <raw>");
  Serial.println("nodeId <id>");
/*  Serial.println("setSensor <index> <id> <pin>");
  Serial.println("sensors <nr>");
  Serial.println("");
*/
}

Binary size: 19012 bytes.

I can imagine, that the code size only triggers some primary bug in my code, but since the programm memory and data memory are seperated, i don’t really know what kind of bug that could be. I don’t use any function pointers, except for one interrupt routine and whatever the Ethernet library uses.

Any suggestion on where i should look for the bug?

Bye,
NsN

Edit: I just checked and the same problem happens with an arduino pro with the original firmware on it.

Sounds more like a RAM problem. Cut your prints or put the strings into progmem

Instead of all those Serial.println("string") lines, add this somewhere in one of your headers:

#define DEBUG_PRINT_p(a) { const char *__addr=a; char __c; while((__c=pgm_read_byte(__addr++))) Serial.write(__c); Serial.write('\n'); }

Then do this instead of each Serial.println:

DEBUG_PRINT_p(PSTR("my string"));

There is also a useful little utility function that I found on the forums that attempts to display available RAM based on the assumption that the stack starts at the end of RAM and the heap grows up from the base. It will show a bogus result if the malloc is satisfied by the free list though.

void check_mem()
{
  uint8_t * heapptr, * stackptr;

  stackptr = (uint8_t *)malloc(4);          // use stackptr temporarily
  heapptr = stackptr;                     // save value of heap pointer
  free(stackptr);      // free up the memory again (sets stackptr to 0)
  stackptr =  (uint8_t *)(SP);           // save value of stack pointer

  char buffer[30];
  sprintf(buffer,"%u, %u, %u\n",(unsigned int)heapptr,(unsigned int)stackptr,(unsigned int)(stackptr-heapptr));
  Serial.print(buffer);
}

If you are running out of RAM because you have a lot of strings, I highly recommend Mikal Hart's Flash library: http://arduiniana.org/libraries/flash/

Thank you, it looks like lack of RAM is the really the problem. 2k is really not that much, if you want to have a customizable device with a human interface.

Thanks for the String functions, i will look into those, but as far as i can tell, i will have to rethink my design quite a bit. The strings weere just intented to provide a interface via the serial port, a bigger problem will be the various arrays, that hold configuration data and cache sensor information.

I also suspect, that i have a memory leak somewhere in my code, since the arduino rarely runs for more than 5 minutes, even with most RAM cleared out. Is there any way to get memory leaks without dynamic memory allocation (every variable either declared locally or globally) and no recursive functions?

Bye, NsN

I also suspect, that i have a memory leak somewhere in my code, since the arduino rarely runs for more than 5 minutes, even with most RAM cleared out. Is there any way to get memory leaks without dynamic memory allocation (every variable either declared locally or globally) and no recursive functions?

Add the check_mem() function from the code in my post above and call it say, once every 10 seconds within your loop() function. Monitor the output and if the first two numbers converge and the third gets smaller then you have a RAM leak.

e.g. (untested)

static unsigned long lastcall;

loop()
{
[...]
  unsigned long now=millis();
  if(now-lastcall>10000)
  {
    check_mem();
    lastcall=now;
  }
[...]
}