Recover RAM memory space

Hello

I have some calculations that I need to do once, each time Arduino starts... or even each new day...
For that, I need to use some 'static long' and 'static floats' arrays to obtain some data.
After that, I have some problems with RAM... so, my question is how can I free memory after use this 'static' arrays ?

I'll appreciate your help
Thanks on advance
Best regards
Pedro Ferrer

malloc and free

Yes, Arrch.. malloc() and free().

Care to expand on that a lottle?

Perhaps you could put them in PROGMEM and only copy them into local variables when you need them? If you put this code in a separate function, the memory used would be released as soon as you return from the function.

Hello

Thanks by the reply.

I'm using now 'free(varA)' - static long varA - each time that I call a function... at the end, before apply 'return', but now PLC crash even earlier that before... :frowning:

The function is used about 105 times before finish the job... so, I'm applying free (varA) 105 times... 105*10 different arrays...(ex: varB, varC...)

Please let me know what can I do
Thanks on advance
Best regards
Pedro Ferrer

You can only free a variable that has been allocated with malloc:

float *myVar = malloc(sizeof(float));

// do something with *myVar - note the * as "myVar" is a pointer, not a variable.

free(myVar);

Hello

Thanks once again.

If I remove 'static' from arrays, the PLC crashes... start do things that I didn't tell him to do...

One of the arrays is this one:

const int SL_coeffs = 49 - 1;

static float SL_multipliers[SL_coeffs+1]={0.9287892, 35999.1376958, 35999.4089666, 35998.7287385, 71998.20261, 71998.4403, 36000.35726, 71997.4812, 32964.4678, -19.441, 445267.1117, 45036.884, 3.1008, 22518.4434, -19.9739, 65928.9345, 9038.0293, 3034.7684, 33718.148, 3034.448, -2280.773, 29929.992, 31556.493, 149.588, 9037.75, 107997.405, -4444.176, 151.771, 67555.316, 31556.08, -4561.54, 107996.706, 1221.655, 62894.167, 31437.369, 14578.298, -31931.757, 34777.243, 1221.999, 62894.511, -4442.039, 107997.909, 119.066, 16859.071, -4.578, 26895.292, -39.127, 12297.536, 90073.778};

Which is the best way to apply 'malloc' on this case?

Thanks on advance
Best regards
Pedro Ferrer

If that is data that never changes, then it can be stored in progmem and you won't use any RAM at all.

I'm not sure of the mechanism on the Arduino. Maybe someone else can point you in the right direction for that?

Enough of this stating the problem one line at a time...

I have some calculations that I need to do once ...

What calculations?

For that, I need to use some 'static long' and 'static floats' arrays to obtain some data.

How do arrays obtain data?

I have some problems with RAM ...

What problems? Be specific.

... how can I free memory after use this 'static' arrays ...

What static arrays?

I'm using now 'free(varA)' - static long varA - each time that I call a function... at the end, before apply 'return', but now PLC crash even earlier that before...

Show this code.

One of the arrays is this one:

const int SL_coeffs = 49 - 1;

static float SL_multipliers[SL_coeffs+1]={0.9287892, 35999.1376958, ...

Are these fixed arrays? That is, they don't ever change?

Then majenko is right. Put them in PROGMEM and don't attempt to free them.

Which is the best way to apply 'malloc' on this case?

You are getting these answers (eg. use malloc) because you haven't shown the whole problem, so we have to guess what you are really doing.

majenko:
Yes, Arrch.. malloc() and free().

Care to expand on that a lottle?

Teach a man to fish...

You can write a function that uses your variables as locals and when it goes out of scope the variables will be deleted. In this case they will be kept on the stack, not the heap.

Hello

I've read some literature about PROGMEM and it seems that floats don't work well...
What do you know about that?

Thanks on advance
Best regards
Pedro Ferrer

I've read some literature about PROGMEM and it seems that floats don't work well..

What you read was garbage.
Post links, please.

Take a look at the AVR lib docs about using program space. There are macros like pgm_read_float_near() that may do what you need.

Even so, it may be easier to store those floats as integers or dwords and then scale them when you read them back into SRAM. Which, it appears, is all AVR lib appears to be doing.

This is how you put them into PROGMEM:

float PROGMEM SL_multipliers[SL_coeffs+1]={
  0.9287892, 35999.1376958, 35999.4089666, 35998.7287385, 71998.20261, 
  // ...  etc.
};

To get them out you can use pgm_read_float etc. but I thought it would be nice to use templates. I've written a small library to do that:

http://www.gammon.com.au/Arduino/PROGMEMAnything.zip

This is what is in it:

// Written by Nick Gammon
// May 2012

#include <Arduino.h>

// returns into item in PROGMEM pointed to by ptr into value
// returns incremented pointer
template <typename T> T * PROGMEMAnything(T * ptr, T& value)
  {
    memcpy_P (&value, ptr, sizeof value);
    return ptr + 1;
  }  // end of PROGMEMAnything
 
// returns value of item in PROGMEM pointed to by ptr 
template <typename T> T PROGMEMAnything(T * ptr)
  {
    T result;
    memcpy_P (&result, ptr, sizeof result);
    return result;
  }  // end of PROGMEMAnything

With that this simple sketch shows how you can pull floats out of PROGMEM:

#include <PROGMEMAnything.h>

const int SL_coeffs  = 49 - 1;
float PROGMEM SL_multipliers[SL_coeffs+1]={
  0.9287892, 35999.1376958, 35999.4089666, 35998.7287385, 
  71998.20261, 71998.4403, 36000.35726, 71997.4812, 
  32964.4678, -19.441, 445267.1117, 45036.884, 3.1008, 
  22518.4434, -19.9739, 65928.9345, 9038.0293, 3034.7684, 
  33718.148, 3034.448, -2280.773, 29929.992, 31556.493, 149.588, 
  9037.75, 107997.405, -4444.176, 151.771, 67555.316, 31556.08, 
  -4561.54, 107996.706, 1221.655, 62894.167, 31437.369, 14578.298, 
  -31931.757, 34777.243, 1221.999, 62894.511, -4442.039, 107997.909, 
  119.066, 16859.071, -4.578, 26895.292, -39.127, 12297.536, 90073.778};

void setup () 
  {
  Serial.begin (115200);
  Serial.println ();
  for (int i = 0; i < SL_coeffs; i++)
    Serial.println (PROGMEMAnything (&SL_multipliers [i]));
  } // end of setup
  
void loop () {}

Output:

0.93
35999.14
35999.41
35998.73
71998.21
71998.44
36000.35
71997.49
32964.47
-19.44
445267.12
45036.88
3.10
22518.44
-19.97
65928.94
9038.03
3034.77
33718.15
3034.45
-2280.77
29929.99
31556.49
149.59
9037.75
107997.41
-4444.18
151.77
67555.32
31556.08
-4561.54
107996.71
1221.66
62894.17
31437.37
14578.30
-31931.76
34777.24
1222.00
62894.51
-4442.04
107997.91
119.07
16859.07
-4.58
26895.29
-39.13
12297.54

Hello

Thanks for all the are participating on this topic.

Nick Gammon, I'll check your *.zip file

(...)

I'm trying to start work with PROGMEM applied on strings, but it happens that the LCD shows crazy characters instead show 'MSG1' ...

I don't know what I'm missing...

//

#include <avr/pgmspace.h>

char textoLCD[15]; //LCD 2X16

const char * SubMenu [] PROGMEM = {
"MSG1" ,
"MSG2" ,
"MSG3",
"MSG4",
"MSG5"
};

strcpy_P(textoLCD, (char*)pgm_read_word(&(SubMenu[0])));

lcd.cursorTo(1,1);

lcd.printIn(textoLCD);

//

Please let me know
I'll appreciate your prompt help
Thanks on advance
Best regards
Pedro Ferrer

Missing? Tell me if you have read this page: PROGMEM - Arduino Reference

And in particular the section "Arrays of strings", which would appear to be relevant.

What's wrong with GoForSmoke's idea of having local variables in a function? I think that's a very clean option.


Rob

Or, you could just use the Flash library. :wink:

Well they still need to be copied from somewhere. I suspect that if you have an array of floats (as in one of the earlier posts) the compiler would first copy it from flash into RAM, and then make another copy onto the stack when the function is invoked.

...

A quick test of this sketch shows:

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

void loop ()
{
const int foo [5] = { 0x1234, 0x5678, 0xabcd, 0x9876, 0x5432 };

for (int i = 0; i < 5; i++)
  Serial.println (foo [i]);
}

With "const" there you get two copies: the original in PROGMEM, and a second one in RAM. The const keyword stops the compiler from making a third copy on the stack.

However remove const and you get three copies, the PROGMEM one, the "initial copy" in RAM, and the copy on the stack.

So really, that hardly saves any memory. You may as well have said:

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

const int foo [5] = { 0x1234, 0x5678, 0xabcd, 0x9876, 0x5432 };

void loop ()
{
for (int i = 0; i < 5; i++)
  Serial.println (foo [i]);
}

The only real way of saving RAM is to use the PROGMEM keyword and drag it out of flash one way or another.