Good practices (Arduino Programming)

@PaulS, I will be sort of calling you out for some info on this one (but would love to hear from the masses too)... Its not a problem to solve (necessarily) but more some good practices to follow while programming...
I have seen many posts in which you speak (...type) about some of the "best methods" to apply while programming. You are a very knowledgeable coder so I would like to maybe hear a few tips from you and other guru's on the forum.
I have adequate programming skills and have done my fair share of Arduino projects but often find myself mixing styles.

Might you share some of your wisdom with us? Thanks in advance!

+1 :slight_smile:

I will start the ball rolling.

Every { and } goes on its own line with no other code.
Code to be executed when an if is true always has { and } around it, even if it is only one line of code.
Give variables appropriate names to indicate their purpose.
Use defines or variables to give pin numbers meaningful names.
Consider putting blocks of code in appropriately named functions to make it easier to test and debug.
Use Auto Format often. Not only does it tidy up the code it points out missing/extra brackets and braces.
Test small sections of code or functions as you go along using appropriate test data, hard coded into variables if necessary.

Pass the popcorn, some of the things you have suggested I've seen argued between even experienced programmers, and fall into the catogory of 'personal preferences'. At least that is the impression I've gotten from hanging around here for several years. :wink:

UKHeliBob:
Every { and } goes on its own line with no other code.

pushes HeliBob off a bridge

How can you get any coding done when all you're doing is scrolling up and down because of all the whitespace?

How can you get any debugging done when you are constantly peering at code to ascertain what code is in what block ?

If you are short of vertical screen space because of the stupid aspect ratios that are being forced on us then turn your monitor 90 degrees, work in portrait mode and take command of your editor, particularly if it allows code collapsing.

CTRL-T does a pretty good job of formatting the code.
Except: Does a poor job job on arrays, spreads them all over the page.
Use the Tabs feature in the IDE to break the code up into scrollable chunks.
I use the Named tab as an intro to keep notes, test status, things to fix, change descriptions. Then:
a_presetup - start of real sketch; #includes, #defines, pin assigments, variable declarations, arrays etc.
b_setup - normal setup code
c_loop - start of loop code
d_loop - more loop if needed
e_end_loop - etc.
f_functions - or would be if I actually wrote any
Code seems to compile alphabetically starting with tab a.

Chagrin:

UKHeliBob:
Every { and } goes on its own line with no other code.

pushes HeliBob off a bridge

How can you get any coding done when all you're doing is scrolling up and down because of all the whitespace?

I like the each and every { and } on a new line. I have been using this from when I was working on a 80*25 line monitor.
So with modern monitors (even on my laptop with a relative bad resolution) with higher resolution there should be no problem.

I still have some hungarian variable naming habits from the good old days as well. It's been watering down due to C++ usage but in the C only days that was a really good practice.

Best regards
Jantje

UKHeliBob:
How can you get any debugging done when you are constantly peering at code to ascertain what code is in what block ?

Proper identation.

UKHeliBob:
How can you get any debugging done when you are constantly peering at code to ascertain what code is in what block ?

I personally prefer like this, and there is (for me) nothing fuzzy about:

if (condition) {
  // do something
  // and another thing
  // and check something else
  while (condition2) {
    // do something else
    // measure something
    // calculate something
  }
}

I really find it annoying if every { and } is on a single blank line. But it's all a matter of personal preference's ofcourse.

i have always heard it is good practice to use camelCase with our function and variable names.

And here on the StyleGuide from the Reference page there are also some other tips which might be useful (even for our little everyday code writing)...

:wink:

  1. Be consistent in your formatting and naming conventions.
  2. Follow the local standard, if any. (In the case of Arduino, format your code the same way that auto-format would format it.)

I think here in the arduino forums, we often fail to stress the importance of breaking up your program into appropriately sized functions, and frequently have loop() with WAY too much code in it...

Be aware of performance issues. Things like Strings, and 64bit math, operator overloading, and calls to elegant libraries, may look simple and clean, but they can't actually magically perform better than more complicated combinations of simpler functions. On the other hand, don't be paranoid about performance, either. "Fast enough" is in fact fast enough, and "if it doesn't matter, it doesn't matter."

Visual structure -- how we 'see' things.

Task: in these two snippets, find the word 'not.'

if (condition) { do something and another thing and check something
else while (condition2) { do not something else  measure something calculate something
}
}
if (condition) {
  do something
  and another thing
  and check something else
  while (condition2) {
    do not something else
    measure something
    calculate something
  }
}

And, in the first snippet, figure out what the 'not' does in -relation- to the entire snippet, how it's affected by what comes before it and how it affects what follows afterward. Obviously this is gibberish code and it doesn't do anything, but the point is that the run-on-code is EXTREMELY difficult to glance at and without explanation -intuitively- understand the flow.

Each logical step or decision should have its own line. Each line is a discrete 'thought.' Run-on code is like reading a run-on sentence.

It's very similar to reading instructions like this:

  1. do this 1b) maybe do this 2) do more of that 3) do the previous item twice more, unless you didn't do 1b.

Rather than...

  1. do this
    1b) maybe do this
  2. do more of that
  3. do the previous item twice more, unless you didn't do 1b.

In the 'sentence' format, I'm reading instruction 3 near the end of the line that references 1b. I have to make a mental note of where I am -horizontally-, look backwards, make a decision about that, then look forward to where I was reading and make another decision based on what I remember waaaay over on the left side of the screen.

...rather than seeing that I'm on -line- 3 (because that's the 'title' of the line,) glance up two lines to 1b and make a decision, then continue at line 3.

Visually, 1b and 3 are...

V
1b

3
^
...this far away vertically, rather than...

----------v---------------------------------------v ...this far away horizontally.

  1. do this 1b) maybe do this 2) do more of that 3) do the previous item twice more, unless you didn't do 1b.

It takes tens of thousand of lines of code to -really- learn how much TIME and AGITA properly structured code -saves-.

About the...
code here....
}
code here...
}
code here...
}
...wait till you've got a chunk of code where those three brackets are on three separate (printed) pages, with maybe another page of code between two of them. It gets 'not fun' reeeal fast.

This is even related to physical control panels, car dashboards, GUI layouts. The effects of many aspects of human visual perception can make something hard to use for no -apparent- reason, unless you know what to look for in the design.

UI is an art and a science, and these lines of text are our interface.

"Be the Code" -- Bill Murray, Caddyshack

Any one Function or more correctly Object method in C++ should be readable on a page of A4..

If its longer then you design is flawed...

About the...
code here....
}
code here...
}
code here...
}
...wait till you've got a chunk of code where those three brackets are on three separate (printed) pages, with maybe another page of code between two of them. It gets 'not fun' reeeal fast

You are making a good case for using functions with meaningful names for your 'code here..' lines to avoid the code spreading vertically.

I started the ball rolling with the first reply in this thread knowing that some of my suggestions would jar with some people.

On the whole there is nothing actually wrong with any style as long as it works for you, but as soon as someone else needs to read and understand your code, or you revisit it some months later then consistent layout, use of functions, and meaningful function and variable naming pay dividends.

There are some conventions that are generally accepted, such as capitals for the names of constants (why ?) but even that is not strictly adhered to in the Arduino IDE. As soon as I used them I wondered why the constants for true and false are lowercase and not uppercase for example. Yes, I know that I can define them for myself.

One thing is for sure. We are all going to differ in our views and we are all correct in our own views on this subject.

How can you get any coding done when all you're doing is scrolling up and down because of all the whitespace?

How do you deal with newbies that do this?

void loop(){



    int useless = analogRead(0);

I'm firmly in the { and } on lines by themselves camp.

Thank you all for your great replies... I was looking for this post for a minute before I (like a putz) saw the "my replies" link. Keep them coming people!

f_functions - or would be if I actually wrote any

More and more I find myself writing functions for basically everything! Makes the loop() neat and tidy. And #defines are HUGE! Makes my code read like plain English.

UKHeliBob:
...but as soon as someone else needs to read and understand your code,

You should check out the Drupal-freaks. There's a whole module that does nothing but check for conformity to module style and structure standards. It's partly for legibility but also for potential module version auto-upgraders. That's the -ultimate- intent, though still a work in progress. It makes sense. If one version is defined and cast in stone, and the next version similarly cast, then an upgrader could perform the upgrade automagically. The current version doesn't some of the work, but not very much, it's a long term goal. Drupal version upgrades are at about 1.5-year intervals, but modules can be so spectacularly difficult to upgrade that authors often don't, or they leave, and so the actual user who NEEDS a particular module -can't- upgrade.

Conformity is also used for tools that pull info out of module definitions for other documentation purposes, test generators, compatibility analysis (with other modules,) and version control.

One thing is for sure. We are all going to differ in our views...

+1

...and we are all correct in our own views on this subject.

Mmmm.... that's a little argumentative. I've never thought and of MY views to be incorrect. Otherwise, why would I have that view? By default, wouldn't that make -your- view incorrect? But I guess since I've agree that we can DIFFER I'll let it slide. :wink: