Please forgive my english, I'm Italian and I'm still learning.
I've been informing myself a lot about how the Arduino manages its different memories, what's stored in them etcetera, because I want to save SRAM usage in any way possible. So, I've got an Arduino UNO rev3, connected to an OLED display (128x64) via SDA and SCL. I'm using the library 'Adafruit_SSD1306' to drive the screen, the 'Adafruit_GFX' and 'Wire'. When initialized, the SSD1306 library allocates about 1K of SRAM as the frame buffer. I've done some testing, and only initializing the screen during setup(), leaves me with 462 bytes of free SRAM, according to the FreeMemory function. Then, I declare an int variable, before setup(), and assign it a value of 0. In order to avoid that it gets 'cancelled out' by teh compiler during the compiling process, I also add 1 to it and (why not) print it on serial, every iteration. Now freeMemory is telling me that there's 492 bytes of free SRAM! I'll paste the code down here:
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
//Declare variables
int v = 0;
Adafruit_SSD1306 display(128, 64, &Wire, -1);
void setup() {
// Initialize the serial port. (allocates serial buffer!)
Serial.begin(9600);
// Initialize the OLED display.
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // (allocates frame buffer!)
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
}
void loop() {
Serial.print(F("freeMemory:"));
Serial.println(freeMemory());
Serial.println(v);
v++;
delay(1000);
}
//FreeMemory Function, from the memoryFree.h library. Prints the available SRAM (the space between Stack and Heap).
#ifdef __arm__
// should use uinstd.h to define sbrk but Due causes a conflict
extern "C" char* sbrk(int incr);
#else // __ARM__
extern char *__brkval;
#endif // __arm__
int freeMemory() {
char top;
#ifdef __arm__
return &top - reinterpret_cast<char*>(sbrk(0));
#elif defined(CORE_TEENSY) || (ARDUINO > 103 && ARDUINO != 151)
return &top - __brkval;
#else // __arm__
return __brkval ? &top - __brkval : &top - __malloc_heap_start;
#endif // __arm__
}
From what I've read, the freeMemory() function is returning the space between the Stack and the Heap. So at first I thought it was heap fragmentation: maybe the space for the int is allocated in a hole. But this doesn't explain why the free memory is increasing.
[This second issue has been solved. Thanks to everyone who helped!]
There's also another issue I can't solve (still related to the memory management). I read that every local variable is held only in Stack, and when the function is returned the space it held is freed up completely. Well, I did some testing, and printing on serial the free SRAM, it looks like that space is not retrieved when the function returns. The space is occupied tho, as the freeMemory(); function now constantly returns 488. That's the code with the function:
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
//Declare variables
int v = 0;
Adafruit_SSD1306 display(128, 64, &Wire, -1);
void setup() {
// Initialize the serial port. (allocates serial buffer!)
Serial.begin(9600);
// Initialize the OLED display.
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // (allocates frame buffer!)
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
}
void loop() {
Serial.print(F("freeMemory:"));
Serial.println(freeMemory());
Serial.println(v);
v++;
func();
delay(1000);
}
void func() {
int loc = random(0,15);
Serial.print(F("(From function)freeMemory:"));
Serial.println(freeMemory());
Serial.println(loc);
return; //Added just to try. Didn't seem to change things.
}
//FreeMemory Function, from the memoryFree.h library. Prints the available SRAM.
#ifdef __arm__
// should use uinstd.h to define sbrk but Due causes a conflict
extern "C" char* sbrk(int incr);
#else // __ARM__
extern char *__brkval;
#endif // __arm__
int freeMemory() {
char top;
#ifdef __arm__
return &top - reinterpret_cast<char*>(sbrk(0));
#elif defined(CORE_TEENSY) || (ARDUINO > 103 && ARDUINO != 151)
return &top - __brkval;
#else // __arm__
return __brkval ? &top - __brkval : &top - __malloc_heap_start;
#endif // __arm__
}
I'm really having some hard time understanding this. Any kind of help is widely appreciated! Thanks is advance
A tiny note: what's my objective? I'm coding some games that run on the tiny OLED display. I want to make at least 2, but I don't want to reuse global variables to save SRAM, it just looks confusing. So what I'm trying to do is to declare as many variables as possible as local, inside a function with its own 'main' loop, which basically runs a game. I'll just need a little selection screen that calls a function with the chosen game. That way, I can declare only the variables I need each time for each game, and when the current game is exited, the space is freed up for the next game, which will declare its own local variables again.