10
\$\begingroup\$

Several times I had some suspicious outputs on the Serial Monitor after uploading code to the Arduino: like eternal output of whitespaces or suddenly cut of strings or scrambled strings.

Because there was no compile error or warning in the Arduino IDE I thought the Arduino was broken but after some tests I found out that not all kinds of errors are caught by the Arduino IDE compiler - especially when assigning variables in a loop for array structures. This seems to crash the Arduino in a short amount of time.

How can I discover errors not displayed by the Arduino IDE?

\$\endgroup\$
10
\$\begingroup\$

The MemoryFree library can help you find risks with memory usage.

Example:

#include <MemoryFree.h>

// On Arduino Duemilanove with ATmega328:
//
// Reported free memory with str commented out:
// 1824 bytes
//
// Reported free memory with str and Serial.println(str) uncommented:
// 1810
//
// Difference: 14 bytes (13 ascii chars + null terminator)

// 14-bytes string
//char str[] = "Hello, world!";


void setup() {
    Serial.begin(115200);
}


void loop() {
    //Serial.println(str);

    Serial.print("freeMemory()=");
    Serial.println(freeMemory());

    delay(1000);
}

I'm unsure if MemoryFree accounts for the stack pointer. If your stack pointer collides with your heap pointer you can experience segmentation faults.

\$\endgroup\$
7
\$\begingroup\$

The most common cause for RAM exhaustion is using the String object or using lots of constant-character arrays (c-style string).

Forutantly IDE 1.0.4 includes a fix to malloc which has plagued the String-object for a very long time.

To reduce the RAM wasted by constant-character strings like:

Serial.print("Hello World");  // This consumes RAM!

You can use the F() macro. This macro will force the character array to stay in PROGMEM. When the array is used, only one byte of memory is consumed.

Serial.print(F("Hello World"));  // Keeps the character-array in PROGMEM

Keep in mind that strings stored in PROGMEM cannot be altered during runtime.

As far as discovery goes, without a debugger or memory controller, you have to use old-fashioned detective techniques to find where the problems occurring.

\$\endgroup\$
  • 1
    \$\begingroup\$ Thank you for the helpful answer! There is really no IDE support memory debugger? \$\endgroup\$ – powtac Apr 30 '13 at 7:33
  • 1
    \$\begingroup\$ This is an old question, but yes, there are proper debuggers for atmel ATmega MCUs. There are no debuggers for arduinos, because the arduino toolchain and "IDE" is basically a toy. \$\endgroup\$ – Connor Wolf Feb 4 '14 at 7:18
  • 1
    \$\begingroup\$ Actually your hint with F() saved us some hundred bytes in RAM! \$\endgroup\$ – powtac Aug 26 '14 at 16:02
  • 1
    \$\begingroup\$ I get a compile error when using F() with strings that contain //. :-( \$\endgroup\$ – powtac Sep 14 '14 at 14:32
  • \$\begingroup\$ I get this compile error on Arduino 1.5.7... \$\endgroup\$ – powtac Sep 14 '14 at 14:45
2
\$\begingroup\$

Looks like you're talking about runtime errors(of the memory leak/segfault type) here.

There isn't any way to discover such errors (unless you comb very carefully through the code) in code that's already written. However, it is quite easy to prevent these from happening while writing the code. Just be very careful when writing loops or recursive calls; ask yourself "could this get out of hand?". If it looks like these is scope for it to "get out of hand", then write code to protect against that.

About segfaults -- just check the boundary values of array indices and you ought to be OK. If you're using pointers, then please be careful with pointer arithmetic.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.