I am working on a simple project on talking to the serial monitor, and my only global variable ("int" type, named "incomingByte") is consuming a lot of memory. There is no problem on running the scketch, but I am not satisfied to have it that way.
When I load it, I receive: "Global variables use 390 bytes (19%) of dinamic memory...". Why is it happening, and how could I fix this?
int incomingByte = 0; //for the incoming serial data
void setup() {
// put your setup code here, to run once:
randomSeed(analogRead(0)); //starts the pseudo-random sequence in a random point
Serial.begin(9600);
//waits for serial initialization to send the messages:
//(Serial) returns false for serial off, and true for serial on. This is inverted with !.
while(!Serial){
;
}
//sending instructions:
Serial.println("Initializing...");
Serial.println(" ");
delay(2000);
Serial.println("Please select an option:");
Serial.println("1 - greetings");
Serial.println("2 - random number");
Serial.println("3 - calculator");
Serial.println(" ");
}
void loop() {
// put your main code here, to run repeatedly:
if(Serial.available() > 0){
incomingByte = Serial.read(); // Serial.read() returns the first byte of incoming data
//recognizing the command received:
if (incomingByte == '1'){
numberOne();
delay(1500);
Serial.println("Waiting; choose another option");
Serial.println(" ");
}
if (incomingByte == '2'){
numberTwo();
delay(1500);
Serial.println("Waiting; choose another option");
Serial.println(" ");
}
if (incomingByte == '3'){
numberThree();
delay(1500);
Serial.println("Waiting; choose another option");
Serial.println(" ");
}
}
}
void numberOne() {
Serial.println("Hello, Vitor! Good to see you!");
}
void numberTwo() {
//sets the random number to be picked between [0, 101[
long randomNum = random(0, 101);
Serial.print("Your random number is: ");
Serial.println(randomNum, DEC);
}
void numberThree(){
Serial.println("Tool not available yet");
}
1 Answer 1
A few things that count towards the "global variables" that you may not think of:
- all your literal strings, unless encapsulated within the
F()
macro; you have quite a few of them - The
Serial
object, including its transmit and receive buffers (157 bytes on an Uno) - The vtable for
HardwareSerial
(that's the classSerial
belongs to, 18 bytes) - The time-keeping variables (9 bytes).
And then, on top of that, there are the actual global variables of your
code, and the static locals which, for the purpose of memory allocation,
are the same as globals. An int
, for example, takes 2 bytes on
AVR and 4 bytes on most other hardware platforms.
Edit: answering the questions in a comment
every single time I call
Serial
it will increase the memory consumption of the code?
I don't quite understand what you mean by "every time":
- Every time you add a reference to
Serial
to a sketch, the linker will add theSerial
object to your compiled code, and the program's RAM consumption will grow by the size of this object. - Within a single sketch, whether
Serial
is used once or many times makes no difference: the object will be instantiated only once.
why does the IDE considers everything that uses RAM as a global variable?
When it says "global variables" it actually means "statically allocated data". It says "global variables" because it is targeted at beginners, and the authors assume beginners would not understand what static allocation means. Globals are the simplest form of static allocation.
is there a difference in consumption between globals and locals?
Yes. Globals get allocated statically, i.e. at compile time. That's why the IDE can report how much space they will consume. Locals (at least non-static locals) get allocated and deallocated on the stack, at run time. Short of running the program in an emulator, it is very hard to predict how much stack space a program will consume, as this will usually depend on run-time events.
-
I understood about the literal strings and the serial consumption, but I couldn't get some points. Firstly, every single time I call
Serial
it will increase the memory consumption of the code? Also, why does the IDE considers everything that uses RAM as a global variable? (is there a difference in consumption between globals and locals?)Vitor Z.– Vitor Z.2022年02月02日 21:35:06 +00:00Commented Feb 2, 2022 at 21:35 -
1@VitorZ.: se expanded answer.Edgar Bonet– Edgar Bonet2022年02月02日 22:18:35 +00:00Commented Feb 2, 2022 at 22:18
-
1Oh now I got it! Your explanation was very useful and complete, thank you. By using your tip in transferring the strings to PROGMEM with F(), I could reduce the SRAM consumption from 19% to only 9%, with just 1% more of Flash usage.Vitor Z.– Vitor Z.2022年02月02日 22:42:22 +00:00Commented Feb 2, 2022 at 22:42
Serial
) also use some of the RAM