Tips on writing efficient code for Arduino

Hi all,

I'm loving the ease of use of Arduino, however my coding knowledge is limited to a first year programming course, about 10 years ago.

I have a sneaking suspicion that the code for my fairly modest project (solar power mointoring) is quickly going to fill the 32 kilobytes of flash on the Arduino UNO, using my (probably) clumsy approach to coding.

Can anyone point me to some tips on writing efficient code?

Would I be correct in thinking resources titled "optimizing C code for Assembler" would be a good start?

A few quick experiments at the limit of my own knowledge - such as trying to write clever loops results in more efficient C code, but the compiled size basically doesn't change.

Hopefully I won't have to buy a Mega in order to squeeze all that code onto the flash...

Thanks in advance.

Andrew.

32k is a surprising amount of space to fill after its been compiled, and the assembler does a pretty darn good job of squashing it down, where you run into trouble much quicker is the 2k of RAM

use byte instead of int if your numbers never exceed 255, use program memory (the 32k) to store large constants (like text), and if your really up against a wall, use an older version of arduino as every little feature they introduce eats more space in both ram and compiled size.

Osgeld:
32k is a surprising amount of space to fill after its been compiled, and the assembler does a pretty darn good job of squashing it down, where you run into trouble much quicker is the 2k of RAM

use byte instead of int if your numbers never exceed 255, use program memory (the 32k) to store large constants (like text), and if your really up against a wall, use an older version of arduino as every little feature they introduce eats more space in both ram and compiled size.

Thanks a lot for the info. Will be sure to use byte for numbers not exceeding 255.

Potential silly question:

For very large constants, such as, text for an interactive initial setup sequence over RS232, would SD card storage be an option? (just one example)

I'm guessing the short answer to this is "yes". But perhaps someone with more experience would advise against it, due to relative unreliability of SD?

Thanks again.

Andrew.

yes

(cant fit it all in under 32,000 characters?)

Osgeld:
yes

(cant fit it all in under 32,000 characters?)

Excellent! Well, just thinking ahead. So far I have an I2C LCD, 2 x I/V sensors, already consuming 6kb.

To do list:

  • Several more sensors
  • 4 actuators x 2 solar panels
  • A nifty "sky scan" idea to optimize the angle of the panels
  • Xbee wifi to send data to a web server
  • The interactive setup sequence for the users panels, battery info, wifi network
  • Feature creep...
  • And I almost forgot, the SD reader.

Anyway, cheers buddy!

Andrew.

Post some chunks of code you wrote and prepare for critiques. That's best way to learn how to do things. It's like turning in homework for marks. It's the red markings that you value, not only the grade. We can tell you a few tricks but you remember your own mistakes much better :slight_smile:

liudr:
Post some chunks of code you wrote and prepare for critiques. That's best way to learn how to do things. It's like turning in homework for marks. It's the red markings that you value, not only the grade. We can tell you a few tricks but you remember your own mistakes much better :slight_smile:

Indeed :slight_smile: I'm also pleasantly surprised by the "vibe" of the community. It really promotes learning.

Looking forward to seeing some red marks after posting some code. Will try to implement a few more features first.

Andrew.

And don't use floats unless you really need them which is unlikely for a solar monitoring program.


Rob

Will the "sky scan" generate more power than it uses and compensate for the increased complexity?

It may be a lot simpler just to change the angle of panels manually say once a month using an arrangment ike that used to change the angle of sunbeds. One thing you don't want to do is to chase the sun peeking through clouds.

In general computer programs make compromises between size and speed.
A loop will run slower, but take up less memory, than doing away with the loop and explicitly performing all the steps (because you have to increment/decrement and test the loop conditions).

What can be useful is to write your code in the high level language then look at the assembler generated by the compiler. Think about how you might improve the assembler then tweak the high level code so that the compiler produces the assembler you want. This is scraping the bottom of the barrel though as compilers normally produce very efficient output.

Apart from avoiding things that you think are obviously wasteful of resources I would not worry to much until you really know you are going to have a problem.

I would not worry to much until you really know you are going to have a problem.

This. It sounds like you're borrowing trouble that likely doesn't exist. The libraries you'll need for LCD and wifi will eat some of your flash, but to code up the features you've listed so far should be easily plausible in the space you have. Get coding :wink:

Libraries take up code space. When I started with Arduino, I was concerned when really simple sketches used 4-5K, however most of that was the library and not my code. As I added more code, the memory grew slower.

I just did a quick experiment using the Bare_Minimum sketch as a starting point with only 1 or 2 lines of actual code:

Serial.begin() 1.7k

SPI.begin() is 916 bytes

LiquidCrystal 'hello world' is 2.5k, even with everything removed except lcd.begin(); it is nearly 2k

Regards,
Steve

To augment the point about the libraries eating up flash space, the SD card library, as masterful as it is, takes up a good chunk of flash space. It would probably use more flash then your constants will. Also, if you're worried about flash space, then don't put your constants into flash, leave them in RAM. The compiler will optimize your code reasonably well. As others have said, use the smallest types that you need to fit your data.

There is another option; get a bigger chip. There are a bunch of Arduino boards based on the 1284P, which has an ocean of flash.

skyjumper:
To augment the point about the libraries eating up flash space, the SD card library, as masterful as it is, takes up a good chunk of flash space. It would probably use more flash then your constants will. Also, if you're worried about flash space, then don't put your constants into flash, leave them in RAM.

Aha! I was just starting to wonder about that myself.

Thanks for the info. Will experiment with putting them in RAM.

Cheers,

Andrew.

radman:
Will the "sky scan" generate more power than it uses and compensate for the increased complexity?

It may be a lot simpler just to change the angle of panels manually say once a month using an arrangment ike that used to change the angle of sunbeds. One thing you don't want to do is to chase the sun peeking through clouds.

Apart from avoiding things that you think are obviously wasteful of resources I would not worry to much until you really know you are going to have a problem.

To be honest, I'm not sure if it will compensate for energy consumption and complexity :slight_smile:

Your idea about adjusting the angle monthly could well be better.

Also, perhaps just rotating the panels based on time of day could also be much simpler.

Thanks for the comments.

Andrew,

wildbill:

I would not worry to much until you really know you are going to have a problem.

This. It sounds like you're borrowing trouble that likely doesn't exist. The libraries you'll need for LCD and wifi will eat some of your flash, but to code up the features you've listed so far should be easily plausible in the space you have. Get coding :wink:

Yeah. It seems I was thinking along the same lines as a lot of beginners - not realizing that libraries are the main culprits.

Will be having a marathon coding session tonight!

Andrew.

Also, perhaps just rotating the panels based on time of day could also be much simpler.

Time of day and year along with your latitude and longitude will tell you where the sun is, so essentially rotating based on time will do it.
I want build something that points to where the sun is myself, but I keep getting distracted.

Another idea would be to have the panels facing south but static and use moving mirrors or heliostats to reflect additional light onto the panels - that would certainly look cool. Actually cooling the solar panels may make them more efficient perhaps with a heat sink or if there is running water available.

radman:
Time of day and year along with your latitude and longitude will tell you where the sun is, so essentially rotating based on time will do it.
I want build something that points to where the sun is myself, but I keep getting distracted.

Another idea would be to have the panels facing south but static and use moving mirrors or heliostats to reflect additional light onto the panels - that would certainly look cool. Actually cooling the solar panels may make them more efficient perhaps with a heat sink or if there is running water available.

Interesting idea with lots of options for implementation... GPS would be good for time and position, if this project were to function in any location. Add some (or a lot!) of sun positioning data via SD card.

I know that would be much more complex than it needs to be, but I can't help it!

Add some (or a lot!) of sun positioning data via SD card.

Surely from the GPS position and time of day / month, you can get a very good approximation of the position the Sun

AWOL:
Surely from the GPS position and time of day / month, you can get a very good approximation of the position the Sun

I see. Haven't quite got my head around this concept yet... But will not sleep tonight until I do!

Thanks :slight_smile:

Surely from the GPS position and time of day / month, you can get a very good approximation of the position the Sun

Yes, you can calculate it exactly.

The solar panels don't move around so you only need to know latitude and longitude at installation time.
You also need to know the direction of true (not magnetic) north.

A program called SunAlign was written in QBasic by David Williams:
David Williams
P.O. Box 48512
Long Branch P.O.
Toronto, Ontario. M8W 4Y6
Canada

This was converted to c by Marius Gundersen, January 25 2009.
The conversion to C was quite faithful to the structure of the original QBasic program, some variable names were changed.
I think there may have been some bugs in the C code I found.

I was intending converting Gunderson's code to run on the Arduino adding in comments derived from an explanation of the original QBasic program by David Williams, again with minimal alteration. unfortunately I got bogged down on other things.

If somebody wanted to collaborate on getting the thing running I would be interested to hear from them and might pick it up again.
There is enough info here to find the original code and explanation.