5 tips for Arduino programs


A few random tips for Arduino programmers. We cover saving RAM by storing text in program memory, making your programs easier to read, a technique to avoid being held up in delays, the C++ ternary operator and the watchdog timer.

Putting text strings in program memory saves ram

Write Serial.println(F("Hello World!")); instead of Serial.println("Hello World");

When you write:
Serial.println("Hello World!");
the text ‘Hello World!’ is stored in two places:

  1. Program memory
  2. Random access memory (RAM)

The contents of RAM are lost every time the Arduino is reset, or the power is lost. Program memory is retained through reset and power loss, so at the start of each program, normal strings are copied from program memory into RAM so they can be used by your program.

Many Arduino boards don’t have much RAM though: there’s only 2 kb on the 328 chip used in the Uno, for example. So it is easy to run out of RAM if your program uses many strings or other variables.

When you write:
Serial.println(F("Hello World!"));
the println function gets the text from program memory directly, using a temporary buffer that doesn’t eat up lots of precious RAM.

Constants make programs easier to read

Let’s say you want to annoy your little brother: attach a buzzer to one of the digital outputs of your Arduino and have it beep every few seconds. If the buzzer is attached to port 6, you’ll need to enter the 6 in three places:

  1. setting the pin mode as an output,
  2. turning on the buzzer, and
  3. turning off the buzzer.

Instead, define a constant at the top of your program: const int BuzzerPort = 6;

Now, when you plug the buzzer back into port 7 (after your little brother has ripped the wires out to shut the thing up), you have to change the port in only one place.

Even better, the code is clearer. Straight away we know that digitalWrite(BuzzerPort, HIGH) should turn on a buzzer; with digitalWrite(6, HIGH), we need to remember what is connected to port 6.

So why use a constant instead of just a variable? Wouldn’t int BuzzerPort=6; work just as well?

Sort of: you still only have one number to change when the port changes. But when the ‘variable’ is declared as a constant, the compiler, the tool that turns your program into something the Arduino can use, won’t let you change it accidentally. So if you have const int BuzzerPort=6, and you try to change is value:

The compiler will report an error. So with constants, you can rely on the value never being changed after it is set.

No little brothers were harmed in the writing of this tip.

Delays are boring

The delay function stops your program dead. The classic blink program spends most of its time doing absolutely nothing:

Think of all the great things you could do in that dead time: reading sensors, making noise, driving motors. Delays can be useful, but often they are just a waste of time.

There’s an easy way around it, but we’ll need a few variables:

And the loop becomes:

Ternary Tricks

C++, the language the Arduino platform uses, includes a handy expression for selecting between two values:
(expression) ? (true-value) : (false-value).

This is called a ternary operator…because it has 3 arguments:

  1. (expression), a test which is true or false
  2. (true-value), the result if (expression) is true
  3. (false-value), the result if (expression) is false

It lets you write things like:

Instead of:

It is easy to create code that is hard to follow using this tip. Use it wisely!

Taming runaway programs with the watch-dog timer

The Arduino’s microprocessor includes a watch-dog timer. The watch-dog timer is a sort of dead-man’s switch: if your program doesn’t keep telling the timer all is well, it will blow up the Arduino.

Actually, it just resets the micro: what you do on reset is your own responsibility.

To use the watch-dog timer, you’ll need to:

  1. include a library
  2. enable the watch-dog
  3. tell the watch-dog that all is well

This example should work on any Arduino that uses a microcontroller from Atmel, including the Uno, Mini and Mega. Note, older Mega’s had a problem in their bootloader. If you set the watch-dog timeout too low, you won’t be able to reprogram the Arduino using the serial bootloader. Update to the latest Mega bootloader to fix that.

This program contains a bug which means the countdown will never finish. Can you spot it?

The program will get stuck in the while loop. Because that means wdt_reset() is only called the first time into loop, the watch-dog timer will eventually timeout and the program will get reset.

Got a thorny question on Arduino development? Post your question below and we’ll try to cover it in our next tip.

Posted in Articles
Tags: ,
11 comments on “5 tips for Arduino programs
  1. bask185 says:

    you wanna save space, lose the pinMode, digitalWrite/read and if you wanna use delays, use delayMicroseconds instead. yay 1kB saved. you can use assembly instructions like DDRD 0b00001111, will set pins PD7 to PD4 to input and PD 0 to PD3 outputs, safes around 500 bytes. I used this with attiny chips it didnt work with my UNO yet I think you gotta lose the bootloader for that

    • Paul Martinsen says:

      Good tip. The Arduino IO is easy to use, but it does eat up quite a lot of program space!

  2. Cabbi says:

    Thanks for your tips!

    I have some qestions about your “Note, older Mega’s had a problem in their bootloader. If you set the watch-dog timeout too low, you won’t be able to reprogram the Arduino using the serial bootloader. Update to the latest Mega bootloader to fix that.”
    How can I check my bootloader version?
    What version fixes this bug?

    Thanks,
    Cabbi

    • Phil Rowe says:

      Hi Cabbi, I’m not exactly sure how you check. Best thing is to upgrade using the latest arduino IDE and an in-system programmer (AVRISP). Cheers Phil

Leave a Reply