4

What are some of the best programming practices that can be adopted while coding sketches for Arduino, so that it uses the least memory and performance should not suffer from memory outage, and still the code be robust?

From the link: https://www.arduino.cc/en/Products/Compare

I have learned that the Uno has 32 KB of Flash memory. The maximum available is in the MEGA with 256 KB. I think Uno and Mega are the most widely used by people.

1
  • First off, I'd consider NOT using Arduino library and directly use AVR C library, as Arduino adds a lot of code to simplify programming, but not necessary once you know AVR MCU. This is what I'm trying to achieve in github.com/jfpoilpret/fast-arduino-lib optimized library
    – jfpoilpret
    Nov 30, 2016 at 9:42

2 Answers 2

5

Paul covered the most important points. This answer is intended to be a complement to his.

First, you should keep in mind the general rules, which are more important than the more specific ones. The general rule for saving RAM is: be aware of what you are storing, and do not store anything you do not really need. The general rule for saving flash is: be aware of what you are doing, and do not do anything you do not really need.

Now, a few specific tips:

Use the const qualifier for declaring constants (e.g. const int ledPin = 13;). The compiler will optimize-out the storage of the constant and use immediate addressing instead.

Use PROGMEM for arrays of constants.

Whenever possible, use static memory (globals and static locals) rather than heap allocation (malloc() and new). This will prevent memory fragmentation and make the memory usage more predictable (only the stack holds dynamic memory): you know at compile time, rather than run time, whether you are low in RAM.

For the same reason, prefer C strings (char *) over String objects.

Use the C99 types int8_t and uint8_t whenever 8 bits are enough for your integer variables.

Use the static qualifier for functions that will be used only in the same source file, especially for functions that are called only from one place. This gives the compiler more optimization opportunities.

If you need to optimize, use avr-nm to know what is consuming your precious RAM.

2
  • just out of curiosity @Edgar , is 'const int ledPin = 13' use the same memory size as const char ledPin = 13' ?
    – duck
    Dec 1, 2016 at 6:19
  • @dhimaspw: In my tests, yes, the size and the generated assembly are the same. In both cases, digitalWrite(ledPin, HIGH); compiles to ldi r22, 1 $ ldi r24, 13 $ call digitalWrite. Here, ldi means “load an immediate value into a register”, i.e. the value given as the second argument (1 for HIGH or 13 for ledPin) is part of the instruction itself. Dec 1, 2016 at 8:46
3

Keep in mind that RAM is even less. 32KB is a fair lot of code, since C/C++ is highly efficient. "Don't save **** in RAM."

If you need to load images into a display, save the images on an SD card. And "stream" it to the display. You can read and transmit the bytes one by one, or 10 by 10 or something.

Also, if you need long strings, you can use the "flashStringHelper" to store the string in flash memory. For example: println(F(”Error message: Couldn't connect to server));. By using F() around the string, you save valuable bytes.

Not using Arduino code, but pure AVR-C/C++, can save you a little also. (Will also save the bootloader piece of memory, if you program directly with a programmer.)

If you use Arduino, know how it works. The Arduino serial library uses ~256 or 500 bytes (I believe) as a buffer. You can change this if you need it for other applications.

Keep in mind that your saving technique depends on what resources are low. If you need to do a lot simultaneously, it's better to write non-blocking code.

But also remember: Don't optimize unless it's actually needed! Or, actually set measurable and realistic requirements, optimizing something to be "as fast as possible" can take infinite amounts of time... Run a google search on "premature optimization" as the old folks in the field like to call it.

12
  • 1
    I agree with part premature optimisation is mother of all evils , I have read it before however the point of start looking into optimisation comes when you start seeing low memory warning while uploading to Arduino Nov 30, 2016 at 7:30
  • 1
    @Ciastopiekarz That's complete nonsense, I am afraid. A mis-quote of a partial excerpt from a perfectly good quote. Good software design includes a certain level of optimization right from the start. What is "evil" is spending many man hours doing pointless micro-optimization of small bits of code. When that statement was first quoted "optimization" meant something completely different to what it does today, yet it is still erroneously spouted as a reason to not bother doing any optimization at all, and you end up with Windows applications.
    – Majenko
    Nov 30, 2016 at 10:07
  • Windows application 😳 Nov 30, 2016 at 10:12
  • @Ciastopiekarz Have you ever noticed how things like Office run at about the same speed with a modern version on a 3GHz i7 as old versions ran on a 33MHz 486? They spread to fill the available space, but there hasn't been much change in functionality... Bloat is a blight. Interesting article: ubiquity.acm.org/article.cfm?id=1513451
    – Majenko
    Nov 30, 2016 at 10:27
  • @Ciastopiekarz If you share and explain your sketch (and the debug output, which states how many bytes have been used from what memory) we could try and point out where it could be optimized. Often, it's just the whole approach that is ineffective/inefficient.
    – Paul
    Nov 30, 2016 at 12:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.