Am I running out of RAM

I’m developing a sketch and as I am not getting near the end, some of the additional features I want seem to cause the Arduino to freeze up when the sketch gets to them. I spent several hours looking for some error in my code, and eventually simplified it down to a very basic:

if (boolVar) { 
client.println("white");
} else {
client.println("green");
}

which would still cause the arduino to lock up when it got to that point. I’m wondering if I am perhaps running out of RAM? I’ve tried optimizing my code as much as I can at this point (changing ints to bytes where possible, etc.), but I still have several Strings (that’s Strings with a capital S), char strings, and several lines of literal text (like client.println(“white”);). Is there any way to check how much RAM is being used at a given point? Is there a list somewhere of what is placed in RAM and when it is automatically flushed from RAM? Are there any scripts/tools that can analyze C code and estimate how much RAM it will use when executed?

PS: I’m running my sketch (which I can post on request) on a Uno R3.

try this

if (boolVar) { 
client.println(F("white"));
} else {
client.println(F("green"));
}

it puts the strings into flash instead of RAM saved my bacon a few times :)

/** Returns the number of bytes currently free in RAM. */
static int FreeRam(void) {
  extern int  __bss_end;
  extern int* __brkval;
  int free_memory;
  if (reinterpret_cast<int>(__brkval) == 0) {
    // if no heap use from end of bss section
    free_memory = reinterpret_cast<int>(&free_memory)
                  - reinterpret_cast<int>(&__bss_end);
  } else {
    // use from top of stack to heap
    free_memory = reinterpret_cast<int>(&free_memory)
                  - reinterpret_cast<int>(__brkval);
  }
  return free_memory;
}

it puts the strings into flash instead of RAM

Can you go into more detail on this (or link me to a [u]reliable[/u] source that documents this)? I have never heard of this, but it sounds interesting.

florinc: I am going to try that code snippet and see what I come up with.

I'm still wondering if there is a resource for microprocessor beginners that explains what uses RAM, and when the Arduino frees that space? Would be helpful to understand just how the RAM is used when I am writing sketches.

or link me to a reliable source that documents this)

The documentation for Serial.print over at the Main Site reference page.

Thanks. As a test, I wrapped one of my client.println() strings in F(). This increased the free RAM by 16, but also increased the sketch size by 70. Will each use of F() result in a similar effect (that is, save X amount of RAM, but use 4.5X additional flash) or should the trade off for additional uses of F() be closer to 1:1?

void setup()
{
  Serial.begin(115200);
  
  Serial.print("One long string of junk");
  Serial.print("And another bunch of characters");
}

void loop()
{
}

Binary sketch size: 1950 bytes (of a 30720 byte maximum)

Changing

  Serial.print("One long string of junk");

to

  Serial.print(F("One long string of junk"));

results in

Binary sketch size: 2020 bytes (of a 30720 byte maximum)

Changing

  Serial.print("And another bunch of characters");

to

  Serial.print(F("And another bunch of characters"));

results in

Binary sketch size: 1974 bytes (of a 30720 byte maximum)

So, no, there is no kind of linear progression (or rationale that I can see).

I don't have an Arduino with me to see what actually happens to SRAM.

Hum. I've done some testing and it appears that the first invocation of F() is the most costly in terms of flash space. After that, the additional uses of F() have a much lower use of flash space compared to the RAM they save. However, there doesn't seem to be a consistent ration. Oh well, I am going through and cleaning up my code now, after which I will try to add my additional features again. If the Arduino continues to lock up, I'll post back.

Thanks for all the help so far.

the first invocation of F() is the most costly in terms of flash space

This doesn’t make much sense.
Flash memory is used for storing the code (program) that the processor runs. Regardless of how many times a function is called, the program remains unchanged (and therefore the amount of “used” flash).

I’m still wondering if there is a resource for microprocessor beginners that explains what uses RAM

The principles for using RAM during program execution in both Harvard and Princeton architectures are the same: a processor needs RAM for the stack (used for function calls, to pass parameters and to create variables defined in functions) and for the heap.

So you can save some memory (RAM) by

  • making fewer nested function calls (reduces the size of the stack), passing fewer arguments (use globals instead);
  • use simple types rather than objects (class instances), wherever possible;
  • use char* rather than String;
  • used #defines instead of declaring variables, wherever possible;
  • reduce the size of buffers.

You got the idea. You never showed your code, so I we are only talking generics here.

This doesn't make much sense.

I'd say it makes pretty good sense. The first invocation will import the method to allow access to flash memory.

I’d say it makes pretty good sense.
The first invocation will import the method to allow access to flash memory.

I don’t understand: are you saying that the program (flash) memory gets changed as soon as some code gets executed?

The first invocation will import the method to allow access to flash memory.

That’s what I was thinking. When compiling the sketch, the code necessary to implement “F()” is only included if “F()” is called. Therefore, the first time it is called not only is the string passed to “F()” included in the binary, but so is the code necessary to handle that string at run time.

My sketch is still locking up, but as I now have plenty of free RAM, I’m starting to think it is an issue with the Ethernet shield. I’ve read some suggestions here http://arduino.cc/forum/index.php/topic,85342.0.html which I will be trying when I can. Unfortunately the second half of that three totally confuses me. I have no idea what patches they are talking about…

I also need to review my code one more time. I think I may have client.close() in the wrong location as well as a few other issues.

However, even with all of the above potential issues, the behavior of my sketch seems unusual. If I call the webpage hosted by the Arduino from my laptop, I get the password form. I enter the password and it takes me to the status page. Here I can click ARM or DISARM (once or several times) and it continues to respond. However, as soon as one of the “zones” is breached (and the pin on the Uno it connects to goes high), subsequent attempts to click ARM/DISARM or refresh the page just sit there, never loading. However, I can occasionally attempt to call the root page (no parameters) and the password form will load again. After logging in, things are once again working as normal until another zone status change. This is what is throwing me off, as I can’t figure out how any of this would cause the server to hang.

I’ll attach my sketch here (with potential bugs as noted above) here in a couple minutes.

Alarm_dev.ino (8.17 KB)

I don't understand: are you saying that the program (flash) memory gets changed as soon as some code gets executed?

No. The compiler notes that the function is needed. The linker imports the function, whether it is used one or a thousand times matters not. Therefore the first usage that the compiler sees will cause the amount of flash needed to increase.

The compiler notes that the function is needed. The linker imports the function, whether it is used one or a thousand times matters not. Therefore the first usage that the compiler sees will cause the amount of flash needed to increase.

That is obvious. Anytime you add a function (that is actually used, although it wasn't the case in the first versions of the Arduino IDE), the code (thus the amount of flash memory) grows.

The issue here is related to the execution of the code, which happens after the code is compiled, linked, uploaded. That's what does not makes sense. All I know is that, once uploaded (to flash memory), the code stays the same regardless of what gets executed. (This is always true for Harvard architecture, not true for Princeton/von Neuman (this is how viruses propagate).)

The issue here is related to the execution of the code, which happens after the code is compiled, linked, uploaded.

The last few replies have been discussing the amount of SRAM and flash used when F() is added to an existing sketch. The only measure of flash usage comes from the linker, so I don't know what issue you are discussing.

Not follow the confusion. An example with made up numbers:

Without using F() at all: Size of sketch=1000 RAM used when running=500 Using F() once: Size of sketch=1100 RAM used when running = 490 Using F() twice: Size of sketch=1150 RAM used when running = 475

After the first use of F(), I (as a beginner who has literally no knowledge of C or the Arduino platform) would expect the ratio between the addition size of the sketch to the decrease in size of RAM used to be constant, but it doesn't seem to be.

If you think my issue is still related to free RAM space, please let me know. Otherwise, I will break off into a separate topic after cleaning up the code to get help on why the HTTP server locks up.

Paul, The confusion may be caused by the use of the word "invocation":

the first invocation of F() is the most costly in terms of flash space

To me, function "invocation" sounds like "runtime function call". That was obviously not the meaning in the quoted sentence above.

florinc: Paul, The confusion may be caused by the use of the word "invocation":

the first invocation of F() is the most costly in terms of flash space

To me, function "invocation" sounds like "runtime function call". That was obviously not the meaning in the quoted sentence above.

Ahh, that would do it.