A question regarding my misunderstanding of Program/Dynamic memory

Hello all

I am programming a Pro mini. Has an Oled screen on I2C.

As usual, I have been sending the text to the screen using the ‘F’ method:

display.println(F(“This is some text”));

I was under the thought that this saved Dynamic memory by robbing Program memory.

But, I have run out of memory at 92% Program storage and 37% Dynamic memory (program doing odd things if I add more code).

So, I took out all the ‘F’ commands and it didn’t decrease the Program memory, just increased the Dynamic memory (and still didn’t run).

How can I overcome this? I have trimmed the code down to the best of my ability (no repeats, variables set to their correct types etc).
It is the text that is killing it, but it is a text heavy routine.

Has to be a Pro mini due to space restrictions. Is there any other small form factor Arduino with more memory? Don’t think there is (maybe a Teensy?)

Is there a better way to say:

** display.setTextSize(2);**
** display.setCursor(23,5);**
** display.print(F(“Some text”));**
** display.display();**

I tried using a single Char print routine and variables for the position, then sending the text to the print routine as required. It actually increased the memory usage.

Could I store the text in an external eeprom?

Any suggestions would be great. Thank you

(deleted)

Err... didn't I say in that post that size was an issue? No room for a Mega

So, I took out all the ‘F’ commands and it didn’t decrease the Program memory,

No, obviously, the string literal has to come from somewhere.

Why external EEPROM?
Have you used all the internal EEPROM?

phoneystark2020:
Has to be a Pro mini due to space restrictions. Is there any other small form factor Arduino with more memory? Don't think there is (maybe a Teensy?)

You'll have to compare the dimensions, but a Teensy 3.2 is pretty small. Performance-wise, it will blow the doors off a Pro Mini.

Yes, a lot of the internal EEprom is allocated for phone number storage

It's looking like a Teensy 3.2 might be the way forward

I think you're barking up the wrong tree. Even at 99.9% Program Memory usage, there should be no instability. You're almost certainly doing something wrong, and clobbering memory with an array running out of bounds, a bad pointer, or other problem in your code.

Regards,
Ray L.

Don't think so. It falters when I try adding more print commands to the Oled.

Just found a 24LC256 lying around. Will throw all the text onto that and retrieve it with the I2C bus.

phoneystark2020:
Don't think so. It falters when I try adding more print commands to the Oled.

It won’t compile (due to out of space), or you get worse instability?

Ray’s right. You can be 100% out of program FLASH with no ill effects at runtime at all, so if program memory is 92% or 100% full has no effect on execution. Program FLASH is not modified or dynamically allocated at runtime.

You’ve added more code, and what SRAM is getting overwritten by whatever errant piece of code is executing to cause the instability can also change as a result of where the compiler decides to place things. That can easily have a knock on effect on how and when the instability manifests itself.

Moving your data to an external EPROM is not a fix for instability. If it works it’s pure luck, and you may well make a change later on and elsewhere that just causes it to come back.

The program memory size does not decrease when you remove the F() macro because the literal text is still stored in program memory, then it is copied into dynamic memory at the very start of execution by some of the code that is added “behind the scenes” before your code.

One thing that may save you some program memory is to look for identical text in the F() statements, and instead of using the F() macro manually declare the string literal in program memory, and refer to it by name in the print() statement. The compiler automatically combines identical string literals when not using the F() macro, and only stores a single copy of each unique string literal, but unfortunately does not do this when using the F() macro.

Is there a better way to say:

display.setTextSize(2);
display.setCursor(23,5);
display.print(F(“Some text”));
display.display();

If there are enough instances of that exact sequence of commands, you may save a bit of program memory by using a function that takes as arguments the text size, cursor position, and string literal, such as:

void displayText(byte textSize, byte cursorColumn, byte cursorRow, const __FlashStringHelper* text) {
  display.setTextSize(textSize);
  display.setCursor(cursorColumn, cursorRow);
  display.print(text);
  display.display();
}

Then call the above function with:

  displayText(2, 23, 5, F("some text"));

Check with the library you are using for the OLED display, that type display can take a considerable amount of dynamic ram for a display buffer, but depending on your use of the display you may be able to use a smaller buffer, or no buffer at all.

Does display.println have an overload that understands about fetching strings from program memory?

Thanks for the suggestions.

Not sure what the issue is then. Can't see any obvious memory problems.

If I take the 'F' out of the print statements, it doesn't perform the code in the correct order, or it just hangs at the start of the routine.

I will check the Oled buffer size.

I have a lot of names/phone numbers in the code at the moment. I'll lift them out and then I can post the code.

There are also the adafruit “itsy bitsy” boards, which I think are the same size as a pro-mini, and have samd21 and samd51 versions with up to 512k of cpu flash, plus an additional 2MB of external flash.

And the Teensy LC…

And a number of esp8266 modules.

PaulMurrayCbr:
Does display.println have an overload that understands about fetching strings from program memory?

If the OP is successfully using the F() macro then it does.

david_2018:
Then call the above function with:

void displayText(byte textSize, byte cursorColumn, byte cursorRow, const __FlashStringHelper* text) {

display.setTextSize(textSize);
  display.setCursor(cursorColumn, cursorRow);
  display.print(text);
  display.display();
}

displayText(2, 23, 5, F("some text"));

This method actually saved me 6% program space. Still can't find any programming or memory errors.
Might try the same method to the graphics rectangles that are used to highlight menu selections - this might save a bit more.

Thank you

It is extremely likely your problem is with dynamic memory, not program memory. Look at your variables and see if you are using int where byte would be sufficient, that can often save a small amount of memory. Also look for any variables that can be made local to a function instead of being defined globally.

phoneystark2020:
Don't think so. It falters when I try adding more print commands to the Oled.

Quite a normal symptom when accessing (probably writing) elements outside the boundaries of an array.

The other one is excessive use of Strings and String concatenation.

I try to stay away from Strings.

I don't think I have any arrays.

phoneystark2020:
I don't think I have any arrays.

You're funny :smiley: