In today´s lesson (number three) we will be seeing how variables are used in Arduino. Variables are used to save information.
Types of variables
The data that we save in the variables can be of different types. We will list a few of them here. For a complete reference of all types of variables in Arduino, check out this website.
- char, these are used to store characters and they take up one byte.
- byte, they can store a number between 0 and 255.
- int, they take up 2 bytes (16 bits), so they store a number between 2-15 and 215-1, which means between -32,768 and 32,767.
- unsigned int, also takes up 2 bytes, but as it is not signed, it can take values between 0 and 216-1, which means between 0 and 65,535.
- long, takes up 32 bits (4 bytes), from -2,147,483,648 to 2,147,483,647.
- unsigned long.
- float, decimal numbers that take up 32 bits (4 bytes). They can take values between -3.4028235E+38 and +3.4028235E+38.
- double, also stores decimal numbers but it has 8-bytes (64 bits).
Whenever we select a type of data, we have to choose the smallest possible size to cover our needs, as it will take up space in the available memory of our board, which could lead to our program requiring more space than what is available.
But how do we “make” variables in our code? It´s very simple: by indicating the type and name of the variable. We also have the option of giving it an initial value. Let´s take a look at an example:
1 2 3 4 5 |
char miCaracter='a'; // we declare a char variable called "miCaracter" and we start it with value a byte unNumero = 189; // byte type variable started at 189 int unEntero; // int type variable without starting unsigned int numeroPositivo = 2343; //positive whole number started float numDecimal = 12.212; // decimal number started at 12,212 |
There is another important type of variable, the string, which serves to store text chains, and it is essential for sending text via serial port. It enables chains to be created from number, other variables or concatenated chains. Let´s have a look at a few examples (from this website):
1 2 3 4 5 |
String stringOne = "Hello String"; // using a constant String String stringOne = String('a'); // converting a constant char into a String String stringTwo = String("This is a string"); // converting a constant string into a String object String stringOne = String(stringTwo + " with more");// concatenating two strings String stringOne = String(13); // using a constant integer |
There is also another important type called array, which is an organised group of data of a determined type. But we won´t go into that now, one step at a time!
We´re going to create an example program that adds two whole numbers and shows the result via serial port.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
int a = 5; // variable a is a whole number, starting at 5 int b = 6; // variable b is a whole number, starting at 6 int c = a + b; // variable c s a whole number, starting at 11. void setup() { // initialize Serial Serial.begin(9600); // baudrate 9600 Serial.print("a + b equals "); Serial.println(String(c)); } void loop() { } |
In this program we have written everything in the setup function as we only want to execute it once. Which of these three options do you think will be printed via the serial port?
- a + b equals c
- 5 + 6 equals 11
- a + b equals 11
You will have to figure it out yourself to see whether you have got it right.
Variable scope
We will explain this using examples.
Global environment
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
int a= 5; void setup() { // initialize Serial Serial.begin(9600); // baudrate 9600 Serial.println(String(a)); Serial.println("fin setup"); } void loop() { a = a + 1; Serial.println(String(a)); delay(1000); } |
We say that variable a is global because it can be accessed from anywhere, which means we can access its value from both the setup and loop functions. We would receive the following from the serial port:
Local environment
These are variables that only exist in the environment that they have been declared in. To explain quickly, an environment is what is between the keys. If we use them outside of its environment, we would get a compilation error. As it only exists with its environment, my program could repeat the same variable name in both environments. Let´s have a look at a few examples to explain things properly:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
void setup() { int a= 5; // variable a only exists in the setup function // initialize Serial Serial.begin(9600); // baudrate 9600 Serial.println(String(a)); Serial.println("fin setup"); } void loop() { // on compiling it would return a compilation error, because a does not exist in the loop a = a + 1; Serial.println(String(a)); delay(1000); } |
On compiling this program, we will get a code error, because the variable int is from the local environment and it only exists within the setup function and therefore cannot be used in the loop function. What would happen to this code?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
void setup() { int a = 5; // variable a only exists in the setup function // initialize Serial Serial.begin(9600); // baudrate 9600 Serial.println(String(a)); Serial.println("fin setup"); } void loop() { int a = 0; a = a + 1; Serial.println(String(a)); delay(1000); } |
Does it compile? Yes, because a has been declared with the loop and the setup. What would be printed on the serial port monitor?
1 2 3 4 5 |
5 fin setup 1 1 1 |
Surely you will have got it… Were you expecting it to print 1, 2, 3, 4… ? Yes, anyone would expect that. Why not? Because variable a of the loop is created and destroyed in every iteration, so it always starts at 0 and 1 is added to it… So within the loop, it´s always worth 1. What about the next programs? Let´s see if you can guess, have a go yourself to check the results.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
int a = 0; void setup() { int a = 5; // variable a only exists in the setup function // initialize Serial Serial.begin(9600); // baudrate 9600 Serial.println(String(a)); Serial.println("fin setup"); } void loop() { a = a + 1; Serial.println(String(a)); delay(1000); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
int a = 0; void setup() { int a = 5; a = a + 1; // initialize Serial Serial.begin(9600); // baudrate 9600 Serial.println(String(a)); Serial.println("fin setup"); } void loop() { a = a + 1; Serial.println(String(a)); delay(1000); } |
If you´re brave enough, leave a comment saying what you think the result should be (before you check it), and we´ll see who gets it right