Arduino is freaking out with +19,000 bytes sketches

I am using Arduino Duemilanove (328P).

I came to the conclusion that there is a magic number (19200 bytes), and after that everything is erratic.

At the beginning I thought that I was doing something wrong.

Today I spent almost all day trying to debug this problem and I figure it out that was a problem after 19,200 bytes of the sketch.

I've tried with different 328P's (I have many of those), and always with the same result.

Then, I switch to my Arduino Mega 2560, and all the problems are gone.

There is any known problem with Atmega328P with sketchs bigger than 19,000 bytes?

I am the only one here with this problem?

The problem is much more that your Sketch uses too much SRAM.

That would make sense.

There is any practical way to optimize the SRAM?

Any way to check how much SRAM I am using?

Actually... how the heck Arduino developers check for leaks and all that stuff?

There are two kinds of memory your program must use. The program code goes into flash memory and a 328 will hold a program of 30K+, so it's not your 19K+ code size that is the problem. The second memory is the SRAM memory. This is where all your variables, arrays and the stack data lives.

This SRAM is the memory you are most likely exceeding. The IDE does not report how much sram your program is using up, nor can it accurately tell at compile time as stack usage is a run-time accumulation. The 328p chip has just 2K or SRAM, and the 1280 and 2560 chips have 8K of SRAM space.

There are ways to save on SRAM space. All the string constant characters and other static data can be forced to be located into flash code memory instead of sram memory. See Flash | Arduiniana

Lefty

Looks like working with "float" and "long" doesn't make it easy either.

Thank you guys. Now I know where I have to focus now.

Now, here are some open questions.

How reliable is the Flash.h library? (Flash | Arduiniana)

Methods to detect/fix memory leaks on Arduino?

Is there a way to make the sketch output the current SRAM usage to the serial port for debugging?

How reliable is the Flash.h library? (Flash | Arduiniana)

I've found it to be very reliable.

Methods to detect/fix memory leaks on Arduino?

There is nothing in the Flash library for detecting memory leaks. The purpose of the Flash library is to manage constants (large arrays of constants, string constants). If your Sketch includes many / large constants, the Flash library will help reduce the amount of SRAM your Sketch uses.

UnaClocker:
Is there a way to make the sketch output the current SRAM usage to the serial port for debugging?

I use the following. I have no idea if it works correctly when the heap is activated (malloc and its ilk). Ideally, the value from the "maximum stack depth" should be used to determine if there is an SRAM overrun (heap and stack overlap).

extern unsigned int __bss_end;
extern void *__brkval;

int freeMemory() 
{
  int free_memory;

  if((int)__brkval == 0)
    free_memory = ((int)&free_memory) - ((int)&__bss_end);
  else
    free_memory = ((int)&free_memory) - ((int)__brkval);

  return free_memory;
}

That function works quite well. It will return a point-in-time number of bytes between the top of the stack and the end of the heap. __brkval starts at zero and moves up towards the stack as heap memory is allocated. Using AVR_STACK_POINTER_REG (found in avr/io.h) would be better than taking the address of a local variable near the end of the stack if you wanted to improve that function.

Thanks for the reply. It's good to know the function is generally useful.

Using AVR_STACK_POINTER_REG (found in avr/io.h) would be better

Better in what way?

Using the actual stack pointer address is arguably better than taking the address of an automatic variable as an approximation, but the difference will be minor.

the address of an automatic variable as an approximation

Under what circumstances would the address of "free_memory" be an approximation?

The way that AVR stack frames are built, the automatic variable "free_memory" is in fact at the top of the stack -- I think. But that presumes a bit about the layout of the function activation record. Looking at the actual stack pointer, rather than some offset from the frame pointer, is a more sure-fire way to know where the stack has grown to.

If the code were:

{
  char buffer[SOME_SIZE];
  int free_memory;
  int otherbuffer[SOMEOTHERSIZE];

  /* some code here that uses malloc() */

  if((int)__brkval == 0)
    free_memory = ((int)&free_memory) - ((int)&__bss_end);
  else
    free_memory = ((int)&free_memory) - ((int)__brkval);
  }

   /* use the value of free_memory to decide what to do */

}

Then the size of the other automatics would affect the calculation, where inspecting the actual stack pointer value would not have this effect. None of this matters that much as long as you do the calculation in a function with a simple stack frame, but if you go in-lining it into bigger modules, it could make a difference.

No biggie.