Go Down

Topic: 20 Things I've Learned in Years of Programming Arduino. (Read 6460 times) previous topic - next topic

devashareen

Comment the code.

Use meaningful variable names. Not that i,j,x,y,z.

Format the code either K&R or allman. I am a Allman guy. Also use ctrl+t shortcut. [spam link deleted]

Avoid magical numbers (constants on code).

Use macro definitions "#define". [spam link deleted]

Version the progress of a working code. Use git if possible. Have version 1,2,3 or a,b,c whatever you want to use if you do it manual. If something is working so far, keep it!

Implement heartbeat even a simple LED blink every 1 second.

Use F() macro on your serial.printf. Save your RAM for more important tasks. [spam links deleted]

For commercial projects, don't release a code with above 70% program memory. Have enough space for revisions.

Learn to explore the source code of your library on the library folder. Sometimes you to change it on your code.

Don't write super long void loop() function. Learn to write in chucks. Don't be lazy.

Save the code. I have a cloud storage (e.g. dropbox) so that if my laptop/pc collapse I still have a backup copy.

Avoid using global variables if possible. This is a tip a got from software developers.

Don't trust raw values from sensor. Implement a simple filter even a simple average. I love getting the median first before doing any averaging. Much better.

For critical communications, use checksum. It is easy to implement.

Powerbank is a fine power supply as long as it won't sleep.

Implement initialization indicator like beep or led blink pattern. So you know if your code resets.

Learn to use watchdog timer reset.

Enable verbose on IDE. Be aware on warnings and cause of errors.


dale_needham

globals may be bad in larger projects but for lower powered boards they can save a lot of passing variables back and forth. Do think before defining them though.

single letter variables are fine for something like a loop counter thats disposable

the rest is hard to argue with, except the 70% memory one, that depends on what you are doing and how much you have to start with, smaller amounts and you will likely use more of it - not bad as a guide to aim for though

tjsloli

#2
May 20, 2020, 05:03 am Last Edit: May 20, 2020, 05:14 am by CrossRoads
Is it possible for you to help explain more to these things for us because we are very interested in this information?

[We'll see if devashareen responds, or just making a clever post to get some spam links posted. Moderator]

larryd

No technical PMs.
If you are asked a question, please respond with an answer.
If you are asked for more information, please supply it.
If you need clarification, ask for help.

jeffsilverm

Is it possible for you to help explain more to these things for us because we are very interested in this information?

[We'll see if devashareen responds, or just making a clever post to get some spam links posted. Moderator]

I am not the author of that post, but I do teach computer programming to beginners, and I am familiar with what Devashareen wrote, so I am taking the liberty of attempting to answer your question.  I think it's a great question.

Use meaningful variable names. Not that i,j,x,y,z.
Let's say that I need count pulses.  I could use the variable p or the variable pulses or the variable pulse_ctr .  There are also some variable names you should avoid, such as D03 or DO3 for digital output 3.  Use Dout3.  Remember that a computer program can be thought of as a message between you and the computer.  The computer understands exactly what you wrote.  You need to formulate your message so that what you meant and what you wrote are the same thing.


Format the code either K&R or allman. I am a Allman guy.  Also use ctrl+t shortcut
K & R is shorthand for the first book ever written about the C programming language, The C Programming Language.  K&R is an important not only because it more or less defined the C programming language, but it also it is a superb example of how to write a technical document.  K&R invented the computer program hello_world.c, which in turn spawned hello_world.cpp, hello_world.pas, hello_world.sh, hello_world.py, hello_world.java, etc.  Definitely worth purchasing a copy.  Devashareen should have referred you to a Wikipedia article on indentation style.

Avoid magical numbers (constants on code).
Use macro definitions "#define". [spam link deleted]

delay(254)   Does that make sense?  How about, instead:
#define MAX_BUTTON_DOWN_TIME 254                     // if the button is down for more than this time (msec), then increment the counter



Version the progress of a working code. Use git if possible. Have version 1,2,3 or a,b,c whatever you want to use if you do it manual. If something is working so far, keep it!
git is a configuration management tool.  The literature on it is vast, and I won't repeat it here.

Implement heartbeat even a simple LED blink every 1 second.
The power LED tells you that your board has power.  A blinking LED tells you that your CPU is actually executing something.  In thinking about this a little bit, I would make the blink rate faster.

Use F() macro on your serial.printf. Save your RAM for more important tasks.
I make a living writing python software.  Python programs tend to consume a lot of memory, which is not a problem on a 64-bit CPU with 16 GB of physical RAM and a virtual memory with demand-paging memory management system which is driven by a multi-user, multi-processing operating systems such as Darwin, Linux, or Windows.  An Arduino has a few KBytes of RAM, no paging hardware.  The F() macro allows the system to put things that look like data into the instruction memory space, which saves a few bytes here and there.  Which is a great segue into

For commercial projects, don't release a code with above 70% program memory. Have enough space for revisions.
This is argumentative.  If your target machine has 2KBytes of RAM and your program has to fit into that, then you are memory constrained.  If you apply this rule, then you now have 1433 bytes of RAM, which means you are even more memory constrained.  Basically, Devashareen is arguing that your program should assume that more functionality will be added in the future.  Devashareen both right and wrong.  If your program fits into 1433 bytes now, and its future feature set is going to cost 721 bytes, then following that rule saves your bacon.  But if the future feature set costs 1023 bytes, then no matter what constraint you applied, this future feature is not going to happen.  You also have to remember that the more your constrain your software, any constraint, the more your software is going to cost and it might be less reliable.

Learn to explore the source code of your library on the library folder. Sometimes you to change it on your code.
I don't know what this means.

Don't write super long void loop() function. Learn to write in chucks. Don't be lazy.
Don't tell people to not do something.  Be diligent.  Tell people what to do.  Use functions and subroutines.  Compare:

void loop() {
  // put your main code here, to run repeatedly:
  int i,k;
  //  delay(sD);
  // If I had to do this over again, I would reverse the polarity of the LEDs so that
  // everything off would D3 LOW
  digitalWrite(A0,LOW);
  digitalWrite(D3,LOW);
  for (k=0; k<5; k++) {
    for (i=D4; i<=PINS; i++) {
      digitalWrite(i, HIGH);
      delay(flash);
      digitalWrite(i, LOW);
      delay(sD);
    };
    digitalWrite(A0,HIGH);
    digitalWrite(D3, HIGH);
    delay(sD);
  };
};

(full disclosure: I wrote that code) with:

void flash_row() {
   for (i=D4; i<=PINS; i++) {
     digitalWrite(i, HIGH);
     delay(flash);
     digitalWrite(i, LOW);
     delay(sD)
  }
}


void loop() {
 // put your main code here, to run repeatedly:
 int i,k;
 //  delay(sD);
 // If I had to do this over again, I would reverse the polarity of the LEDs so that
 // everything off would D3 LOW
 digitalWrite(A0,LOW);
 digitalWrite(D3,LOW);
 for (k=0; k<5; k++) {
     flash_row()
   };
   digitalWrite(A0,HIGH);
   digitalWrite(D3, HIGH);
   delay(sD);
 };
};

Which do you think is clearer?  Remember, that a program is a message, so clarity is a virtue.  Now, if I became memory constrained, then I might take out that subroutine because it takes some bytes to implement.

Save the code. I have a cloud storage (e.g. dropbox) so that if my laptop/pc collapse I still have a backup copy.
Everything breaks.  Shit happens.  Deal with it.  Backup to the cloud.  Get a free account on github or gitlab, use git, and push to the server frequently.

Avoid using global variables if possible. This is a tip a got from software developers.
Consider the following code snippet:


int innocent_global_variable;
void sub_1(){
  // .... something happens here
};

void sub_2(){
  // .... something happens here
};

void loop() {
  sub_1();
  sub_2();
};

After sub_2 returns, innocent_global_variable has something strange in it.  Did it get that strange value from sub_1 or from sub_2?  This is more of an issue with large programs, but it still is "best practices".

Don't trust raw values from sensor. Implement a simple filter even a simple average. I love getting the median first before doing any averaging. Much better.
An "ideal switch" has infinite resistance when open, zero resistance when closed, and has an instantaneous switching time.  Real switches always have some finite resistance, and it takes time to switch from the high resistance state to the low resistance state.  Worse, the transition from state to state is not linear, and might not even be monotonic.  So when listening to a switch, take several readings before your program decides that the switch has actually changed states.

For critical communications, use checksum. It is easy to implement.
The literature on checksums is vast.  If you are TCP (as in TCP/IP) then you are using a checksum, but TCP does that for you.  If you are running on an Arduino, then you probably are *not* using TCP.  Remember, you are memory constrained and a bad checksum is better than no checksum.

Powerbank is a fine power supply as long as it won't sleep.
You can also use a powerbank as an uninterruptible power supply (UPS).

Implement initialization indicator like beep or led blink pattern. So you know if your code resets.
This a variant of Devashareen's comment about heartbeat.

Learn to use watchdog timer reset.
For critical systems, an excellent idea.  For systems that are not critical or which are simple, this might not be needed.  Nevertheless, learning how to use a watchdog timer reset is a good thing to know. (Full disclosure: I haven't learned
how to use it on an Arduino yet)

Enable verbose on IDE. Be aware on warnings and cause of errors.
Just because something is legal, doesn't mean that it's a good idea.  Just because something is questionable, doesn't mean it's a bad idea.  But if you don't have warnings on, then you won't know what's questionable and you won't make an active effort to investigate if they are bad ideas or clever ideas or both.

RIN67630

I have learned to use the tabs of the arduino IDE to structure my larger code.

a) Copyright and credits (only comments)
b) Parameters and Definitions (users not aware of the program should change only that)

c) Libraries and Variables
d) Functions and Instantiations
e) Setup
f) Menu  (as a function)
g) Data processing (as a function)
h) Display (as a function)
i)  Serial (as a function)
j)  Wireless (as a function)
k) Loop (Scheduler that call the functions)

and finally
x) Read_me  (only comments)
y) Parked code snippets (commented out)

When you edit you can swap easily between the different subparts, frequently functionally related:
you modifiy something in the menu that impacts data processing and the display...,
The editor remembers where you edited last time...

That is really a huge help to manage larger code.

Go Up