Hello! I've been writing some code for ATmega328p, but I almost filled out the whole flash memory (PROGMEM).
What are the methods I could use to save memory, besides optimizing the code (I'm going to do that as well, but I'm afraid it's not going to be enough)?
A friend of mine told me about replacing functions in asm() directive, but I'm not sure how's that done and what I should look out for. He also told me about xor a, a but I'm not sure where to implement it. I'm also going be removing the bootloader at the end.
Hello! I've been writing some code for ATmega328p, but I almost filled out the whole flash memory (PROGMEM).
What are the methods I could use to save memory, besides optimizing the code (I'm going to do that as well, but I'm afraid it's not going to be enough)?
A friend of mine told me about replacing functions in asm() directive, but I'm not sure how's that done and what I should look out for. He also told me about xor a, a but I'm not sure where to implement it. I'm also going be removing the bootloader at the end.
Compiler and linker already do there best to make very efficient code. Unless you are very good at assembly you will probably not save any flash by writing in asm. So time to find places where you waste memory.
Because filling flash with just code would be a very large program I assume you put lookups or text in it. If it's text, try to split common parts:
Example:
//instead of
const char AnserOneText[] PROGMEM = "The answer is one";
const char AnserTwoText[] PROGMEM = "The answer is two";
const char AnserThreeText[] PROGMEM = "The answer is three";
const char AnserFoutText[] PROGMEM = "The answer is four";
//do
const char AnserText[] PROGMEM = "The answer is ";
const char OneText[] PROGMEM = "one";
const char TwoText[] PROGMEM = "two";
const char ThreeText[] PROGMEM = "three";
const char FoutText[] PROGMEM = "four";
Cross-posting is against the rules of the forum. The reason is that duplicate posts can waste the time of the people trying to help. Someone might spend 15 minutes (or more) writing a detailed answer on this topic, without knowing that someone else already did the same in the other topic.
Repeated cross-posting will result in a timeout from the forum.
In the future, please take some time to pick the forum board that best suits the topic of your question and then only post once to that forum board. This is basic forum etiquette, as explained in the sticky "How to use this forum - please read." post you will find at the top of every forum board. It contains a lot of other useful information. Please read it.
@lukapetko2 Code might be to long for us to optimize. But that leaves you with the primary task of finding out WHAT is taking so much flash? Like I said, I doubt it's the code (logic) itself but something you store.
Often a lot can be gained optimising the code indeed. Find repetitive pieces and place those in a function. Ditch the String class. Avoid sprintf(). Get rid of all floating point calculations (several kB to be gained just there), replace them with integer calculations.
Removing the bootloader will save some 3500 bytes (you get the full 32k = 32768 bytes).
Try MiniCore, if only for its much smaller bootloader. The compiled code in my experience is not always smaller, but just the smaller bootloader tends to make up for that.
Railroader
I can send you the code in PM if you are willing to read it. Is that fine? septillion
yeah, I indeed need to use a lot of strings because I communicate with a GSM module. I do use F(), and I think they only take 2 or 3KB at most. But I'll optimize them as well. Is there a way to see which part of the code is using how much space, or I have to do it manually?
wvmarle
Thanks, I'll do all that! By sprintf(), you mean Serial.print? Also, are floating point calculations only used with floats? Because I mostly use ints anyways.
lukapetko2:
I don't need anyone to optimize the code for me, I just needed some methods for it. Code is too long for anyone to optimize it for me.
This is either a misunderstanding or the wrong attitude, because in fact you are asking the forum to optimize your code, but instead of working with the actual code, you are making yourself a fence, which limits the amount of help the forum can give. I could list a bunch of random things I've come across over the years that have reduced my code, but they may or may not apply to your code. Also, being in a vacuum, they may not have enough context to make sense. I'm not going to spend time trying to create examples and other academic context to bridge from the concrete to the abstract when you can't be bothered to provide that concreteness to this discussion with your actual code.
Perehama
Sorry, man. posting code is the easiest thing I could do, but I didn't want to use up anyone's time reviewing a long code. and spoon feeding me. But, I did post in the previous reply. Sorry for the inconvenience.
Use a floating point operation ONE TIME and you add several kB to your code. Subsequent floating point calculations don't add much, they share the same code algorithm. So if you want to optimise that part, if you use floating point calculations, you have to convert ALL of them into integer only operations.
lukapetko2:
What else is there to do? How much do you estimate I could shrink the code? Right now, it's taking up around 73% of the PROGMEM.
73% only? What's the problem with that? You said you almost filled up the flash. To me that implies 98% or even more...
Looking over it... I would recommend that instead of using Strings, i.e. the Arduino String class object, to concatenate print statements, like AWOL said, use c strings, i.e. a char array, and the sprintf (or snprintf to avoid overwriting your buffer). You are duplicating a lot of variables already existing in the RTC library. If you are going to use the library, use it more, in it's entirety.
wvmarle
The problem is that I'm only halfway done with my code!
It also seems I'll encounter some EEPROM size problems: I'll need to memorize >30 temperature sensor addresses.
So far, it seems I'll have to switch to another MCU. I think ATmega1284 could make this all possible, but I've never used it and I can't buy it in my country.
Perehama
Thanks! I'll do that. Actually, in the end, I won't even need serial, I guess a lot of space could be saved by removing all the Serial.prints. Also, fine with it being pinned I didn't have any malicious intentions.