How can I regain stack memory

Hi!
I made this little example to illustrate my problem

#include <MemoryFree.h>

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

void loop() {
  Serial.print("Loop: ");
  Serial.println(freeMemory(), DEC);
  dummy1();
  delay(500);
  dummy2();
  delay(500);
}

void dummy1() {
  Serial.print("Dummy1: ");
  Serial.println(freeMemory(), DEC);
}

void dummy2() {
  Serial.print("Dummy2 has longer text: ");
  Serial.println(freeMemory(), DEC);
}

dummy1 and dummy2 functions reports same amount of memory available (1816). I thought dummy2 would use more memory than dummy1. What I think is happening is that all strings are put in stack memory, otherwise the main loop should report more free memory than it does (1820).
I’m programming an application where I need to control a LCD. In this environment I need to use strings and because the behaviour illustrated above I have a hard time getting the application fit the 2k stack.

Is there any way to program around this?
Is this maybe caused by Serial.print function itself? I could turn my logging off but I have no means of knowing if it helps.

Thanks in advance,

MrZ

If you need to access to mostly static strings this might help:

http://www.arduino.cc/en/Reference/PROGMEM

Eberhard

Thanks wayoda, some strings are static and some I receive from a server so PROGMEM should help. The strings I receive from the server ends up in a buffer like dummy1 below and that space is given back.

#include <MemoryFree.h>

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

void loop() {
  Serial.print("Loop: ");
  Serial.println(freeMemory(), DEC);
  dummy1();
  delay(500);
  dummy2();
  delay(500);
}

void dummy1() {
  char buf[128] = "Dummy1: ";
  Serial.println(buf);
  Serial.println(freeMemory(), DEC);
}

void dummy2() {
  Serial.print("Dummy2 has longer text: ");
  Serial.println(freeMemory(), DEC);
}

In dummy1 the buf[128] is given back but not "Dummy1: " so I guess I could also do

char buf[128] = "";
char[0] = 65;
char[1] = 66;
char[2] = 67;
char[3] = 0;

to print “ABC” without loosing stack space. I do not understand why the compiler have to put it on the stack in the first place.

MrZ

Maybe

void loop() {
  Serial.print("Loop: ");
  Serial.println(freeMemory(), DEC);
  {
    dummy1();
  }
  delay(500);
  {
    dummy2();
  }
  delay(500);
}

?

Yes, PROGMEM did the trick. Whole stack is now given back.
I still would like to understand the reason compiler uses the stack in my previous examples.

Thanks wayoda.

¨
#include <avr/pgmspace.h>
#include <MemoryFree.h>

prog_char string_0[] PROGMEM = "Dummy1: ";
prog_char string_1[] PROGMEM = "Dummy2 has longer text: ";
PROGMEM const char *string_table[] =          
{   
  string_0,
  string_1
};

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

void loop() {
  Serial.print("Loop: ");
  Serial.println(freeMemory(), DEC);
  dummy1();
  delay(500);
  dummy2();
  delay(500);
}

void dummy1() {
  char buf[128];
  strcpy_P(buf, (char*)pgm_read_word(&(string_table[0])));
  Serial.println(buf);
  Serial.println(freeMemory(), DEC);
}

void dummy2() {
  char buf[128];
  strcpy_P(buf, (char*)pgm_read_word(&(string_table[1])));
  Serial.println(buf);
  Serial.println(freeMemory(), DEC);
}

MrZ

That would have been very elegant AlphaBeta :-/

I still would like to understand the reason compiler uses the stack in my previous examples.

Because all strings are loaded into memory when the program starts. These include the strings in dummy1() and dummy2(). Since both strings are in memory at runtime, it doesn’t matter where you decide to find how much free memory you have left, the result will be the same.

When using PROGMEM, strings are stored into the onboard flash and not loaded until you tell them to, thus why you need strcpy_P. Once the variable that contains that string falls out of scope, the stack space it occupied becomes available.