Arduino Programming

Programming Arduino boards is done via a language called Wiring, which itself is based on Processing and C/C++ languages. We can think of Wiring as providing a simpler abstraction on top of the more complex C/C++ syntax.

Hardware can be programmed directly using a USB connection. Arduino IDE is open source and it supports all the Arduino variants. It's also possible to program the hardware from within a web browser after installing a plugin.

Every Arduino board will have constraints of memory, GPIO pins, and so on. Developers should be aware of these and optimize the code accordingly.

Discussion

  • Which are the basic programming constructs used in Arduino?

    Every Arduino sketch must have two basic constructs:

    • setup(): This is called once when the program starts, that is, when the board is powered up or is reset. This is the place to initialize interfaces, such as GPIO pin modes or baud rate for serial communication.
    • loop(): This is called repeatedly and is the place for the main code. This is equivalent to while (1) {…} C code.

    For digital IO, we can use digitalRead() and digitalWrite(). Since a GPIO pin can be either input or output, it should first be setup using pinMode(). For analogue IO, we can use analogRead() and analogWrite().

    Like in C/C++, control structures in Arduino include if-else, switch-case, for loops, do-while, break and continue.

    Data types common in C language are available but there's also String class for easier manipulation of strings. Serial and Stream are also useful classes.

    There are built-in math functions, timing functions, random number generation, bit-level operation, and interrupt processing. All of these are documented in the Arduino Reference.

  • What are the main features of the Arduino IDE?
    Screenshot of the Arduino IDE with annotations. Source: Devopedia 2019.
    Screenshot of the Arduino IDE with annotations. Source: Devopedia 2019.

    Arduino programs are called sketches. Arduino IDE is more than a code editor for a sketch. It does syntax highlighting on the code. It includes a number of simple examples to learn programming. Examples are accessible via File→Examples menu. From the IDE, we can verify the sketch and upload the binary to the target hardware. Any errors in this process are shown to the user.

    The IDE can target all hardware variants. This selection is done via Tools→Board menu. What's more, we can use the Boards Manager to install newer boards or update to newer versions of board libraries. Likewise, developers have easy access to hundreds of third-party libraries or install custom libraries from a Zip file. This is done via menu Sketch→Include-Library.

    To monitor serial communications, there's Serial Monitor and Serial Plotter. If IoT data is being sent, Serial Plotter's visualization makes it easy to see what's happening.

    We also mention that there are alternatives to the Arduino IDE for programming Arduino boards. Some names are PlatformIO, Eclipse Arduino and Atmel Studio.

  • How can I make the best use of limited memory resources on the Arduino?
    Dynamic allocation can result in heap memory fragmentation. Source: Earl 2013.
    Dynamic allocation can result in heap memory fragmentation. Source: Earl 2013.

    Arduino Uno has only 2KB of SRAM. This means that not a lot of variables can be held in memory, particularly long strings. If SRAM is required for processing data, try offloading the processing to the cloud or another computer/device. If the range of your data can fit within a byte, use byte data type rather than two bytes of int. Use String.reserve() to avoid memory fragmentation. Prefer local to global variables.

    Using PROGMEM keyword as part of data declaration, we can tell the compiler to store data in Flash. Using the macro pgm_read_byte_near(), we can read a byte from Flash. Similar macros exist for other data types: word, dword, float and ptr. If a string is defined inline, then the F() is useful to store it in Flash.

    Let's note that the const keyword has read-only semantics, particularly useful for passing function arguments. It's not meant to tell the compiler where to store the data.

  • What exactly is Software Serial and why do we need it?

    Serial communications can be controlled using Serial class. This relies on the underlying UART hardware that's part of the microcontroller. Arduino Uno has one serial interface on pins 0 and 1. Due and Mega have four serial interfaces. What if we want another serial interface on the Uno? This is where Software Serial becomes useful.

    Serial communications can be implemented on any pair of digital pins using software. We don't have to write low-level code to do this since third-party libraries are available. SoftwareSerial is available in Arduino IDE by default. The main disadvantage is that if multiple software serial interfaces are used, only one can receive data at a time. Speeds are also limited compared to UART. AltSoftSerial is an alternative but it has other limitations.

    Either UART or software, serial interface operates at either 5V or 3.3V depending on the Arduino board. Don't connect them directly to RS232 serial port that operates at +-12V. Use a USB-to-serial adaptor in between.

  • How do I program the Arduino for analogue input?

    For analogue input, there's analogRead() function. Arduino Uno uses a 10-bit Analogue-to-Digital Converter (ADC). Since Uno runs on 5V, this implies that the ADC resolution is 5V/1024 = 4.88mV. It's possible to improve the resolution by sacrificing range. For example, calling analogReference(INTERNAL) sets the ADC reference to 1.1V and improves resolution to 1.1V/1024 = 1.07mV. Uno WiFi Rev2 board has a default reference of 0.55V.

    Due, Zero and MKR Family boards use 3.3V reference and 12-bit ADC. Thus, their resolution is at 0.806mV. However, they default to 10-bit ADC and this can be changed using analogReadResolution(). It's interesting that this function can be used to specify a lower resolution (least significant bits are discarded) or a higher resolution (extra bits are zero-padded).

    An external reference via the AREF pin can also be used and selected using analogReference(EXTERNAL). It's important to call this before calling analogRead(). The input to AREF must also respect the allowed voltage range.

  • How do I program the Arduino for analogue output?

    On most Arduino boards, analogue output is not actually a continuous signal but rather a stream of digital pulses called Pulse Width Modulation (PWM). MKR and Zero boards are capable of true analogue on pin DAC0. Due can do this on pins DAC0 and DAC1.

    For both PWM and true analogue, the relevant API to call is analogWrite(). Arduino Uno has PWM on pins 3, 10 and 11 at 490Hz and pins 5 and 6 at 980Hz. On Due, twelve pins can do PWM at 1000Hz.

    PWM is generated from timers. For example, ATmega328P used in the Uno has three timers. These can be used in one of two modes: Fast PWM or Phase-Correct PWM. However, these are low-level details not exposed via analogWrite().

    Called Software PWM, it's possible to generate PWM waveforms on digital pins. This approach is called bit banging. With this, we can also control the frequency of the pulses. The problem with Software PWM is that interrupts will affect timing, resulting in jitter. Another problem is that processor is dedicated to generating PWM and can't be doing anything else.

  • How do I program the Arduino for I2C and SPI interfaces?

    Both I2C and SPI are synchronous protocols that rely on a clock line. In both cases, libraries are available: Wire for I2C and SPI for SPI. In addition, other specialized libraries might wrap these to further simplify programming. An example of this is Adafruit TMP007 library for the I2C-based infrared thermopile sensor. These libraries abstract away the actual pins used by these interfaces.

    I2C is also called Two-Wire-Interface (TWI). For I2C, the Wire library uses 7-bit slave addressing and 32 byte buffer. Pullup resistors are required for lines SDA and SCL. Uno has one I2C interface while Due has two.

    With SPI interfacing, microcontroller is typically the master. We need to know some things about the slave: bit order, mode, and maximum clock speed. These must be configured using SPI.beginTransaction(SPISettings(…)). On Uno, pins 10-13 make up the SPI interface. MOSI, MISO and SCK are also available on the ICSP header.

  • How can I manage power consumption of my Arduino application?
    Current consumption of ATmega328P on breadboard. Source: Alex The Giant 2016.
    Current consumption of ATmega328P on breadboard. Source: Alex The Giant 2016.

    Managing power consumption is critical for battery-powered applications. When there's no activity, Arduino must go into sleep to save energy. The built-in function delay() gives some savings but more can be obtained by using the LowPower library. The problem with both approaches is that the system can't respond to interrupts while asleep. Sleep time is also limited to maximum 8 seconds.

    A better approach is to use the built-in sleep_cpu() along with interrupts. On Uno, hardware interrupts are available on pins 2 and 3. Depending on the application, interrupts can come from a sensor or an RTC module.

    You can also slow down the clock to as low as 62.5kHz by setting the CLKPR register. An external crystal can be used for other clock values. This will need changes to bootloader and optionally to the Arduino IDE. Optiboot can be used to create a custom bootloader.

    Other hardware changes can reduce power. Replace the onboard voltage regulator with a more efficient DC-DC buck converter. Better still, make a custom board just right for your application.

  • Could you name some popular third-party libraries for the Arduino?

    Registered Arduino libraries are listed online and also available from within the IDE. Libraries are organized by category, license and processor architecture. In June 2019, among the most starred or forked libraries were ArduinoJson, WiFiManager, FastLED, Blynk, IRremote, PubSubClient, Adafruit NeoPXL8, Adafruit NeoPixel, and MFRC522.

    During Jan-Mar 2019, these libraries recorded most downloads: Adafruit Circuit Playground, DHT sensor library, ArduinoJson, Servo, SD, Adafruit GFX Library, Adafuit NeoPixel, LiquidCrystal I2C, MFRC522, and Blynk.

    Among the top contributors are Adafruit Industries, SparkFun Electronics, Seeed Studio, Arduino Libraries, and STM32duino.

    A curated list of libraries is available from Lembed. Another list appears on Arduino Playground site. Read a tutorial to create your own library.

Milestones

2003

Hernando Barragán creates Wiring platform so that designers and artists can approach electronics and programming more easily. Wiring abstracts away the hardware pins with API calls such as pinMode, digitalRead, analogWrite, delay, etc. In fact, the syntax is defined before any hardware implementation.

Aug
2005

Arduino IDE and language library is released for the first time with the name Arduino 0001. Main sketch is compiled as C code but from Arduino 0004 (April 2006) it's compiled as C++ code.

Nov
2011

Arduino 1.0 is released. Sketches now use extension *.ino rather than *.pde used for Processing files. This version introduces the use of F() macro. This macro was invented about a year ago by Paul Stoffregen who invented the Teensy derivative of Arduino.

Oct
2012

With the release of Arduino 1.5 Beta, the IDE now supports both AVR 8-bit and ARM 32-bit. This is also the year when the first 32-bit Arduino is released with Arduino Due.

Mar
2019

There are more than 2,150 libraries registered with the Arduino Library Manager. These can be downloaded and installed directly from within the IDE. There are also over 7,000 libraries in the wild. Since v1.0.5, the latter can be installed from a Zip file. Meanwhile, Arduino 1.8.9 is released with support for ARM64 such as NVIDIA Jetson and Raspberry Pi 3.

Sample Code

  • // Source: https://www.arduino.cc/reference/en/language/functions/digital-io/digitalread/
    // Accessed: 2019-06-23
    // Use of digitalRead() and digitalWrite()
     
    int ledPin = 13;  // LED connected to digital pin 13
    int inPin = 7;    // pushbutton connected to digital pin 7
    int val = 0;      // variable to store the read value
     
    void setup() {
      pinMode(ledPin, OUTPUT);  // sets the digital pin 13 as output
      pinMode(inPin, INPUT);    // sets the digital pin 7 as input
    }
     
    void loop() {
      val = digitalRead(inPin);   // read the input pin
      digitalWrite(ledPin, val);  // sets the LED to the button's value
    }
     

References

  1. Alex The Giant. 2016. "Reducing Arduino Power Consumption." SparkFun, November 10. Accessed 2019-06-21.
  2. Arduino. 2017. "Installing Additional Arduino Libraries." Arduino, February 07. Accessed 2019-06-21.
  3. Arduino. 2019a. "Language Reference." Accessed 2019-06-21.
  4. Arduino. 2019b. "Arduino Software Release Notes." Accessed 2019-06-21.
  5. Arduino. 2019c. "Memory." Accessed 2019-06-20.
  6. Arduino. 2019d. "PROGMEM." Language Reference, Arduino. Accessed 2019-06-21.
  7. Arduino. 2019e. "analogRead()." Language Reference, Arduino. Accessed 2019-06-21.
  8. Arduino. 2019f. "analogReference()." Language Reference, Arduino. Accessed 2019-06-21.
  9. Arduino. 2019g. "analogReadResolution()." Language Reference, Arduino. Accessed 2019-06-21.
  10. Arduino. 2019h. "analogWrite()." Language Reference, Arduino. Accessed 2019-06-21.
  11. Arduino. 2019i. "Serial." Language Reference, Arduino. Accessed 2019-06-21.
  12. Arduino. 2019j. "SoftwareSerial Library." Accessed 2019-06-21.
  13. Arduino. 2019k. "SPI Library." Accessed 2019-06-21.
  14. Arduino. 2019l. "Wire Library." Accessed 2019-06-21.
  15. Arduino. 2019m. "Frequently Asked Questions." Accessed 2019-06-20.
  16. Arduino. 2019n. "Arduino Create." Accessed 2019-06-21.
  17. Atmel Corporation. 2015. "AVR Libc Reference Manual." Rev. #####X-MCU-04/2015, Atmel Corporation, Microchip. Accessed 2019-06-21.
  18. Azzola, Francesco. 2018. "10 Arduino IDE alternative to start programming." Java Code Geeks, August 27. Accessed 2019-06-21.
  19. Badami, Vasudhendra. 2016. "Arduino programming for beginners-1." Blog, HackerEarth, October 25. Accessed 2019-06-21.
  20. Barragán, Hernando. 2016. "The Untold History of Arduino." Accessed 2019-05-31.
  21. Beard, Peter. 2017. "Arduino Power Saving." March 31. Accessed 2019-06-21.
  22. Buckley, Ian. 2018. "5 Arduino Power Saving Tips That’ll Keep Yours Running for Days." MakeUseOf, July 04. Accessed 2019-06-21.
  23. Circuito. 2018. "Everything You Need to Know About Arduino Code." Blog, Circuito, March 11. Accessed 2019-06-21.
  24. Earl, Bill. 2013. "Optimizing SRAM." Adafruit, August 02. Accessed 2019-06-21.
  25. Humfrey, Nicholas. 2019. "Arduino Library List." June 21. Accessed 2019-06-21.
  26. Igoe, Tom. 2014. "Synchronous Serial Communication: The Basics." ITP Physical Computing, October 23. Updated 2018-08-30. Accessed 2019-06-21.
  27. Kurk, Ab. 2018. "Tutorial:A guide to putting your Arduino to sleep." January 26. Accessed 2019-06-21.
  28. Pieter P. 2018. "Optiboot - ATmega328P at custom frequency." April 22. Accessed 2019-06-21.
  29. Sam. 2017. "History of Arduino." Core Electronics, July 15. Accessed 2019-06-20.
  30. Shirriff, Ken. 2009. "Secrets of Arduino PWM." July. Accessed 2019-06-21.
  31. Sterling, Bruce. 2019. "The top ten Arduino library authors." Wired, March 11. Accessed 2019-06-21.
  32. Stoffregen, Paul. 2019. "Arduino Contributions." PJRC. Accessed 2019-06-21.
  33. Torrone, Phillip. 2019. "Top 10 Arduino library downloads." Blog, Adafruit, March 16. Accessed 2019-06-21.
  34. YorkshireKev. 2017. "Arduino power consumption - Delay vs Sleep." January 15. Accessed 2019-06-21.
  35. liuzengqiang. 2011. "How is arduino related to wiring?" Arduino Forum, August 16. Accessed 2019-06-21.

Further Reading

  1. Circuito. 2018. "Everything You Need to Know About Arduino Code." Blog, Circuito, March 11. Accessed 2019-06-21.
  2. Programming Electronics Academy. 2012. "Tutorial 03: Arduino Code & Syntax Overview." Programming Electronics Academy, August 26. Updated 2016-01-11. Accessed 2019-06-22.
  3. Mitchell, Robin. 2018. "Common Communication Peripherals on the Arduino: UART, I2C, and SPI." Maker Pro, August 30. Accessed 2019-06-21.
  4. Arduino. 2019a. "Language Reference." Accessed 2019-06-21.

Article Stats

Author-wise Stats for Article Edits

Author
No. of Edits
No. of Chats
DevCoins
2
1
1481
User avatar kps
4
0
25
1876
Words
0
Likes
4384
Hits

Cite As

Devopedia. 2019. "Arduino Programming." Version 6, June 22. Accessed 2023-11-13. https://devopedia.org/arduino-programming
Contributed by
2 authors


Last updated on
2019-06-22 19:10:00