Instantiating a class causes lock-up

I have a sketch which uses two external classes. One is mature, and has been used as a library in other sketches, the other is new. I try to set up a single global instance of both of these classes. When I try to access the second class (either class can be second. I have tried changing “order”) in setup, the sketch locks up. I have tried removing the (NULL) constructors, and using begin() methods in setup. I get similar behavior. Even when the ::begin() method has no contents, calling begin() seems to lock the sketch.

I can include code, but it gets rather long.
For testing, I have all code in the sketch area, no user libraries.

Main sketch like:

...
#include "ioUtil1.h"
SerialLineBuffer SerialCmd;  // has default constructor, gets called automaticly
...
#include "HistoryPID.h"
HistoryPID History;
...
void setup()
{
...
  History.begin();  // will cause lock up, comment this out, and we are ok...
}

The constructor for SerialLineBuffer just sets some constants.
The History::begin() has been reduced to

void History::begin() {}

I have chopped up the code to where SerialBuf and History are never actually used. Just trying to instantiate both will cause the lockup. One is OK. SerialBuf has been changed to have no constructor, and be the one with the NULL begin, and it causes the lock-up.

Any idea how to address this? How do you debug such a lock-up?

Since HistoryPID is less mature, it is the more likely culprit. I can post full code.

HistoryPID.cpp (2.47 KB)

HistoryPID.h (1018 Bytes)

ioUtil1.cpp (3.52 KB)

Please use the # button when posting your code, it makes it easier to read.

You are running out of RAM. Class HistoryPID uses 1792 bytes. You haven't supplied ioUtil1.h but I see that class SerialLineBuffer uses an array. You only have 2K of RAM on the Arduino Uno.

You could try changing HISTORY_LEN to a smaller value.

Thanks! That looks correct. I need to learn more about the oddities of memory on the AVR's. I thought there was a 32K limit, but these uControllers have different memory spaces of different size. I'll go read up on this! 32K flash... but 2K RAM? something like that...

2K SRAM (static RAM) for both heap and stack. The stack holds return addresses, copies of the registers for some commands and local variables used in functions. The stack starts at the top of RAM and 'grows' down (it also shrinks as things finish) while the heap starts at the bottom and 'grows' up. Add in dynamic allocation and the heap can get messy real fast. Once the heap overwrites the stack you can be pretty sure that something is not going to return to the place it should, end of the world for your code!

Yes, 2K on a 328. My bet is that you are running out of RAM. This is a common issue and there have been numerous threads regarding this type of heap exhaustion problem. I saw something on playground that might be relevant (http://arduino.cc/playground/Code/AvailableMemory). One thread that might be interesting is this one: http://arduino.cc/forum/index.php/topic,85970.0.html There is a small function you can cut/paste into your sketch that checks for the amount of heap available. This could be useful for debugging, just to confirm that your understanding of the issue is correct, and that your solution is the right one.

Here are some tips on using less RAM:

  • Put string literals and constant data tables in PROGMEM. For string literals, if you use the F() macro then you can print them directly to Serial, lcd etc.
  • Don't create arrays with more elements than you really need.
  • Don't use the String class or dynamic memory allocation, because these cause the heap to become fragmented. Exception: you may allocate dynamic memory in setup() to create your initial objects (and never free them), and you can allocate dynamic memory and then free it in the same function, in a stack-wise manner.
  • Don't use float or double (especially in arrays) where int or unsigned int would do. Similarly, don't use int or unsigned int where you could use uint8_t or another 8-bit type.
  • If all else fails, upgrade to a Mega 2560, which has 8Kb of SRAM.

My Teensy++ has 8K SRAM and with pins to pop right into the breadboard ran me all of $27.