I use two simple libraries (see 1, 2) I found online for my code on the Arduino Uno, unfortunately I also use ROS and all those libraries take away to much space, when I compile my code I get this error:
Global variables use 2,112 bytes (103%) of dynamic memory, leaving -64 bytes for local variables. Maximum is 2,048 bytes.
I shortened my Strings, but it was not enough. How can I change the code in the libraries to achieve less used memory?
I think I don't understand the concept of global variables completely. For example I changed all double
variables in the libraries to float
variables, but it did not change dynamic memory use at all. How can I use less memory?
3 Answers 3
When you write a program, some memory can be determined in compilation time, due to it's predefinition, (float
and double
in Arduino - not Due model - use 4 bytes each - in Due, double
uses 8 bytes for 64 bit precision).
But there is some memory that only can be known at runtime; where we are talking about objects (or arrays determined by user input). In these cases, programs need to dynamically allocate memory, for which the C++ language integrates the operators new
and delete
. More info at: Dynamic memory.
You should control the creation of objects and arrays (those are created with new
and then deleted with delete
).
If your requirements are greater than the resources of any Arduino (except Arduino Due), you should change to the Due model, which has more memory space and computing power (but changes the 5 V to 3.3 V, be careful).
-
1There is also the Mega 2560, which has the same architecture as the Uno (AVR), but 4 times as much RAM.Edgar Bonet– Edgar Bonet12/09/2016 15:43:01Commented Dec 9, 2016 at 15:43
@jonas I had a similar problem not quite exceeding the limit. One item you can do is move the strings to Flash.
<pgmspace.h>
there is the definition of PSTR which will place the literal in flash
the patternname, which we normaly just use strcpy, we need to use strcpy_P.
strcpy_P states the string will come from Flashmemory and copy it into SRAM space. Once it is in SRAM sapce we can maniputate it all we want.
for example:
setPatternName((char*)PSTR("My PatternName"));
void setPatternName(const char* text) {
memset(patternName, MAX_PATTERN_NAME_LEN + 1, 0 );
strcpy_P(patternName, text);
int length = strlen(patternName);
}
This should have a significant reduction in mem usage.
char buf[50];
char* tm1Txt (byte num){
if (num == 0){strcpy_P(buf, (char*) F("t1 - Задepжka koмaнды xoд"));}
if (num == 1){strcpy_P(buf, (char*) F("t2 - Bpeмя cepвoфиkcaции "));}
if (num == 2){strcpy_P(buf, (char*) F("t3 - Bpeмя дoтягивания "));}
if (num == 3){strcpy_P(buf, (char*) F("t4 - Bpeмя тopмoжeния "));}
if (num == 4){strcpy_P(buf, (char*) F("t5 - Наложениe тормоза "));}
if (num == 5){strcpy_P(buf, (char*) F("t6 - Снятия нагр воздуха "));}
return buf;
}
Explore related questions
See similar questions with these tags.
PID_ATune
which contains a lot of members, including an array of 100double
, i.e. 400 bytes for each instance ofPID_ATune
. Not sure so many double are needed there, but you could first try to reduce this number.