Optimizing code to use less Flash Memory and SRAMWhat can I do if I run out of Flash memory or SRAM?Why do sketches take up so much space and memory?Guide to code for multitasking and non blocking timersArduino Program uses less RAM then expected and doesn't runFormatting and code errors?How to use strtok() and strstr() with arduino?Global variables use to much space in the dynamic memoryCan I make existing libraries use external SRAM for the ArduinoUse ESP8266 GPIOs after Flash StartupSegmentation fault and huge SRAM need for Serial.println

What are the cons of stateless password generators?

Unknown indication below upper stave

Can you continue the movement of a Bonus Action Dash granted by Expeditious Retreat if your Concentration is broken mid-move?

How to innovate in OR

How to efficiently shred a lot of cabbage?

Why would anyone ever invest in a cash-only etf?

Should I put my name first, or last in the team members list

Is it unprofessional to mention your cover letter and resume are best viewed in Chrome?

Coworker mumbles to herself when working, how to ask her to stop?

Are all French verb conjugation tenses and moods practical and efficient?

How to prevent a single-element caster from being useless against immune foes?

Why don't short runways use ramps for takeoff?

What is a good example for artistic ND filter applications?

Why didn't Stark and Nebula use jump points with their ship to go back to Earth?

Antonym of "Megalomania"

Patio gate not at right angle to the house

Solve equation using Mathematica

When encrypting twice with two separate keys, can a single key decrypt both steps?

How does Asimov's second law deal with contradictory orders from different people?

Bouncing map back into its bounds, after user dragged it out

On the sensitivity conjecture?

What clothes would flying-people wear?

Why tantalum for the Hayabusa bullets?

How to have poached eggs in "sphere form"?



Optimizing code to use less Flash Memory and SRAM


What can I do if I run out of Flash memory or SRAM?Why do sketches take up so much space and memory?Guide to code for multitasking and non blocking timersArduino Program uses less RAM then expected and doesn't runFormatting and code errors?How to use strtok() and strstr() with arduino?Global variables use to much space in the dynamic memoryCan I make existing libraries use external SRAM for the ArduinoUse ESP8266 GPIOs after Flash StartupSegmentation fault and huge SRAM need for Serial.println






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








1















I'm trying to reduce my sketch size and managed to reduce both SRAM and Flash memory.



From:
1570 SRAM - 32144 Flash memory
To:
644 SRAM - 19458 Flash memory


This are what I've done so far:



Enabling LTO



Using PROGMEM



Dropping string and using char



Dropping bootloader



Using port manipulation



Using registers to declare pins output/input



Removing/Optimizing/Combining; unnecessary/repeated codes in the sketch



Using EEPROM is not an option for me.



What else i can do to take optimization one or two step further?










share|improve this question



















  • 1





    ArduinoIDE is designed to be easy and not fast. To really optimise your code switch to AtmelStudio and write logic on registry level. ArduinoIDE loads many libraries out of box. Some of them are probably unnecessary in your sketch.

    – Filip Franik
    Jul 21 at 9:24







  • 1





    Change the compiler optimization levels. I looks like you can do that within the code, though I've done it by changing the boards.txt file in the past.

    – Gerben
    Jul 21 at 9:32






  • 2





    Also use the right type for (global) variables. Use byte instead of int for variables whose values are always between 0 and 255.

    – Gerben
    Jul 21 at 9:33

















1















I'm trying to reduce my sketch size and managed to reduce both SRAM and Flash memory.



From:
1570 SRAM - 32144 Flash memory
To:
644 SRAM - 19458 Flash memory


This are what I've done so far:



Enabling LTO



Using PROGMEM



Dropping string and using char



Dropping bootloader



Using port manipulation



Using registers to declare pins output/input



Removing/Optimizing/Combining; unnecessary/repeated codes in the sketch



Using EEPROM is not an option for me.



What else i can do to take optimization one or two step further?










share|improve this question



















  • 1





    ArduinoIDE is designed to be easy and not fast. To really optimise your code switch to AtmelStudio and write logic on registry level. ArduinoIDE loads many libraries out of box. Some of them are probably unnecessary in your sketch.

    – Filip Franik
    Jul 21 at 9:24







  • 1





    Change the compiler optimization levels. I looks like you can do that within the code, though I've done it by changing the boards.txt file in the past.

    – Gerben
    Jul 21 at 9:32






  • 2





    Also use the right type for (global) variables. Use byte instead of int for variables whose values are always between 0 and 255.

    – Gerben
    Jul 21 at 9:33













1












1








1








I'm trying to reduce my sketch size and managed to reduce both SRAM and Flash memory.



From:
1570 SRAM - 32144 Flash memory
To:
644 SRAM - 19458 Flash memory


This are what I've done so far:



Enabling LTO



Using PROGMEM



Dropping string and using char



Dropping bootloader



Using port manipulation



Using registers to declare pins output/input



Removing/Optimizing/Combining; unnecessary/repeated codes in the sketch



Using EEPROM is not an option for me.



What else i can do to take optimization one or two step further?










share|improve this question














I'm trying to reduce my sketch size and managed to reduce both SRAM and Flash memory.



From:
1570 SRAM - 32144 Flash memory
To:
644 SRAM - 19458 Flash memory


This are what I've done so far:



Enabling LTO



Using PROGMEM



Dropping string and using char



Dropping bootloader



Using port manipulation



Using registers to declare pins output/input



Removing/Optimizing/Combining; unnecessary/repeated codes in the sketch



Using EEPROM is not an option for me.



What else i can do to take optimization one or two step further?







programming sketch-size






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Jul 21 at 8:16









newbienewbie

14512 bronze badges




14512 bronze badges










  • 1





    ArduinoIDE is designed to be easy and not fast. To really optimise your code switch to AtmelStudio and write logic on registry level. ArduinoIDE loads many libraries out of box. Some of them are probably unnecessary in your sketch.

    – Filip Franik
    Jul 21 at 9:24







  • 1





    Change the compiler optimization levels. I looks like you can do that within the code, though I've done it by changing the boards.txt file in the past.

    – Gerben
    Jul 21 at 9:32






  • 2





    Also use the right type for (global) variables. Use byte instead of int for variables whose values are always between 0 and 255.

    – Gerben
    Jul 21 at 9:33












  • 1





    ArduinoIDE is designed to be easy and not fast. To really optimise your code switch to AtmelStudio and write logic on registry level. ArduinoIDE loads many libraries out of box. Some of them are probably unnecessary in your sketch.

    – Filip Franik
    Jul 21 at 9:24







  • 1





    Change the compiler optimization levels. I looks like you can do that within the code, though I've done it by changing the boards.txt file in the past.

    – Gerben
    Jul 21 at 9:32






  • 2





    Also use the right type for (global) variables. Use byte instead of int for variables whose values are always between 0 and 255.

    – Gerben
    Jul 21 at 9:33







1




1





ArduinoIDE is designed to be easy and not fast. To really optimise your code switch to AtmelStudio and write logic on registry level. ArduinoIDE loads many libraries out of box. Some of them are probably unnecessary in your sketch.

– Filip Franik
Jul 21 at 9:24






ArduinoIDE is designed to be easy and not fast. To really optimise your code switch to AtmelStudio and write logic on registry level. ArduinoIDE loads many libraries out of box. Some of them are probably unnecessary in your sketch.

– Filip Franik
Jul 21 at 9:24





1




1





Change the compiler optimization levels. I looks like you can do that within the code, though I've done it by changing the boards.txt file in the past.

– Gerben
Jul 21 at 9:32





Change the compiler optimization levels. I looks like you can do that within the code, though I've done it by changing the boards.txt file in the past.

– Gerben
Jul 21 at 9:32




2




2





Also use the right type for (global) variables. Use byte instead of int for variables whose values are always between 0 and 255.

– Gerben
Jul 21 at 9:33





Also use the right type for (global) variables. Use byte instead of int for variables whose values are always between 0 and 255.

– Gerben
Jul 21 at 9:33










2 Answers
2






active

oldest

votes


















2














What you can do in addition to the items you mentioned:



SRAM reduction



  • Use the smallest amount of data type for integers, e.g. use an 8 bit data type instead of the default integer, this saves you one byte for every variable. See remark below about types. I made my own types (if not existing) for int32_t, uint32_t, int16_t, uint16_t, int8_t and uint8_t and always use the smallest possible.

  • Use unsigned instead of signed for types that cannot be negative. This might save you one byte if you can prevent using an unsigned byte instead of a signed int because a value can be in range [128..255]. The same for unsigned int instead of signed long.

  • Use bit fields if you use multiple booleans inside a struct or class. Make sure the bit fields are declared consecutively.

  • Pack data in smart structures ... I.e. if you have two variables, where one can be 0..7 and another can also be 0..7, store this together using bit fields (in combination with boolean to bit field above).

  • Prevents float/doubles (see KIIV's comment below), instead:

  • Instead of using a float, multiply the value by the needed accuracy and store it in an integer (if you don't need high accuracy and it fits in the integer type).

  • In case you need a lot of strings to be stored, and those strings do not have characters above 128, you can save 1 bit per byte, of course this means quite some programming work to handle 7 bits 'ASCII' characters.

  • The same, if you have to store a lot of values that can be e.g. 0 to 50, you can use 6 bits instead of 8 bits; you cannot use bit fields, but you can make a smart array and program your own get/set functions to access the 6 bit values.

  • If you use libraries which declare big buffers, try to minimize those buffers, this might cause to copy them and manually change them yourself.

  • Prevent your own buffers to be made global, instead use them as a local variable temporarily when you need them. If you have two of such buffers, you don't have both buffers allocated at the same time; note however, that during execution, that buffer still needs space (so you have to calculate or make a guess/estimation what the maximum stack size will be).

Flash Reduction



  • Don't use duplicated code blocks, but make functions with parameters to differ between the differences of the duplicated code.

  • Instead of lookup tables, create a function that calculates it (if possible). Of course the gain depends on the length of the lookup table and the length of the function.

  • Instead of debugging strings, use numbers.

Both SRAM/Flash Reduction



  • Split your application over multiple MCUs, of course this adds some kind of communication protocol (UART, I2C, SPI).





share|improve this answer






















  • 1





    It's more like: Don't use floats/doubles on architectures without hardware FPU (pretty much just some Cortex M3/M4 boards have it). And for example on AVR based arduinos is double just an alias for float.

    – KIIV
    Jul 22 at 8:45












  • @KIIV Thanks for the comment, didn't know the aliases were the same.k

    – Michel Keijzers
    Jul 22 at 10:35






  • 1





    You can also change to a processor with more SRAM, such as 16kbytes in Atmega1284P. I use that chip in many Arduino-based projects. Dual hardware serial ports,128K flash, 16K sram, and 32 IO.

    – CrossRoads
    Jul 22 at 11:23











  • @CrossRoads I didn't took hardware solutions into account (because of the OP not wanting EEPROM, which is more or less equal than using another MCU). Too bad they don't make a (cheap) Arduino with that MCU, I think the 2 KB SRAM is really a limit for many projects. I'm now making mine with a Mega and using an external EEPROM for storage. I was thinking about an external SPI RAM but I try to make my project without that.

    – Michel Keijzers
    Jul 22 at 11:30






  • 1





    Yep, China is not offering '1284P based boards like they do for Uno, Nano, and Promini. I sell boards, but I get my parts from Digikey & Mouser, so there is some markup there, but it ensures I get parts from a known good supply.

    – CrossRoads
    Jul 22 at 11:36


















0














I'm having flashbacks to my early days as a C programmer in the 80's.



Some thoughts in addition to all of the excellent advice already given ...



  • Depending on how much data your application uses, you may want to
    read / write data to an SD card (or other external storage).
    While there is a certain amount of
    overhead for the libraries, the payoff is you then have virtually
    unlimited storage. This is the equivalent of how we used to store
    data on 5 1/4" diskettes back in the old days.


  • Avoid static variables whenever possible.


  • Keep the scope of a variable as small as possible.


  • As a philosophy you should consider unsigned char to be your
    default data type and only 'upgrade' to a bigger footprint when your
    code requires.






share|improve this answer






















  • 1





    Re “use dynamic memory as much as possible”: You should probably be more specific. When hearing “dynamic memory”, most would think malloc(), which is something to be avoided if you can. I guess you mean “automatic allocation”, i.e. local variables not qualified as static.

    – Edgar Bonet
    Jul 21 at 19:02






  • 1





    Re “re-use variables if you don't need them at the same time”: −1, as this is terrible advice! Please, refrain from encouraging such horribly bad practice. It may have been a reasonable optimization 30 years ago, but since at least 20 years, it has become quite difficult to find a compiler dumb enough to not do this optimization itself. Trust your compiler, and write clear code. Or ditch the compiler if you managed to find one that is that bad.

    – Edgar Bonet
    Jul 21 at 19:02











  • Funny, keeping scope as small as possible is mutualy exclusive with reusing variables. Reusing variables is also error prone, but maybe little bit less error prone than variable declaration and initialization later (often later than it's used)

    – KIIV
    Jul 22 at 8:32











  • Agreed with feedback, updated my answer to reflect that.

    – Rob Sweet
    Jul 22 at 15:35













Your Answer






StackExchange.ifUsing("editor", function ()
return StackExchange.using("schematics", function ()
StackExchange.schematics.init();
);
, "cicuitlab");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "540"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2farduino.stackexchange.com%2fquestions%2f67306%2foptimizing-code-to-use-less-flash-memory-and-sram%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









2














What you can do in addition to the items you mentioned:



SRAM reduction



  • Use the smallest amount of data type for integers, e.g. use an 8 bit data type instead of the default integer, this saves you one byte for every variable. See remark below about types. I made my own types (if not existing) for int32_t, uint32_t, int16_t, uint16_t, int8_t and uint8_t and always use the smallest possible.

  • Use unsigned instead of signed for types that cannot be negative. This might save you one byte if you can prevent using an unsigned byte instead of a signed int because a value can be in range [128..255]. The same for unsigned int instead of signed long.

  • Use bit fields if you use multiple booleans inside a struct or class. Make sure the bit fields are declared consecutively.

  • Pack data in smart structures ... I.e. if you have two variables, where one can be 0..7 and another can also be 0..7, store this together using bit fields (in combination with boolean to bit field above).

  • Prevents float/doubles (see KIIV's comment below), instead:

  • Instead of using a float, multiply the value by the needed accuracy and store it in an integer (if you don't need high accuracy and it fits in the integer type).

  • In case you need a lot of strings to be stored, and those strings do not have characters above 128, you can save 1 bit per byte, of course this means quite some programming work to handle 7 bits 'ASCII' characters.

  • The same, if you have to store a lot of values that can be e.g. 0 to 50, you can use 6 bits instead of 8 bits; you cannot use bit fields, but you can make a smart array and program your own get/set functions to access the 6 bit values.

  • If you use libraries which declare big buffers, try to minimize those buffers, this might cause to copy them and manually change them yourself.

  • Prevent your own buffers to be made global, instead use them as a local variable temporarily when you need them. If you have two of such buffers, you don't have both buffers allocated at the same time; note however, that during execution, that buffer still needs space (so you have to calculate or make a guess/estimation what the maximum stack size will be).

Flash Reduction



  • Don't use duplicated code blocks, but make functions with parameters to differ between the differences of the duplicated code.

  • Instead of lookup tables, create a function that calculates it (if possible). Of course the gain depends on the length of the lookup table and the length of the function.

  • Instead of debugging strings, use numbers.

Both SRAM/Flash Reduction



  • Split your application over multiple MCUs, of course this adds some kind of communication protocol (UART, I2C, SPI).





share|improve this answer






















  • 1





    It's more like: Don't use floats/doubles on architectures without hardware FPU (pretty much just some Cortex M3/M4 boards have it). And for example on AVR based arduinos is double just an alias for float.

    – KIIV
    Jul 22 at 8:45












  • @KIIV Thanks for the comment, didn't know the aliases were the same.k

    – Michel Keijzers
    Jul 22 at 10:35






  • 1





    You can also change to a processor with more SRAM, such as 16kbytes in Atmega1284P. I use that chip in many Arduino-based projects. Dual hardware serial ports,128K flash, 16K sram, and 32 IO.

    – CrossRoads
    Jul 22 at 11:23











  • @CrossRoads I didn't took hardware solutions into account (because of the OP not wanting EEPROM, which is more or less equal than using another MCU). Too bad they don't make a (cheap) Arduino with that MCU, I think the 2 KB SRAM is really a limit for many projects. I'm now making mine with a Mega and using an external EEPROM for storage. I was thinking about an external SPI RAM but I try to make my project without that.

    – Michel Keijzers
    Jul 22 at 11:30






  • 1





    Yep, China is not offering '1284P based boards like they do for Uno, Nano, and Promini. I sell boards, but I get my parts from Digikey & Mouser, so there is some markup there, but it ensures I get parts from a known good supply.

    – CrossRoads
    Jul 22 at 11:36















2














What you can do in addition to the items you mentioned:



SRAM reduction



  • Use the smallest amount of data type for integers, e.g. use an 8 bit data type instead of the default integer, this saves you one byte for every variable. See remark below about types. I made my own types (if not existing) for int32_t, uint32_t, int16_t, uint16_t, int8_t and uint8_t and always use the smallest possible.

  • Use unsigned instead of signed for types that cannot be negative. This might save you one byte if you can prevent using an unsigned byte instead of a signed int because a value can be in range [128..255]. The same for unsigned int instead of signed long.

  • Use bit fields if you use multiple booleans inside a struct or class. Make sure the bit fields are declared consecutively.

  • Pack data in smart structures ... I.e. if you have two variables, where one can be 0..7 and another can also be 0..7, store this together using bit fields (in combination with boolean to bit field above).

  • Prevents float/doubles (see KIIV's comment below), instead:

  • Instead of using a float, multiply the value by the needed accuracy and store it in an integer (if you don't need high accuracy and it fits in the integer type).

  • In case you need a lot of strings to be stored, and those strings do not have characters above 128, you can save 1 bit per byte, of course this means quite some programming work to handle 7 bits 'ASCII' characters.

  • The same, if you have to store a lot of values that can be e.g. 0 to 50, you can use 6 bits instead of 8 bits; you cannot use bit fields, but you can make a smart array and program your own get/set functions to access the 6 bit values.

  • If you use libraries which declare big buffers, try to minimize those buffers, this might cause to copy them and manually change them yourself.

  • Prevent your own buffers to be made global, instead use them as a local variable temporarily when you need them. If you have two of such buffers, you don't have both buffers allocated at the same time; note however, that during execution, that buffer still needs space (so you have to calculate or make a guess/estimation what the maximum stack size will be).

Flash Reduction



  • Don't use duplicated code blocks, but make functions with parameters to differ between the differences of the duplicated code.

  • Instead of lookup tables, create a function that calculates it (if possible). Of course the gain depends on the length of the lookup table and the length of the function.

  • Instead of debugging strings, use numbers.

Both SRAM/Flash Reduction



  • Split your application over multiple MCUs, of course this adds some kind of communication protocol (UART, I2C, SPI).





share|improve this answer






















  • 1





    It's more like: Don't use floats/doubles on architectures without hardware FPU (pretty much just some Cortex M3/M4 boards have it). And for example on AVR based arduinos is double just an alias for float.

    – KIIV
    Jul 22 at 8:45












  • @KIIV Thanks for the comment, didn't know the aliases were the same.k

    – Michel Keijzers
    Jul 22 at 10:35






  • 1





    You can also change to a processor with more SRAM, such as 16kbytes in Atmega1284P. I use that chip in many Arduino-based projects. Dual hardware serial ports,128K flash, 16K sram, and 32 IO.

    – CrossRoads
    Jul 22 at 11:23











  • @CrossRoads I didn't took hardware solutions into account (because of the OP not wanting EEPROM, which is more or less equal than using another MCU). Too bad they don't make a (cheap) Arduino with that MCU, I think the 2 KB SRAM is really a limit for many projects. I'm now making mine with a Mega and using an external EEPROM for storage. I was thinking about an external SPI RAM but I try to make my project without that.

    – Michel Keijzers
    Jul 22 at 11:30






  • 1





    Yep, China is not offering '1284P based boards like they do for Uno, Nano, and Promini. I sell boards, but I get my parts from Digikey & Mouser, so there is some markup there, but it ensures I get parts from a known good supply.

    – CrossRoads
    Jul 22 at 11:36













2












2








2







What you can do in addition to the items you mentioned:



SRAM reduction



  • Use the smallest amount of data type for integers, e.g. use an 8 bit data type instead of the default integer, this saves you one byte for every variable. See remark below about types. I made my own types (if not existing) for int32_t, uint32_t, int16_t, uint16_t, int8_t and uint8_t and always use the smallest possible.

  • Use unsigned instead of signed for types that cannot be negative. This might save you one byte if you can prevent using an unsigned byte instead of a signed int because a value can be in range [128..255]. The same for unsigned int instead of signed long.

  • Use bit fields if you use multiple booleans inside a struct or class. Make sure the bit fields are declared consecutively.

  • Pack data in smart structures ... I.e. if you have two variables, where one can be 0..7 and another can also be 0..7, store this together using bit fields (in combination with boolean to bit field above).

  • Prevents float/doubles (see KIIV's comment below), instead:

  • Instead of using a float, multiply the value by the needed accuracy and store it in an integer (if you don't need high accuracy and it fits in the integer type).

  • In case you need a lot of strings to be stored, and those strings do not have characters above 128, you can save 1 bit per byte, of course this means quite some programming work to handle 7 bits 'ASCII' characters.

  • The same, if you have to store a lot of values that can be e.g. 0 to 50, you can use 6 bits instead of 8 bits; you cannot use bit fields, but you can make a smart array and program your own get/set functions to access the 6 bit values.

  • If you use libraries which declare big buffers, try to minimize those buffers, this might cause to copy them and manually change them yourself.

  • Prevent your own buffers to be made global, instead use them as a local variable temporarily when you need them. If you have two of such buffers, you don't have both buffers allocated at the same time; note however, that during execution, that buffer still needs space (so you have to calculate or make a guess/estimation what the maximum stack size will be).

Flash Reduction



  • Don't use duplicated code blocks, but make functions with parameters to differ between the differences of the duplicated code.

  • Instead of lookup tables, create a function that calculates it (if possible). Of course the gain depends on the length of the lookup table and the length of the function.

  • Instead of debugging strings, use numbers.

Both SRAM/Flash Reduction



  • Split your application over multiple MCUs, of course this adds some kind of communication protocol (UART, I2C, SPI).





share|improve this answer















What you can do in addition to the items you mentioned:



SRAM reduction



  • Use the smallest amount of data type for integers, e.g. use an 8 bit data type instead of the default integer, this saves you one byte for every variable. See remark below about types. I made my own types (if not existing) for int32_t, uint32_t, int16_t, uint16_t, int8_t and uint8_t and always use the smallest possible.

  • Use unsigned instead of signed for types that cannot be negative. This might save you one byte if you can prevent using an unsigned byte instead of a signed int because a value can be in range [128..255]. The same for unsigned int instead of signed long.

  • Use bit fields if you use multiple booleans inside a struct or class. Make sure the bit fields are declared consecutively.

  • Pack data in smart structures ... I.e. if you have two variables, where one can be 0..7 and another can also be 0..7, store this together using bit fields (in combination with boolean to bit field above).

  • Prevents float/doubles (see KIIV's comment below), instead:

  • Instead of using a float, multiply the value by the needed accuracy and store it in an integer (if you don't need high accuracy and it fits in the integer type).

  • In case you need a lot of strings to be stored, and those strings do not have characters above 128, you can save 1 bit per byte, of course this means quite some programming work to handle 7 bits 'ASCII' characters.

  • The same, if you have to store a lot of values that can be e.g. 0 to 50, you can use 6 bits instead of 8 bits; you cannot use bit fields, but you can make a smart array and program your own get/set functions to access the 6 bit values.

  • If you use libraries which declare big buffers, try to minimize those buffers, this might cause to copy them and manually change them yourself.

  • Prevent your own buffers to be made global, instead use them as a local variable temporarily when you need them. If you have two of such buffers, you don't have both buffers allocated at the same time; note however, that during execution, that buffer still needs space (so you have to calculate or make a guess/estimation what the maximum stack size will be).

Flash Reduction



  • Don't use duplicated code blocks, but make functions with parameters to differ between the differences of the duplicated code.

  • Instead of lookup tables, create a function that calculates it (if possible). Of course the gain depends on the length of the lookup table and the length of the function.

  • Instead of debugging strings, use numbers.

Both SRAM/Flash Reduction



  • Split your application over multiple MCUs, of course this adds some kind of communication protocol (UART, I2C, SPI).






share|improve this answer














share|improve this answer



share|improve this answer








edited Jul 22 at 10:34

























answered Jul 21 at 10:58









Michel KeijzersMichel Keijzers

8,0296 gold badges21 silver badges41 bronze badges




8,0296 gold badges21 silver badges41 bronze badges










  • 1





    It's more like: Don't use floats/doubles on architectures without hardware FPU (pretty much just some Cortex M3/M4 boards have it). And for example on AVR based arduinos is double just an alias for float.

    – KIIV
    Jul 22 at 8:45












  • @KIIV Thanks for the comment, didn't know the aliases were the same.k

    – Michel Keijzers
    Jul 22 at 10:35






  • 1





    You can also change to a processor with more SRAM, such as 16kbytes in Atmega1284P. I use that chip in many Arduino-based projects. Dual hardware serial ports,128K flash, 16K sram, and 32 IO.

    – CrossRoads
    Jul 22 at 11:23











  • @CrossRoads I didn't took hardware solutions into account (because of the OP not wanting EEPROM, which is more or less equal than using another MCU). Too bad they don't make a (cheap) Arduino with that MCU, I think the 2 KB SRAM is really a limit for many projects. I'm now making mine with a Mega and using an external EEPROM for storage. I was thinking about an external SPI RAM but I try to make my project without that.

    – Michel Keijzers
    Jul 22 at 11:30






  • 1





    Yep, China is not offering '1284P based boards like they do for Uno, Nano, and Promini. I sell boards, but I get my parts from Digikey & Mouser, so there is some markup there, but it ensures I get parts from a known good supply.

    – CrossRoads
    Jul 22 at 11:36












  • 1





    It's more like: Don't use floats/doubles on architectures without hardware FPU (pretty much just some Cortex M3/M4 boards have it). And for example on AVR based arduinos is double just an alias for float.

    – KIIV
    Jul 22 at 8:45












  • @KIIV Thanks for the comment, didn't know the aliases were the same.k

    – Michel Keijzers
    Jul 22 at 10:35






  • 1





    You can also change to a processor with more SRAM, such as 16kbytes in Atmega1284P. I use that chip in many Arduino-based projects. Dual hardware serial ports,128K flash, 16K sram, and 32 IO.

    – CrossRoads
    Jul 22 at 11:23











  • @CrossRoads I didn't took hardware solutions into account (because of the OP not wanting EEPROM, which is more or less equal than using another MCU). Too bad they don't make a (cheap) Arduino with that MCU, I think the 2 KB SRAM is really a limit for many projects. I'm now making mine with a Mega and using an external EEPROM for storage. I was thinking about an external SPI RAM but I try to make my project without that.

    – Michel Keijzers
    Jul 22 at 11:30






  • 1





    Yep, China is not offering '1284P based boards like they do for Uno, Nano, and Promini. I sell boards, but I get my parts from Digikey & Mouser, so there is some markup there, but it ensures I get parts from a known good supply.

    – CrossRoads
    Jul 22 at 11:36







1




1





It's more like: Don't use floats/doubles on architectures without hardware FPU (pretty much just some Cortex M3/M4 boards have it). And for example on AVR based arduinos is double just an alias for float.

– KIIV
Jul 22 at 8:45






It's more like: Don't use floats/doubles on architectures without hardware FPU (pretty much just some Cortex M3/M4 boards have it). And for example on AVR based arduinos is double just an alias for float.

– KIIV
Jul 22 at 8:45














@KIIV Thanks for the comment, didn't know the aliases were the same.k

– Michel Keijzers
Jul 22 at 10:35





@KIIV Thanks for the comment, didn't know the aliases were the same.k

– Michel Keijzers
Jul 22 at 10:35




1




1





You can also change to a processor with more SRAM, such as 16kbytes in Atmega1284P. I use that chip in many Arduino-based projects. Dual hardware serial ports,128K flash, 16K sram, and 32 IO.

– CrossRoads
Jul 22 at 11:23





You can also change to a processor with more SRAM, such as 16kbytes in Atmega1284P. I use that chip in many Arduino-based projects. Dual hardware serial ports,128K flash, 16K sram, and 32 IO.

– CrossRoads
Jul 22 at 11:23













@CrossRoads I didn't took hardware solutions into account (because of the OP not wanting EEPROM, which is more or less equal than using another MCU). Too bad they don't make a (cheap) Arduino with that MCU, I think the 2 KB SRAM is really a limit for many projects. I'm now making mine with a Mega and using an external EEPROM for storage. I was thinking about an external SPI RAM but I try to make my project without that.

– Michel Keijzers
Jul 22 at 11:30





@CrossRoads I didn't took hardware solutions into account (because of the OP not wanting EEPROM, which is more or less equal than using another MCU). Too bad they don't make a (cheap) Arduino with that MCU, I think the 2 KB SRAM is really a limit for many projects. I'm now making mine with a Mega and using an external EEPROM for storage. I was thinking about an external SPI RAM but I try to make my project without that.

– Michel Keijzers
Jul 22 at 11:30




1




1





Yep, China is not offering '1284P based boards like they do for Uno, Nano, and Promini. I sell boards, but I get my parts from Digikey & Mouser, so there is some markup there, but it ensures I get parts from a known good supply.

– CrossRoads
Jul 22 at 11:36





Yep, China is not offering '1284P based boards like they do for Uno, Nano, and Promini. I sell boards, but I get my parts from Digikey & Mouser, so there is some markup there, but it ensures I get parts from a known good supply.

– CrossRoads
Jul 22 at 11:36













0














I'm having flashbacks to my early days as a C programmer in the 80's.



Some thoughts in addition to all of the excellent advice already given ...



  • Depending on how much data your application uses, you may want to
    read / write data to an SD card (or other external storage).
    While there is a certain amount of
    overhead for the libraries, the payoff is you then have virtually
    unlimited storage. This is the equivalent of how we used to store
    data on 5 1/4" diskettes back in the old days.


  • Avoid static variables whenever possible.


  • Keep the scope of a variable as small as possible.


  • As a philosophy you should consider unsigned char to be your
    default data type and only 'upgrade' to a bigger footprint when your
    code requires.






share|improve this answer






















  • 1





    Re “use dynamic memory as much as possible”: You should probably be more specific. When hearing “dynamic memory”, most would think malloc(), which is something to be avoided if you can. I guess you mean “automatic allocation”, i.e. local variables not qualified as static.

    – Edgar Bonet
    Jul 21 at 19:02






  • 1





    Re “re-use variables if you don't need them at the same time”: −1, as this is terrible advice! Please, refrain from encouraging such horribly bad practice. It may have been a reasonable optimization 30 years ago, but since at least 20 years, it has become quite difficult to find a compiler dumb enough to not do this optimization itself. Trust your compiler, and write clear code. Or ditch the compiler if you managed to find one that is that bad.

    – Edgar Bonet
    Jul 21 at 19:02











  • Funny, keeping scope as small as possible is mutualy exclusive with reusing variables. Reusing variables is also error prone, but maybe little bit less error prone than variable declaration and initialization later (often later than it's used)

    – KIIV
    Jul 22 at 8:32











  • Agreed with feedback, updated my answer to reflect that.

    – Rob Sweet
    Jul 22 at 15:35















0














I'm having flashbacks to my early days as a C programmer in the 80's.



Some thoughts in addition to all of the excellent advice already given ...



  • Depending on how much data your application uses, you may want to
    read / write data to an SD card (or other external storage).
    While there is a certain amount of
    overhead for the libraries, the payoff is you then have virtually
    unlimited storage. This is the equivalent of how we used to store
    data on 5 1/4" diskettes back in the old days.


  • Avoid static variables whenever possible.


  • Keep the scope of a variable as small as possible.


  • As a philosophy you should consider unsigned char to be your
    default data type and only 'upgrade' to a bigger footprint when your
    code requires.






share|improve this answer






















  • 1





    Re “use dynamic memory as much as possible”: You should probably be more specific. When hearing “dynamic memory”, most would think malloc(), which is something to be avoided if you can. I guess you mean “automatic allocation”, i.e. local variables not qualified as static.

    – Edgar Bonet
    Jul 21 at 19:02






  • 1





    Re “re-use variables if you don't need them at the same time”: −1, as this is terrible advice! Please, refrain from encouraging such horribly bad practice. It may have been a reasonable optimization 30 years ago, but since at least 20 years, it has become quite difficult to find a compiler dumb enough to not do this optimization itself. Trust your compiler, and write clear code. Or ditch the compiler if you managed to find one that is that bad.

    – Edgar Bonet
    Jul 21 at 19:02











  • Funny, keeping scope as small as possible is mutualy exclusive with reusing variables. Reusing variables is also error prone, but maybe little bit less error prone than variable declaration and initialization later (often later than it's used)

    – KIIV
    Jul 22 at 8:32











  • Agreed with feedback, updated my answer to reflect that.

    – Rob Sweet
    Jul 22 at 15:35













0












0








0







I'm having flashbacks to my early days as a C programmer in the 80's.



Some thoughts in addition to all of the excellent advice already given ...



  • Depending on how much data your application uses, you may want to
    read / write data to an SD card (or other external storage).
    While there is a certain amount of
    overhead for the libraries, the payoff is you then have virtually
    unlimited storage. This is the equivalent of how we used to store
    data on 5 1/4" diskettes back in the old days.


  • Avoid static variables whenever possible.


  • Keep the scope of a variable as small as possible.


  • As a philosophy you should consider unsigned char to be your
    default data type and only 'upgrade' to a bigger footprint when your
    code requires.






share|improve this answer















I'm having flashbacks to my early days as a C programmer in the 80's.



Some thoughts in addition to all of the excellent advice already given ...



  • Depending on how much data your application uses, you may want to
    read / write data to an SD card (or other external storage).
    While there is a certain amount of
    overhead for the libraries, the payoff is you then have virtually
    unlimited storage. This is the equivalent of how we used to store
    data on 5 1/4" diskettes back in the old days.


  • Avoid static variables whenever possible.


  • Keep the scope of a variable as small as possible.


  • As a philosophy you should consider unsigned char to be your
    default data type and only 'upgrade' to a bigger footprint when your
    code requires.







share|improve this answer














share|improve this answer



share|improve this answer








edited Jul 22 at 15:34

























answered Jul 21 at 16:47









Rob SweetRob Sweet

518 bronze badges




518 bronze badges










  • 1





    Re “use dynamic memory as much as possible”: You should probably be more specific. When hearing “dynamic memory”, most would think malloc(), which is something to be avoided if you can. I guess you mean “automatic allocation”, i.e. local variables not qualified as static.

    – Edgar Bonet
    Jul 21 at 19:02






  • 1





    Re “re-use variables if you don't need them at the same time”: −1, as this is terrible advice! Please, refrain from encouraging such horribly bad practice. It may have been a reasonable optimization 30 years ago, but since at least 20 years, it has become quite difficult to find a compiler dumb enough to not do this optimization itself. Trust your compiler, and write clear code. Or ditch the compiler if you managed to find one that is that bad.

    – Edgar Bonet
    Jul 21 at 19:02











  • Funny, keeping scope as small as possible is mutualy exclusive with reusing variables. Reusing variables is also error prone, but maybe little bit less error prone than variable declaration and initialization later (often later than it's used)

    – KIIV
    Jul 22 at 8:32











  • Agreed with feedback, updated my answer to reflect that.

    – Rob Sweet
    Jul 22 at 15:35












  • 1





    Re “use dynamic memory as much as possible”: You should probably be more specific. When hearing “dynamic memory”, most would think malloc(), which is something to be avoided if you can. I guess you mean “automatic allocation”, i.e. local variables not qualified as static.

    – Edgar Bonet
    Jul 21 at 19:02






  • 1





    Re “re-use variables if you don't need them at the same time”: −1, as this is terrible advice! Please, refrain from encouraging such horribly bad practice. It may have been a reasonable optimization 30 years ago, but since at least 20 years, it has become quite difficult to find a compiler dumb enough to not do this optimization itself. Trust your compiler, and write clear code. Or ditch the compiler if you managed to find one that is that bad.

    – Edgar Bonet
    Jul 21 at 19:02











  • Funny, keeping scope as small as possible is mutualy exclusive with reusing variables. Reusing variables is also error prone, but maybe little bit less error prone than variable declaration and initialization later (often later than it's used)

    – KIIV
    Jul 22 at 8:32











  • Agreed with feedback, updated my answer to reflect that.

    – Rob Sweet
    Jul 22 at 15:35







1




1





Re “use dynamic memory as much as possible”: You should probably be more specific. When hearing “dynamic memory”, most would think malloc(), which is something to be avoided if you can. I guess you mean “automatic allocation”, i.e. local variables not qualified as static.

– Edgar Bonet
Jul 21 at 19:02





Re “use dynamic memory as much as possible”: You should probably be more specific. When hearing “dynamic memory”, most would think malloc(), which is something to be avoided if you can. I guess you mean “automatic allocation”, i.e. local variables not qualified as static.

– Edgar Bonet
Jul 21 at 19:02




1




1





Re “re-use variables if you don't need them at the same time”: −1, as this is terrible advice! Please, refrain from encouraging such horribly bad practice. It may have been a reasonable optimization 30 years ago, but since at least 20 years, it has become quite difficult to find a compiler dumb enough to not do this optimization itself. Trust your compiler, and write clear code. Or ditch the compiler if you managed to find one that is that bad.

– Edgar Bonet
Jul 21 at 19:02





Re “re-use variables if you don't need them at the same time”: −1, as this is terrible advice! Please, refrain from encouraging such horribly bad practice. It may have been a reasonable optimization 30 years ago, but since at least 20 years, it has become quite difficult to find a compiler dumb enough to not do this optimization itself. Trust your compiler, and write clear code. Or ditch the compiler if you managed to find one that is that bad.

– Edgar Bonet
Jul 21 at 19:02













Funny, keeping scope as small as possible is mutualy exclusive with reusing variables. Reusing variables is also error prone, but maybe little bit less error prone than variable declaration and initialization later (often later than it's used)

– KIIV
Jul 22 at 8:32





Funny, keeping scope as small as possible is mutualy exclusive with reusing variables. Reusing variables is also error prone, but maybe little bit less error prone than variable declaration and initialization later (often later than it's used)

– KIIV
Jul 22 at 8:32













Agreed with feedback, updated my answer to reflect that.

– Rob Sweet
Jul 22 at 15:35





Agreed with feedback, updated my answer to reflect that.

– Rob Sweet
Jul 22 at 15:35

















draft saved

draft discarded
















































Thanks for contributing an answer to Arduino Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2farduino.stackexchange.com%2fquestions%2f67306%2foptimizing-code-to-use-less-flash-memory-and-sram%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Get product attribute by attribute group code in magento 2get product attribute by product attribute group in magento 2Magento 2 Log Bundle Product Data in List Page?How to get all product attribute of a attribute group of Default attribute set?Magento 2.1 Create a filter in the product grid by new attributeMagento 2 : Get Product Attribute values By GroupMagento 2 How to get all existing values for one attributeMagento 2 get custom attribute of a single product inside a pluginMagento 2.3 How to get all the Multi Source Inventory (MSI) locations collection in custom module?Magento2: how to develop rest API to get new productsGet product attribute by attribute group code ( [attribute_group_code] ) in magento 2

Category:9 (number) SubcategoriesMedia in category "9 (number)"Navigation menuUpload mediaGND ID: 4485639-8Library of Congress authority ID: sh85091979ReasonatorScholiaStatistics

Magento 2.3: How do i solve this, Not registered handle, on custom form?How can i rewrite TierPrice Block in Magento2magento 2 captcha not rendering if I override layout xmlmain.CRITICAL: Plugin class doesn't existMagento 2 : Problem while adding custom button order view page?Magento 2.2.5: Overriding Admin Controller sales/orderMagento 2.2.5: Add, Update and Delete existing products Custom OptionsMagento 2.3 : File Upload issue in UI Component FormMagento2 Not registered handleHow to configured Form Builder Js in my custom magento 2.3.0 module?Magento 2.3. How to create image upload field in an admin form