Arduino 101 Fundamentals
The purpose of this instructable is to introduce the sketch writing fundamentals to all new comers to the Arduino world. It is meant to be a beginners guide that includes detailed explanation about the basic statements and functions. Most of the sketches I use are taken from the Arduino IDE for their simplicity. I wrote this guide when I first started working with Arduino as a way to help me code easier.
For the purpose of this instructable, I modified it this document a little bit to make it a better fit for everyone.
I hope you like it, if you have comments or questions do not hesitate to ask.
Happy building.
The Basics
To load the most basic Arduino sketch, open the Arduino IDE click on file then examples then 01.Basics and select the BareMinimum.
Here is the sketch:
void setup() {
// put your setup code here, to run once:
}
void loop() {
// put your main code here, to run repeatedly:
}
Essentially this is a complete code, it complies and can be uploaded to the Arduino but there is nothing in this code. It is important to understand this code structure because every Arduino sketch will contain a void setup() and a void loop() functions even if they are empty. The sketch will not compile without either one.
The void setup() is the first function to be executed in the sketch and it is executed only once. It usually contains statements that set the pin modes on the Arduino to OUTPUT and INPUT, example:
pinMode (12, OUTPUT);
pinMode(11, INPUT);
Or to start the serial monitor example: serial.begin(9600);
There are other statements that can be included in the void setup(),the above functions were only examples, but the important thing is to remember that the setup() is a statement that runs only once at the beginning of the sketch.
The void loop() is a function that executes indefinitely until you power off the Arduino. The functions in the void loop() usually manipulates the Arduino’s I/Os , example: Write a HIGH or LOW to a certain pin, and the data collected from them , example: Change the temperature sensor value from Celsius to Fahrenheit . You can also call upon local and global variables as well as other functions. In short this were the magic happens.
PinMode(), DigitalWrite() and Delay()
In this example I will introduce you to three statements that will be used in almost all Sketches. To follow this example, load the blink sketch from the Arduino IDE. It can be found in File then Examples then 01.Basics and select Blink.
You will need and Arduino, a solder less bread board, an LED, and two jumper wires.
Connect the short –ve prong of the LED to the GND on the Arduino and the long +ve prong to PIN 13 on the Arduino.
The Sketch:
void setup() {
pinMode(13, OUTPUT); // initialize digital pin 13 as an output.
}
void loop() {
digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(13, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}
Let’s dissect the sketch:
void setup() {
pinMode(13, OUTPUT); // initialize digital pin 13 as an output.
}
We already established that the void setup() is a function that runs only once at the beginning of the sketch. Within this function there is a statement called pinMode(). The job of the pinMode statement is to set the Arduino pins to OUTPUT or INPUT. OUTPUT means that this pin will produce a result like turning on or off an LED. INPUT is used to prepare the pin to receive information from a connected device like a sensor.
pinMode(Pin, Mode): The Pin can be any physical pin on the Arduino, you can use Pin number like 1, 2, 3 etc… or you can use the variable name assigned to this pin, example LED1, pinLed, etc… The Mode is OUTPUT or INPUT in capital letters. Example:
- pinMode(11, OUTPUT);
- pinMode(echo, INPUT);
Curly braces{}: Are used to define the beginning and the end of functions and certain statements. The braces are not only used with the void setup(), they are used throughout the sketch including the void loop, if statements, user defined functions, etc… every opening { should be followed by a closing } otherwise the code will produce an error when compiling.
Semicolon ;: Are used to define the end of a statement. Missing a semicolon will also produce an error while compiling the code. They are also be found separating elements in a for loop.
Line comment //: Anything written after the // is not used by the program and they are optional. However it is usually good practice to add comments so that other people can understand the code also later on when the code gets bigger and more complicated, it will help the programmer not to lose track of the code.
Back to the code:
void loop() {
digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(13, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}
Within the curly braces of the void loop there are two new statements: digitalWrite() and delay().
digitalWrite() changes the status of a pin by either writing a 5V or 0V using the following syntax:
- digitalWrite(13, HIGH); this will write 5V to pin 13 on the Arduino
- digitalWrite(LEDpin, LOW); this will write a 0V to the variable LEDpin
essentially if you have an LED on PIN 13 on the Arduino, using digitalWrite(13, HIGH); will turn on the LED and using digitalWrite(13,LOW); will turn off the LED.
delay() is straight forward, it is used to delay the execution of the next statement by the amount of milliseconds within the (). Example:
- delay(1000) means delay the execution of the next statement by 1000 milliseconds or 1 second.
Variables
In this example I will introduce the concept of variables and the statements Serial.begin(), Serialprintln() and digitalRead(). So fire up the Arduino IDE and load the DigitalReadSerial sketch from File à Examples à 01.Basics.
You will need an Arduino, a push button, a 10Kohm resistor, a solder less breadboard and some jumper cables. Connect the push button on the breadboard as in the picture. One pin of the button connects on the 5v on the Arduino, the other pin connects to the resistor then to the GND on the Arduino. The third pin connects to Pin 2 on the Arduino.
The Sketch:
int pushButton = 2; // digital pin 2 has a pushbutton attached to it. Give it a name
void setup() {
Serial.begin(9600); // initialize serial communication at 9600 bits per second
pinMode(pushButton, INPUT); // make the pushbutton's pin an input
}
void loop() {
int buttonState = digitalRead(pushButton); // read the input pin:
Serial.println(buttonState); // print out the state of the button
delay(1); // delay in between reads for stability
}
Let’s dissect the sketch:
int pushButton = 2;
int pushButton = 2; is a variable declaration statement that precedes the void setup() function. A variable is the bread and butter of all programming. It is used to store information to be used later in the code. In this case we are declaring that a variable called pushButton of the type int(integer) is assigned to digital pin number 2 on the Arduino. Variables that are declared before the void setup() are called global variables because they can be used by any function within the code. Since we declared pushButton before the void setup(), this variable can be used in the void setup() and the void loop(). On the other hand variables that are declared within a function, can only be used by that function and they are called local variables (we will see an example later on).
Variables have different types used to store different types of data:
Variable type Size Range
boolean 8 bits 0 or 1
byte 8 bits 0 to 255
char 8 bits -128 to 127
unsigned char 8 bits 0 to 255
int 16 bits -32768 to 32767
unsigned int 16 bits 0 to 65535
word 16 bits 0 to 65535
long 32 bits -2,147,483,648 to 2,147,483,647
unsigned long 32 bits 0 to 4,294,967,295
float(decimal numbers) 32 bits -3.4028235E+38 to 3.4028235E+38
double 32 bits -3.4028235E+38 to 3.4028235E+38
Once a global variable is declared, it can be called upon by any function using the name selected by the programmer (case sensitive). If the programmer decides to use pin 5 on the Arduino instead of 2, the only change needed is “int pushButton = 5;”. There is no need to go through the code to replace 2 with 5. Also it’s good coding ethics to select a descriptive name for the variable to easily identify it and also include the line comments “//” to elaborate further.
void setup() {
Serial.begin(9600); // initialize serial communication at 9600 bits per second
pinMode(pushButton, INPUT); // make the pushbutton's pin an input
}
Serial.begin(): starts the serial monitor port and sets the speed rate in bauds per second. According to arduino.cc you can use one of the following speeds to communicate with the computer 300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, or 115200. This is useful to display information on your computer screen. In this case we will display the state of the button by displaying 1 if the button is pressed and 0 if the button is not pressed. Once the program is uploaded to the Arduino you can start the serial monitor by clicking on Tools then Serial Monitor from the Arduino IDE.
pinMode(pushbutton, INPUT): Sets the mode of the pin defined by the variable pushbutton to INPUT.
void loop() {
int buttonState = digitalRead(pushButton); // read the input pin:
Serial.println(buttonState); // print out the state of the button
delay(1); // delay in between reads for stability
}
A new variable is declared within the void loop() called buttonState (local variable). This variable is of the type int and is initialized with the value of the pin 2. Here is a good example on how to initialize a variable without using a number but by using statement called digitalRead().
digitalRead(): is a statement that can be used with pins that are set to INPUT. Since pin 2 was set to INPUT mode, using digitalRead() we can read the value in this pin. In this case the value will be either 1 if the button is pressed or 0 if the button is not pressed. The syntax is digitalRead(pin# or variable);.
Serial.println(): This statement prints the value within the brackets on the serial monitor with a line break. You can use the statement Serial.print() to print without line break. In this sketch the value stored in the variable buttonState will be printed.
delay(1): This is a delay for only 1 millisecond used to give stability in between reads
AnalogRead() and AnalogWrite()
In this example I will demonstrate the use of the two statements analogRead() and analogWrite(). The sketch I am using is called ReadAnalogVoltage that it can be loaded from File/ Examples/01.Basics, and I added few lines to demonstrate analogwrite().
You will need an Arduino, a potentiometer, an LED and few jumper wires. Connect the middle pin of the potentiometer to pin A0 (analog 0) on the Arduino, then the +ve lead to the 5v on the Arduino and the -ve lead to the GND on the Arduino. And Connect the +ve Lead of the LED to D5 on the Arduino and the -ve lead to GND.
In this Sketch the value of the pin A0 will be printed on the serial monitor and at the same time the brightness of the LED will change when we turn the potentiometer.
The Sketch:
int LEDpin = 5; //digital pin 5 has an LED attached to it
void setup() {
Serial.begin(9600); // initialize serial communication at 9600 bits per second
pinMode(LEDpin, OUTPUT); // set the pin mode on pin 5 to OUTPUT
}
void loop() {
int sensorValue = analogRead(A0); // read the input on analog pin 0
float voltage = sensorValue * (5.0 / 1023.0); // Convert the analog reading (which goes from 0 - 1023)
to a voltage (0 - 5V)
analogWrite(LEDpin, voltage); //Apply the voltage value to the LED pin
Serial.println(voltage); // print out the value you read:
}
Let’s dissect the sketch:
int LEDpin = 5;
This is a variable of the type int called LEDpin decalring that there is an LED on pin 5 on the Arduino.
void setup() {
Serial.begin(9600);
pinMode(LEDpin, OUTPUT);
}
Serial.begin(9600): Starts the serial monitor with the speed 9600 bauds per seconds
pinMode(LEDpin, OUTPUT): Sets the pin Mode of pin 5 on the Arduino to OUTPUT.
void loop() {
int sensorValue = analogRead(A0);
float voltage = sensorValue * (5.0 / 1023.0);
analogWrite(LEDpin, voltage);
Serial.println(voltage);
}
analogRead(): The first line is declaring a new local variable called sensorValue of the type int and is assigned the value that we read from the analog pin A0 on the Arduino. The digital pins can read and write 1 and 0, however the analog pins on the Arduino can read and write values between 0 and 1023.
The second line introduces a new variable of the type float (with decimals) called voltage, the value of this new local variable is sensorValue*(5.0/1023.0). Now we can see that the value of a variable can be manipulated using a mathematical equation. Since the analog pins yield results between 0 and 1023, and we want to convert this value to volts between 0 and 5 volts. So we take the value we got in sensorValue and multiply it by 5.0/1023.0 this gives us a value between 0 and 5 volts.
Example: If we turn the potentiometer half way, the analog read will be 512. Then we assign this value 512 to sensorValue.
According to the code float voltage = sensorvalue*(5.0/1023.0) then voltage = 512* (5.0/1023.0) = 2.50 volts
analogWrite(): using this statement we can write a new value into a pin, using the example above, assigning the value voltage to LEDpin will power up the LED if there is enough voltage.
Serial.println(): this will print the value of voltage on the serial monitor.
The LED that I used will turn on faintly when the voltage reaches 1.3 volts
If Statement
I will use the same circuit as in the previous example and turn on the LED using an if/else statement. The if statement is a very efficient way to introduce condition to the code. I will use the Sketch called IfStatementConditional found in the Arduino IDE under File/Examples/05.Control.
You will need an Arduino, a potentiometer, an LED and few jumper wires. Connect the middle pin of the potentiometer to pin A0 (analog 0) on the Arduino, then the +ve lead to the 5v on the Arduino and the -ve lead to the GND on the Arduino. And Connect the +ve Lead of the LED to D5 on the Arduino and the -ve lead to GND.
In this Sketch the value of the pin A0 will be printed on the serial monitor and at the same time the brightness of the LED will change when we turn the potentiometer.
The Sketch
const int analogPin = A0; // pin that the sensor is attached to
const int ledPin = 5; // pin that the LED is attached to
const int threshold = 400; // an arbitrary threshold level that's in the range of the analog input
void setup() {
pinMode(ledPin, OUTPUT); // initialize the LED pin as an output:
Serial.begin(9600); // initialize serial communications:
}
void loop() {
int analogValue = analogRead(analogPin); // read the value of the potentiometer:
if (analogValue > threshold) { // if the analog value is high enough, turn on the LED:
digitalWrite(ledPin, HIGH);
}
else {
digitalWrite(ledPin, LOW);
}
Serial.println(analogValue); // print the analog value:
delay(1); // delay in between reads for stability
}
Let’s dissect the sketch:
const int analogPin = A0;
const int ledPin = 5;
const int threshold = 400;
As usual we start with the variables, this time I opted to use “const int” as a type, this means that the value of the variables will never change.
- analogPin will always be attached to analog pin 0
- ledPin will always be attached to digital pin 5
- threshold will always be at 400
void setup() {
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
}
There is nothing new in the void setup, we set the pin 5 to OUTPUT since there is an LED attached to it and we start the serial monitor at 9600bps
void loop() {
int analogValue = analogRead(analogPin);
if (analogValue > threshold) {
digitalWrite(ledPin, HIGH);
}
else {
digitalWrite(ledPin, LOW);
}
Serial.println(analogValue);
delay(1);
}
The first line in the void loop is the declaration of a local variable of the type int called analogValue and we assign to it the value we read from the analogPin variable.
If and if/else statements:
Syntax:
- if (condition) { execute command if condition is met}
Syntax
- if (condition) { execute command if condition is met}
- else {execute another command if condition is not met}
example:
if (a>b) {digitalWrite(ledPin, HIGH);}
or
if (a>b) {digitalWrite(ledPin, HIGH);}
else { digitalWrite(ledpin2, HIGH);}
Every time we are using an if statement, we are looking to meet a certain condition, example if "a" is bigger than "b". And if the result is true then we can execute whatever is in between the curly brackets. If the result is not true then do nothing.
Now if you are using an if/else statement, and the result is not true, then whatever is under "else" will execute.
The best way to set a condition is to use comparison and logical operators.
Comparison operators:
They are used to compare variables and constants against each other to verify if a certain condition is met.
== Equals to a == b Checks if a is equal to b
!= Not equals to a != b Checks if a is not equal to b < Less than a < b Checks if a is less than b > Bigger than a > b Checks if a is bigger than b <= Less thank or equals to a <= b Checks if a is less than or equals to b >= Bigger than or equals to a >= b Checks if a is bigger than or equals to b
Note: the difference between = and ==. = is used to assign a variable a number or a value, while == is used to compare two variable.
Logical operators:
Logical operators are used to compare two expressions and returns a TRUE or FALSE. The logical operators are AND(&&), OR(||), and NOT (!).
Logical AND if (a>b && c<d) Only true if both expressions are true
Logical OR if(a>b || c<d) True if one or both of the expressions is true
Logical NOT if(!a>b) True only if the expression is false
Let’s get back to the sketch
if (analogValue > threshold) {
digitalWrite(ledPin, HIGH);
}
else {
digitalWrite(ledPin, LOW);
}
- Here we are testing to see if the analogValue is bigger than the threshold : if (analogValue > threshold)
- if so then turn on the LED: digitalWrite(ledPin, HIGH);
- If not : else {
- Then turn off the LED: digitalWrite(ledPin, LOW);
Serial.println(analogValue): print the value of analogValue on the serial monitor
delay(1): A miniscule delay of 1 millisecond to stabilize the reading
For Statement
This example is all about the for statement. I will introduce the syntax and how to use it. I will also use a sketch directly from the Arduino IDE. Load the sketch called ForLoopIteration from File/Examples/05.Control.
You will need an Arduino, 6 red LEDs, 6 220ohms resistors, a breadboard and few jumper wires. Connect the +ve lead of each LED to a resistor and connect them on PINS 2,3,4,5,6, and 7 on the Arduino. Then connect the –ve leads to the GND on the Arduino.
The sketch:
int timer = 100; // The higher the number, the slower the timing.
void setup() {
for (int thisPin = 2; thisPin < 8; thisPin++) { // use a for loop to initialize each pin as an output
pinMode(thisPin, OUTPUT);
}
}
void loop() {
for (int thisPin = 2; thisPin < 8; thisPin++) { // loop from the lowest pin to the highest:
digitalWrite(thisPin, HIGH); // turn the pin on:
delay(timer);
digitalWrite(thisPin, LOW); // turn the pin off:
}
for (int thisPin = 7; thisPin >= 2; thisPin--) { // loop from the highest pin to the lowest:
digitalWrite(thisPin, HIGH); // turn the pin on:
delay(timer);
digitalWrite(thisPin, LOW); // turn the pin off:
}
}
Let’s dissect the sketch
Since this exercise is about the for statement or loop, I will start by explain how to use it.
Syntax:
for (initialization; condition; increment){
statement(s);
}
The for loop is used to repeat the statement(s) enclosed within the curly brackets a number of times defined by the increment and the condition.
For example:
for (int a=0; a <10; a++) { serial.println(a);}
- Initialization: int a = 0, declare a variable and give it a value.
- Condition: use comparison operators to set the condition.
- Increment: increase/decrease the value of the variable.
- Statement: print the value of the variable a.
In the above example, we declare a variable of the type int called “a” and we give it the value 0. Then we set a condition saying that as long as “a” is less than 10 print the value of “a” then increase “a” by 1 using compound arithmetic.
Here is the output:
- “a”=0, is “a” less than 10? Yes; print “a” then add 1 to “a”
- “a”=1, is “a” less than 10? Yes; print “a” then add 1 to “a”
- “a”=2, is “a” less than 10? Yes; print “a” then add 1 to “a”
- “a”=3, is “a” less than 10? Yes; print “a” then add 1 to “a”
- “a”=4, is “a” less than 10? Yes; print “a” then add 1 to “a”
- “a”=5, is “a” less than 10? Yes; print “a” then add 1 to “a”
- “a”=6, is “a” less than 10? Yes; print “a” then add 1 to “a”
- “a”=7, is “a” less than 10? Yes; print “a” then add 1 to “a”
- “a”=8, is “a” less than 10? Yes; print “a” then add 1 to “a”
- “a”=9, is “a” less than 10? Yes; print “a” then add 1 to “a”
- “a”=10, is “a” less than 10? No; stop the loop
This loop ran only 10 times because the condition was not met when it ran the 11th time.
Compound arithmetic or compound assignments:
These are shorthand notation of an arithmetic equation. They can be easily substituted with the arithmetic equation but they look nicer in the code:
a ++ Same as a=a+1 Increments a by +1
a -- Same as a=a-1 Decrements a by -1 a += b Same as a=a+b Increments a by +b a -= b Same as a=a-b Decrements a by –b a *= b Same as a=a*b Increments a by a*b a /= b Same as a=a/b Decrements a by a/b
Let’s go back to the sketch:
int timer = 100;
Declare a variable of the type int called timer with the value 100. This will be used as a timer later on to create the Cylon effect.
void setup() {
for (int thisPin = 2; thisPin < 8; thisPin++) {
pinMode(thisPin, OUTPUT);
}
}
This is a very interesting use of the for loop. We use the for loop to set the pin modes on the Arduino to OUTPUT. This only works if the pins we are using are in a sequence we use the pins 2 to 7. This for loop replaced the following lines:
- pinMode(2, OUTPUT);
- pinMode(3, OUTPUT);
- pinMode(4, OUTPUT);
- pinMode(5, OUTPUT);
- pinMode(6, OUTPUT);
- pinMode(7, OUTPUT);
void loop() {
for (int thisPin = 2; thisPin < 8; thisPin++) {
digitalWrite(thisPin, HIGH);
delay(timer);
digitalWrite(thisPin, LOW);
}
for (int thisPin = 7; thisPin >= 2; thisPin--) {
digitalWrite(thisPin, HIGH);
delay(timer);
digitalWrite(thisPin, LOW);
}
}
The object of this exercise is to turn on the LEDs one at a time from left to right then from right to left crating a Cylon effect or the Knight rider effect.
We do this effect by creating two for loops once to move the light from right to left and another one to move the lights in the opposite direction.
for (int thisPin = 2; thisPin < 8; thisPin++) {
digitalWrite(thisPin, HIGH);
delay(timer);
digitalWrite(thisPin, LOW);
}
In this for loop we start at pin number 2 turning on the LED one at a time until it reaches the 7th pin, the LEDs stay on for a delay of “timer” which is 100 milliseconds, this gives us the illusion that the light traveled from right to left.
for (int thisPin = 7; thisPin >= 2; thisPin--) {
digitalWrite(thisPin, HIGH);
delay(timer);
digitalWrite(thisPin, LOW);
}
In the second for loop the light starts at pin 7 and stops at pin2, again turning off after a delay of “timer”. This completes the effects of the red light moving in both directions.
While Loop
In this example I will demonstrate how the While loop works, this time I will not use a sketch from the Arduino IDE because I didn’t find a sketch simple enough in the IDE examples.
For this example you only need the Arduino.
The sketch:
void setup() {
int i = 0; //declare an integer I and set it to the number 0
Serial.begin(9600); //Start the serial monitor
while (i < 10) { //Beginning of the while loop check for the condition if i is less than 10
Serial.print("i = "); //Print what's in between the brackets
Serial.println(i); //Print the value of i
i++; //increment i with a +1
}
}
void loop() { //void loop is empty
}
The While loop will keep on working until the statement within the brackets is no longer true.
Syntax:
while(condition){
statement1
statement2
etc..
}
Let’s dissect the sketch:
void setup() {
int i = 0;
Serial.begin(9600);
while (i < 10) {
Serial.print("i = ");
Serial.println(i);
i++;
}
}
This is the first time we see a loop within the void setup. This means when this while loop finish running the program will stop since there is nothing in the void loop.
int i = 0: We start by declaring a variable of the type int and set its value to 0.
Serial.begin(9600): then we start the serial monitor at a speed of 9600bps
while (i < 10) {Serial.print("i = "); Serial.println(i); i++ }: this is the while loop, it tests to see if “i” is less than 0, if the condition is true it prints i=it’s current value then it increments “i”. the loop and the program stops when “i” reaches 10 because the void loop is empty