Arduino Board Uno Rev3- Atmega 328: Programming Guide

From Embedded Lab Vienna for IoT & Security
Jump to: navigation, search


The Arduino IDE is a cross-platform Java application that acts as a program code editor and compiler and is also able to send firmware serially to the board. The development environment is based on Processing, an IDE designed to program artists, who normally do not have much contact with the art world programming environments. The programming language is based on Wiring, a C similar language which has a similar scope for a more restricted board design, whose IDE is also based on processing. Make sure you have an updated version of Arduino IDE installed.


The basic structure of the Arduino programming language is relatively simple and is divided into at least two parts. These two required parts or functions enclose blocks of statements.

void setup() {     // put your setup code here, to run once:
void loop() {      // put your main code here, to run repeatedly:

 ➥ Here setup() is the preparation and loop() is the execution. Both functions are necessary to execute the program.

 ➥ The setup function should follow the variable definition, which must be listed before. Setup must be run through as the first function in a program.
   It is executed only once and is used to set PinMode or to initiate serial communication.

 ➥ The setup() function is called once when the program starts. Use this function to set PinModes or start serial communication. The setup() function must
   appear in every program, even if it does not contain any instructions.

 ➥ After the setup() function follows the loop() function. It contains program code that is executed continuously in an infinite loop - read inputs, trigger
   outputs, etc. This function is the core of all Arduino programs and does the main work.


The setup() function is called once when the program starts. Use this function to set PinModes or start serial communication. The setup() function must appear in every program, even if it does not contain any instructions.

void setup()
 pinMode(pin, OUTPUT);     // 'pin' define as output


After running through the setup() function, the loop() function does exactly what its name suggests and runs in an endless loop. This allows the program to interact with the Arduino board via changes, reactions and controls.

void loop()
 digitalWrite(pin, HIGH);    // switches 'pin' on
 delay(1000);                // Pause for one second
 digitalWrite(pin, LOW);     // switches 'pin' off
 delay(1000);                // Pause for one second


A function is a block of program code that has a name and a set of instructions that are executed when the function is called. The functions void setup() and void loop() have already been explained. There are more built-in functions that will be discussed later.

Type FunctionName(parameter)

The following integer type function delayVal() is used to insert a delay value into a program by reading a potentiometer. First a local variable 'v' is created. Next, 'v' is equated with the position of the potentiometer, which can have a value between 0 and 1023. The value is then divided by 4 to get a scale from 0 to 255 and at the end the result of the function is returned to the main program.

int delayVal()
 int v;                     // create temporary variable 'v
 v = analogRead(pot);       // read potentiometer Value
 v /= 4;                    // Convert from 0-1023 to 0-255
 return v;                  // return the calculated value

{} curly brackets

Curly brackets (also called 'curly brackets') define the start and end of function and statement blocks as in the 'void loop()' function and also in the 'for' and 'if' statement.

type function()
Note: An opening curved bracket '{' must always be followed by a closing curved bracket '}'. Here it is often said that the number of brackets must be balanced. Unbalanced parentheses often lead to cryptic, inscrutable errors in the compiler, which are sometimes hard to find, especially in large programs. The Arduino programming environment helps to check that the curved brackets are balanced. To do this, simply select a brace or click just behind it, and the logically connected counterpart is highlighted.


A semicolon must be used at the end of a statement and is used to separate the elements of a program. A semicolon is also used to separate the elements of a for loop.

int x = 13; // declares variable 'x' as integer with value 13
Note: Forgetting a semicolon at the end of a line leads to an error in the compiler. The error description can be very clear and directly point to the missing semicolon, but this does not have to be the case. If an inscrutable or apparently illogical error is reported, the first thing to do is to add missing semicolons near the reported error.

/*... */ block comments

Block comments or multiline comments are text areas that are ignored by the program. They are used for longer descriptions or comments and help other authors to understand program parts. They start with /* and end with */ and can cover several lines.

/* This is an inserted block comment
 please do not forget the closing comment -
 These must be balanced

// Single line comments

Simple single-line comments are defined with a // at the beginning of the line and end with the end of the line. They are ignored by the program and do not consume memory.

// this is a single line comment


A variable is the name of a numeric value with a name and memory location for later use in a program. A variable must be declared and optionally provided with a value. The following example declares a variable 'inputVariable' and assigns the value of analog pin 2 to it:

int inputVariable = 0;          // declares a variable and
                                     // sets its value to 0
inputVariable = analogRead(2);      // sets the value of the variable equal
                                    // with the value of analog pin 2 

'inputVariable' is the variable itself. The first line explains that its data type is 'int', which is the short expression for integer. The second line gives the variable the value of the analog pin 2, making the value of the pin available everywhere in the code.

Note: Variables should always have descriptive names as clearly as possible to make the code easier to read.

Declaration of variables:

All variables must be declared before use. Declaring a variable means defining its type such as int, long, float, etc., giving it a name and optionally an initial value.This only needs to be done once in the program. Afterwards the value can be changed at any time by calculations or various assignments.

The following example declares 'inputVariable' as 'int', i.e. integer data type and sets the initial value to 0. This is called a 'simple assignment'.

int inputVariable = 0;

A variable can be declared at many places in the program. The location of the declaration determines which program parts have access to the variable.

Data types

 ➥ byte: Byte stores an 8-bit numeric, integer value without decimal point. The value can be between 0 and 255.

byte someVariable = 180;         // declares 'someVariable as a 'byte' data type 

 ➥ int: Integers are the most common data type for storing integer values without decimal point. Its value is 16 bits and ranges from -32,767 to 32,768.

int someVariable = 1500;        // declares 'someVariable as an 'integer' data type

 ➥ long: Data type for long integers with extended size, without decimal point, stored in a 32-bit value in a spectrum from
  -2,147,483,648 to 2,147,483,647

long someVariable = 90000;      // declares 'someVariable as a 'long' data type 

 ➥ float: A data type for floating point values or numbers with decimal places. Floating point numbers have a better resolution than integers and are
   expressed as 32-bit values with a spectrum from -3.4028235E+38 to 3.4028235E+38.

float someVariable = 3.14;      // declares 'someVariable' as a 'float' data type 
Note: Floating point numbers are not precise and may lead to strange results when compared. Also, floating-point calculations are much slower than with integer data types. Calculations with floating-point values should be avoided if possible.

 ➥ arrays: An array is a collection of values that are accessed with an index number. Each value in the array can be accessed by retrieving the name of
   the array and the index number of the value. The index number always starts at 0 for an array.
   An array must be declared and optionally assigned values before it can be used.

int myArray[] = {value0, value1, value2...} 

In the same way it is possible to declare an array first with datatype and size and later to give a value to an index position.

int myArray[5];        // declare datatype 'integer' as array with 5 Positions
myArray[3] = 10;            // gives the 4th index the value 10  

To read the value of an array you can simply assign it to a variable specifying the array and the index position.

x = myArray[3];       // x now has the value 10 

Arrays are often used for loops, where the counter of the loop is also used as index position for the values in the array. The following example uses an array to make an LED flicker. With a for loop and a counter starting at 0 an index position in the array is read, sent to the LED pin, paused for 200ms and then the same is done with the next index position.

int ledPin = 10; // LED on pin 10
byte flicker[] = {180, 30, 255, 200, 10, 90, 150, 60};    // array with 8 different values
void setup()
 pinMode(ledPin, OUTPUT);    // Sets the OUTPUT pin

void loop()
 for(int i=0; i<7; i++)               // loop equals the number
 { // of the values in the array
 analogWrite(ledPin, flicker[i]);     // writes the index value to the LED
 delay(200);                          // 200ms pause

Digitaler Input - Output


Used in 'void setup()' to configure a specific pin as either input or output.

pinMode(pin, OUTPUT); // sets 'pin' as output 

Arduino digital pins are inputs by default, so they don't need to be specified as inputs with 'pinMode()'. Pins configured as inputs have a high impedance state.

Note: There are also comfortable 20 k 'pullup' resistors in the ATmega chip which are accessible via software.

These built-in 'pullup' resistors can be accessed in the following way:

pinMode(pin, INPUT);        // sets 'pin' as input
digitalWrite(pin, HIGH);        // switches on the 'Pullup' resistor

 ➥ Pullup resistors are normally used to connect inputs like switches. In the example shown here it is noticeable that the pin is not defined as an output
   although it is written to. It is only the method to activate the internal 'pullup' resistor.

 ➥ Pins configured as output are in a low impedance state and can be loaded with a maximum of 40 mAmpere current from connected elements
   and circuits. This is enough to make an LED light up (don't forget the serial resistor), but not enough to drive most relays, solenoids or motors.

 ➥ Short circuits at the Arduino pins as well as too high current can destroy the output pin or even the whole ATmega chip. For this reason it is a good idea
   to connect an output pin with external elements in series with a 470 or 1K resistor to switch.


digitalRead(pin)' reads the value from a specified digital pin, with the result either HIGH or LOW. The pin can be set either as a variable or constant (0-13).

value = digitalRead(Pin);      // sets 'value' equal to the input pin 

digitalWrite(pin,value) Outputs either logic level HIGH or LOW at a specified pin. The pin can be set as a variable or constant (0-13).

digitalWrite(pin, HIGH);       // sets 'pin' to high

The following example reads a button on a digital input and switches an LED on when the button is pressed:

int led = 13;            // LED connected to pin 13
int pin = 7;                 // Button connected to pin 7
int value = 0;              // Variable to store the readout value

void setup()
 pinMode(led, OUTPUT);    // defines pin 13 as output
 pinMode(pin, INPUT);     // sets pin 7 as input

void loop()
 value = digitalRead(pin);    // sets 'value' equal to
 // the input pin
 digitalWrite(led, value);    // sets 'led' equal to the
}                             // Value of the button

Analoger Input - Output


Reads the value of a specified analog pin with a 10 bit resolution. This function is only available for pins (0-5). The resulting integer values have a spectrum from 0 to 1023.

value = analogRead(pin);     // sets 'value' equal to 'pin
Note: Unlike digital pins, analog pins do not have to be declared as input or output first.

analogWrite(pin, value)

Writes pseudo-analog values to an output pin using hardware-based pulse width modulation (PWM). On newer Arduino boards with the ATmega 168 chip this function is applicable to pins 3, 5, 6, 9, 10 and 11. Older Arduinos with the ATmega8 only support pins 9,10 and 11. The value can be set as a variable or constant in the range 0-255.

analogWrite(pin, value);     // writes 'value' to the analog 'pin 

A value of 0 generates a uniform voltage of 0 volts at a fixed pin; a value of 255 generates a uniform voltage of 5 volts at a fixed pin. For values between 0 and 255, the pin changes very quickly between 0 and 5 volts - the higher the value, the longer the pin is HIGH (5 volts). For a value of 64, the pin is at 0 volts for three-quarters of the time and at 5 volts for one-quarter of the time. A value of 128 means that the output voltage is HIGH half of the time and LOW the other half. A value of 192 means that the voltage at the pin measures 0 volts at one quarter of the time and the full 5 volts at three quarters of the time.

Because this is a hardware-based function, the constant wave runs independently of the program until the next change of state via analogWrite (or a call to digitalRead or digitalWrite on the same pin).

Note: In contrast to digital pins, analog pins do not have to be declared as input or output before.

 ➥ The following example reads an analog value from 'pin', converts the value by dividing it by 4 and then outputs it as a PWM signal to 'led'.

int led = 10;    // LED with 220 resistor at pin 10
int pin = 0;         // Potentiometer at analog pin 0
int value;           // Value for readout

void setup(){}      // no setup required

void loop()
 value = analogRead(pin);      // sets 'value' equal to 'pin
 value /= 4; // converts 0-1023 into 0-255
 analogWrite(led, value);     // outputs the PWM signal 'led

Random functions


Sets a value or 'Seed' as starting point for the random() function.

randomSeed(value);       // sets 'value' as the random seed

The Arduino itself is not able to produce a truly random value. With randomSeed() a variable can be used as 'seed' to get better random results. For example, millis() or analogRead() can be used as a seed variable or function to use electrical noise through the analog pin as an output for random values.

random(min, max)

The random function allows the generation of pseudo-random values within a defined range of minimum and maxium values.

value = random(100, 200);        // sets 'value' with a random number between 100 and 200 equal 

The following example generates a random value between 0 and 255 and outputs it as PWM signal on a PWM pin.

int randNumber;      // Variable to store the random value
int led = 10;            // LED with 220 Ohm resistor at pin 10

void setup() {}          // no setup necessary

void loop()
 randomSeed(millis());              // uses millis() as seed
 randNumber = random(255);          // Random number in the range 0-255
 analogWrite(led, randNumber);      // PWM signal as output
 delay(500);                        // half second pause

Serial communication


Serial.begin(rate)' Opens the serial port and sets the baud rate for the serial transmission. The typical baud rate with the computer is 9600 baud. Other speeds are also supported.

void setup()
 Serial.begin(9600);             // opens serial port sets the data rate to 9600 bps
Note: When using serial communication, digital pins 0 (RX) and 1 (TX) cannot be used at the same time.


Writes data to the serial port, followed by an automatic line break as carrier return and line feed. This function has the same form as 'Serial.print()', but is easier to read on the serial monitor.

Serial.println(analogValue);         // sends the value of 'analogValue'

More detailed information about the numerous variants of the 'Serial.println()' and 'Serial.print()' functions can be found on the Arduino website.

The following simple example reads a value from analog pin 0 and sends the data to the computer once per second.

void setup()
 Serial.begin(9600);                  // sets the data rate to 9600 bps

void loop()
 Serial.println(analogRead(0));      // sends the analog value
 delay(1000);                        // pauses for 1 second


Digital output

  • Arduino-Example-Digital-Output

This is a simple 'Hello World' program and turns something on and off. In this example a LED is connected to PIN 13 and flashes every second. The resistor may be superfluous at this pin because the Arduino has a built-in resistor.

int ledPin = 13;            // LED off digital pin 13

void setup()                     // will run through once
 pinMode(ledPin, OUTPUT);        // sets pin 13 as output

void loop()                      // Running as endless loop
 digitalWrite(ledPin, HIGH);    // switches the LED on
 delay(1000);                   // Pause for 1 second
 digitalWrite(ledPin, LOW);    // switches the LED off
 delay(1000);                 // Pause for 1 second

Digital input

  • Arduino-Example-Digital-Input

This is the simplest form of an input with only two possible states: on or off. This example reads out a simple switch or button at pin 2. When the switch is closed and the input pin is HIGH, the LED is turned on.

int ledPin = 13;               // Output pin for the LED
int inPin = 2;                     // Input pin for a switch

void setup()
 pinMode(ledPin, OUTPUT);         // declares LED as output
 pinMode(inPin, INPUT);           // declares switch as input
void loop()
 if (digitalRead(inPin) == HIGH)   // check if this is the HIGH input
 digitalWrite(ledPin, HIGH);     // switches the LED on
 delay(1000);                  // Pause for 1 second
 digitalWrite(ledPin, LOW);   // switches the LED off
 delay(1000);                // Pause for 1 second

analog PWM output

  • Arduino-Analog-PWM-input

Pulse width modulation (PWM) is a method of simulating analog outputs by pulsing the output voltage. This allows you to make an LED brighter or darker or check a servomotor later. The following example uses a loop to slowly make an LED brighter and darker.

int ledPin = 9;            // PWM Pin for the LED

void setup(){}                  // No setup necessary

void loop()
 for (int i=0; i<=255; i++)     // ascending value for i
 analogWrite(ledPin, i);        // sets the brightness value to i
 delay(100);                    // Pause for 100ms

 for (int i=255; i>=0; i--)     // descending value for i
 analogWrite(ledPin, i);       // sets the brightness value to i
 delay(100);                   // Pause for 100ms

potentiometer Input

  • Arduino-Analog-PWM-input

With a potentiometer and one of the analog-digital converter (ADC) inputs of the Arduino it is possible to read analog values from 0-1024. The following example uses a potentiometer to control the blinking rate of an LED.

int potPin = 0;              // Input pin for the potentiometer
int ledPin = 13;                 // Output pin for the LED

void setup()
 pinMode(ledPin, OUTPUT);        // declare ledPin as OUTPUT

void loop()
 digitalWrite(ledPin, HIGH);     // switches on ledPin
 delay(analogRead(potPin));      // pauses the program by the value of potentiometers
 digitalWrite(ledPin, LOW);      // switches ledPin off
 delay(analogRead(potPin));     // pauses the program by the value of potentiometers

Used Hardware

 ➠ Arduino Board Uno Rev3 DIP Version, ATmega328, USB

 ➠ ARDUINO Wireless Proto Shield

 ➠ Arduino MKR WAN 1300 LoRa

 ➠ Arduino MKR LoRa Gateway Pro