# Arduino Programming

## Summary


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?

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?

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?

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.