Page 1 of 1

Arduino Programming for Beginners – Part 3: Working with Data

Arduino Programming for Beginners – Part 3: Working with Data
   12

In this article we will talk about “data”, after all, a computer can do pretty much only one thing: handle data in a way we dictate. For this we need what is called “data types”, “variables” and “constants”.

This is the third part of a series of articles I’ve written to get beginners started with Arduino Programming in the programming language C, which I’ve written with the intend to teach my 13 year old nephew (Bram) to get started with the Arduino. After all, he wants to build a robot, but without some basic knowledge about programming, he won’t get far ….

Besides an introduction into the language C, the default language used for Arduino Programming, “Arduino Programming for Beginners” will also touch topics like how to setup an Arduino, get a developers environment running, and look at a few basic electronic parts which we connect to our Arduino.




Overview of this Chapter

  A complete overview of this course can be found here: Course Overview.

DataTypes: Data for our Arduino Programming

Every program, or at least most of them, work with data or information. Either to detect it, display it, respond to it, or mangle it in some kind of way. After all, that’s what computers do: handle data. Even when it’s just one bit.

Why Data Types?

Data however, comes in different forms and shapes, and can be handled in only a few ways.

Let’s take a look at two basic types of data, for example text and numbers.
To illustrate how these need to be handled differently is for example this;
You cannot multiply two pieces of text, however, numbers you can multiply.
You can add two parts of text, making the result a text with both arts glued together, but when you add two numbers you do not necessarily get these 2 numbers in sequence.

For example “abc” ×def” makes no sense, however “abc+def” could make “abcdef“.
The same example with numbers; 3 × 4 makes 12 and 3 + 4 makes 7 (but not “34“)!

Since text can also contain numbers, our example becomes even more complicated for the computer.

If we think back about the explanation of “bit” and “byte” in the previous article, then we know that byte is 8 bits and that it can store a character. So if we want to store text, then we would need at least one byte per character.

If the data is a number, things do change a little bit. One byte can hold a number from 0 … 255.
So if we want to store the text “34”, the computer would need at least 2 bytes.
However if we store the number 34, then the computer would need only 1 byte!

These are of course very simplistic examples, but I think you will understand now why the computer needs to be told what kind of data it is dealing with. It needs to knows what kind of operations can be done, how these operations are to be done, and how to store the data.

That’s why there are in most programming languages so called “data types” – which defines the type and how to handle a given kind of data.

Data Types define how data can be handled and how it needs to be stored.

Data Types for your Arduino

You might have noticed that I typed double quotes (  ) around the text pieces. This is what in the language C (used for Arduino Programming) is the common way to indicate text. A sequence of characters enclosed like this is called a “string“, and a “string” is actually one of those “data types”.

The C language for Arduino Programming knows a number of “Data Types”, I’ll list them below, and do not worry too much if you’re not understanding some of these.

Data Types
 Data Type  Purpose / Type of values  Memory usage
 array An array can be seen as a sequence in which data can be accessed through (index) numbers.  Variable
 boolean A boolean can hold one of tow value: true or false  1 byte
 byte
 or
 unsigned char
A whole number, from 0255  1 byte
 char One single character (see our character list)  1 byte
 double Double precision floating point number, a number with numbers after the decimal point (same as float on most Arduino models)  4 bytes
 float Floating point number, a number with numbers after the decimal point (less accurate), ranging from -3.4028235E+38 … -3.4028235E+38  4 bytes
 int
 or
 short
Whole numbers, ranging from -32,768 … 32,767   2 bytes
 long Whole numbers, ranging from -2,147,483,648 … 2,147,483,647  4 bytes
 string
(char array)
Array of Char(acters)  Variable
 String
(object)
Object that holds a string, allowing easier use and manipulation than an array but uses more memory  Variable
 unsigned int
 or
 word
A whole number, ranging from 065,535  2 bytes
 unsigned long A whole number, ranging from 04,294,967,295  4 bytes
 void “nothing” (only used for function definitions)  N/A

Note : The data types that say “variable” in their memory use column will grow (and use more memory) as needed.

Note : Calculations with floating numbers is much slower than with whole numbers.

As you can see, not every data type takes the same amount of storage space in memory, and in some situations it can be good to take a data type that takes as little memory as possible. Unlike your computer, the Arduino has significantly less memory available to work with. However, if you pick a data type that is too small, for example for a calculation, then you might run into unexpected results as well.

Arduino’s have limited memory, so be careful which type you choose to use !

Now that you have seen this list, keep in mind that the most common types are: boolean, int, char, string, float and array.
Array is something we will explain at a later point.

Let’s look at boolean values. A boolean value can only be one of two values: “true” or “false” (read that as: YES/NO, ON/OFF, etc), and is quite often used when comparing information, to switch something on/off, or to detect is something on/off. Makes sense right?

Keep in mind: “true” and “false” are pre-defined in your Arduino (IDE)
and always typed in all small characters.

The boolean values “true” and “false” are stored as numbers,
you will not work with those numbers in the beginning,

but it’s good to know that true = 1 and false = 0 .

Int (integer) is a whole number, so no digits after the decimal point. This type of number is one of the easiest for the Arduino to work with, and can for example be used for adding, subtracting, counting, or for example for pin assignments.

A char is commonly used for a character, like characters in the alphabet for example. It can be used on it’s own, but it’s also often used for working with strings, which brings us to the more complicated data type: strings.

There are 2 string type: string (array of chars) and String (object).
Do not mix them up as they are very different animals!

Arduino knows 2 types of strings. One is the simple type, a so called array of characters (char), and is spelled with a lowercase “s”.

The other one is a more complex type, which is an object. More about objects later, but in this case it means that it comes with quite a few practical functions to work with strings. This type is spelled with a capital “S”.

In essence we have “basic” data types: numbers (int, long, float, double, etc.), text (char and strings) and Booleans (true/false).
The Array is basically a “group”, “sequence” or “list” of one of the mentioned “simple” data types.

What are Variables?

Now that we had a quick look at data types (the topic of data types can be much more complex than what I’ve shown you!), what do we do with those data types? Well ,… we use them with variables.

Variables are “names” that are linked to a specific memory location (don’t worry about where that exactly is) and data type.
This way the computer knows where to find it and what to expect in that memory location.
It will also know how much memory the variable uses, based in it’s data type.

These “names” can be used in your program to reference to a value and/or store your data.

Variables are “place holders” for the data we use in our program(s).
(more correct: the memory locations of our data)

Make sense? No? That’s OK. We will go through a few examples.

Here is a simple use of variables. We define some variables and do some calculations with it (this is not C code!):


1
2
3
4
5
6
A = 4
B = 12
C = 4 + 12   // = 16
D = A + B    // = 4 + 12 = 16
C = 4 + A    // = 4 + 4 = 8
A = A + A    // = 4 + 4 = 8

In the first line we define a variable called “A” and we assign it a value, the number 4.
In the second line we define another variable, “B”, and assign it the value 12.

When ever we call the variable “A”, we refer to it’s value … 4.
Ditto for calling “B”, which results in the value 12.

We can even do a calculation, which we do in the 3rd line: We define the variable “C” and give it the result of adding 4 and 12 (16).

We can do this calculation also by calling the variables “A” and “B” like we do in line 4.
Here we assign the result of adding the value of variable “A” (4) and variable “B” (12), which results in D being 16.

In the 5th line we change the value of “C” by giving it the result of adding 4 and “A”. The “old” value of “C” will be overwritten by this!

Now in the 6th line we go a little nuts: We set the value of “A” to the sum of “A” plus “A”. And guess what. That actually works! First the two last “A”‘s will be replaced by their value (4), then they will be added up (8), and then that value (8) will be assigned to the variable “A”. So as of this point “A” holds the value 8.

So variables are … variable. They can be changed as we go.

We used only simple name for variables, but we could easily use names that make more sense to us.

Variables can should have names that make things easier to read

An example:


1
2
3
PocketMoney = 4
Savings = 12
AllMyMoney = PocketMoney + Savings

Here we used more meaningful variable names, and when you read the code, it’s much easier to understand what is going on (besides not having much money).

When using these kind of variable names, please keep in mind that they are case sensitive. So “PocketMoney” is not the same as “pocketmoney” or “Pocketmoney” or “pocketMoney”!

Variables, and names in code in general, are case sensitive !

Also note that variables have some rules to follow when defining their names: You should start with a letter, the name can include letters, numbers and underscore characters. Do not use special characters, symbols, or spaces!

Variable name:

  • Should start with a letter (a, b, …, z, A, B, … , Z) or underscore ( _ )
  • Can contain letters
  • Can contain underscore(s)
  • Can contain numbers
  • CAN NOT contain special characters, symbols or spaces.

Let’s try an example with a program.
We will use only small whole numbers for this example. Can you guess which data type that should be?

To decide the right data type, we should know a little bit more. So let’s say we are looking at our money in whole dollars. Since we’re not super rich, we might have enough “space” with an “int” ($32,768).

We’re doing everything in the “setup()” section, since we don’t need to calculate this over and over again.
Remember: “setup()” runs only once, “loop()” keeps repeating itself endlessly.

First we set the serial port speed again, so we can “print” the results to our computer.

After that, we define 3 variables, PocketMoney, Savings and AllMyMoney, as an integer (int).
See how we close each statement, in the code below, with a semi colon? Don’t forget!

Next we assign values to those variables. Here each line is a statement again.

And finally we print the results.
Here we use “Serial.print” to print a text indicating which variable we want to show, but the line isn’t finished yet!
The second step uses “Serial.println” to print the value of the variable. However, with a small difference you might not have noticed between “Serial.print” and “Serial.println” – the latter starts a new line once it has printed. The extra “ln” with the print statement adds a line break when printing.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
void setup() {
  // set the speed for the serial monitor:
  Serial.begin(9600);
 
  // define our variables
  int PocketMoney;
  int Savings;
  int AllMyMoney;

  // assign the values
  PocketMoney = 4;
  Savings = 12;
  AllMyMoney = PocketMoney + Savings;

  // print the values to the serial monitor
  Serial.print("PocketMoney = ");
  Serial.println(PocketMoney);

  Serial.print("Savings = ");
  Serial.println(Savings);

  Serial.print("AllMyMoney = ");
  Serial.println(AllMyMoney);
}

void loop() {
  // leave empty for now
}

Copy the code and paste it in the Arduino IDE, replacing the current code.
Click the “Compile and Upload” button (you might get a message asking you to save the code, just click “Save”).
Your Arduino will blink a bit again and the following result will be displayed in the Serial Monitor window:


PocketMoney = 4
Savings = 12
AllMyMoney = 16

What are Constants?

Constants is a construct used to store a value that will never change in the program.
It’s typically used to make an otherwise arbitrary number look more meaning full, or to define this value easily in one spot and have the entire program use that value without having to change anything else in your code.

A Constant is like a variable that has a Fixed Value.

Constant names follow the same rules as Variable names.

We can say that there are 3 kind of constants.

The ones that have been defined by the Arduino Libraries – these you cannot change (like “true” and “false”) – and the ones you define.

Didn’t you say “3”, you’re only mentioning 2 … !?
That’s correct, and that’s because we have 2 ways of defining our own constant(s).

We can define a constant with the keyword “const“, or with the so called compiler directive “#define“.

The biggest difference is in the so called “variable scope” – or the “area” in which this works, I’ll get to that in a minute.

Use “const” only if you want to limit where it can be seen, or when you think you might want to change it to a variable in the future.

In most other cases consider using “#define”.

const

One method of defining a constant is as such:

const int NumberOfLights = 5;

Kind-a looks like what we did before when we defined variables, remember this:

int AllMyMoney;

A “const” constant behaves the same as a variable …
you just can’t change it’s value.

We just added the word “const” in front of it, to indicate that this value will not change, and we right away state that the value “ = 5 “.

So while your program is running, we CANNOT change it’s value!

If we would define such a constant in the “setup()” function, then it would only be known in the setup function.

#define

An alternative is using (done at the beginning of our source code):

#define NumberOfLights 5

Here you might notice a few critical differences.

First of all, the line starts with a pound or hash symbol (#), we haven’t seen that one before, and it basically indicates the start of a special compiler instruction. Later on we will see one or the other compiler instruction appear, for now just assume this is what it is.

The next thing you should notice is that the line doesn’t end with a semi-color (;), unlike normal statements.

And finally, we just typed “5” instead of ” = 5 “.

The compiler reads this instruction basically as “replace every occurrence of NumberOfLights with the number 5 before you start translating“. This implies that, unlike the “const” method, that there is no memory location it might be pointing to!

Defining a constant like this, means that it will be known everywhere in the program!

What is a Scope?

We’ve briefly mentioned it with the constants … the “variable scope” or often just “scope”. Which is used for constants, variables and even functions – but not for the “#define”.

When we talk about “scope” of a variable or constant, we basically mean “where can the variable (or constant) be seen?“, and with seeing we mean: where does it exist and can we read and/or modify it’s value.

Note: As of this point I will talk about variables, but the same goes for constants defined with the “const” statement, as they behave identical (with the exception of course that you cannot change the value of a constant).

The Scope of a variable indicates where it can be “seen” in your program

We know two kinds of variables: local variables and global variables.

Global variables are know EVERYWHERE in the program. But to do so, they must be defined in a specific place. These are typically variables that might be needed everywhere in the program.

Local variables are limited to the “area” they are defined in and are often used to keep code clean (and avoid confusion) or when a function for example needs a “new and fresh” variable each time we call it.

So what are those areas?

Let’s look at an empty Arduino program:


1
2
3
4
5
6
7
8
void setup() {
  // put your setup code here, to run once:

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

}

We see 2 areas: the code block for “setup()” and for “loop()” – both enclosed by accolades. But there is a 3rd area: the entire program.

Let’s define a global variable, to illustrate this:


1
2
3
4
5
6
7
8
9
10
11
int IAmGlobal; // IAmGlobal can be accessed here

void setup() {
  // put your setup code here, to run once:
  // IAmGlobal can be accessed here
}

void loop() {
  // put your main code here, to run repeatedly:
  // IAmGlobal can be accessed here
}

Let’s look at a local variable:


1
2
3
4
5
6
7
8
9
10
11
12
// IAmLocal can be NOT accessed here

void setup() {
  // put your setup code here, to run once:
  int IAmLocal;
  // IAmLocal can only be accessed here
}

void loop() {
  // put your main code here, to run repeatedly:
  // IAmLocal can NOT be accessed here
}

Now I know this is not the most extensive explanation ever, but it gives you an idea why it is important to watch carefully where you define a variable.

If we would have defined “IAmLocal” in the function “setup()” AND in the function “loop()”, then these two variables would not be the same. Changing the value in “setup()” would not affect the value of “IAmLocal” in the function “loop()”.


1
2
3
4
5
6
7
8
9
10
11
12
13
// IAmLocal can be NOT accessed here

void setup() {
  // put your setup code here, to run once:
  int IAmLocal;
  // IAmLocal can be accessed here but it is NOT the same one as in loop()
}

void loop() {
  // put your main code here, to run repeatedly:
  int IAmLocal;
  // IAmLocal can be accessed here but it is NOT the same one as in setup()
}

Let’s try to illustrate this with a working program.

We see a new construct here, which looks like the construct we used for the “const” statement: int A = 0;

Just like we have seen with “const”, we can define a variable and assign it a value right away. So in this line we define the variable “A” and set it’s value to zero (0). This line creates the GLOBAL variable “A”.

After that statement, “setup()” starts and … defines “A” as an integer (whole number) AGAIN. This results in a LOCAL variable “A” that only exists in “setup()”. Code in “setup()” will completely ignore the global variable!!

In “loop()” we do something similar, the “A” defined in “setup()” cannot be seen in “loop()” and the LOCAL variable “A” makes it that the GLOBAL variable “A” (defined in line 1) is being ignored.

The function “delay(x)” can be used to delay a program for “x” milli-seconds.
1000 Milli-seconds = 1 second.

Run this program on your Arduino.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int A = 0;

void setup() {
  int A;
  A = 1;
  Serial.begin(9600);
 
  // print the values to the serial monitor
  Serial.print("Setup: A = ");
  Serial.println(A);
}

void loop() {
  int A;
  A = 2;
 
  // print the values to the serial monitor
  Serial.print("Loop: A = ");
  Serial.println(A);

  delay(100000);
}

The output will be:

Setup: A = 1
Loop: A = 2

To see how LOCAL and GLOBAL variables work, let’s comment out (add comment symbols, the //, in front of the code) lines 4 and 5, and see what happens.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int A = 0;

void setup() {
  // int A;  
  // A = 1;
  Serial.begin(9600);
 
  // print the values to the serial monitor
  Serial.print("Setup: A = ");
  Serial.println(A);
}

void loop() {
  int A;
  A = 2;
 
  // print the values to the serial monitor
  Serial.print("Loop: A = ");
  Serial.println(A);

  delay(100000);
}

The output will be:

Setup: A = 0
Loop: A = 2

See how it now uses the GLOBAL variable in the “setup()” function?

If we would only use the global variable, in the following code, you can see that both functions can actually change the value of this global variable:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
int A = 0;

void setup() {
  Serial.begin(9600);
 
  Serial.print("Setup: First A = ");
  Serial.println(A);

  A = 10;
  // print the values to the serial monitor
  Serial.print("Setup: Second A = ");
  Serial.println(A);
}

void loop() {
  Serial.begin(9600);
 
  Serial.print("Loop: First A = ");
  Serial.println(A);

  A = 20;
 
  // print the values to the serial monitor
  Serial.print("Loop: Second A = ");
  Serial.println(A);

  delay(100000);
}

In this code we only define the variable “A” as a GLOBAL variable – so it can be seen everywhere (unless a LOCAL variable would override this of course).

Your output should show something like this:

Setup: First A = 0
Setup: Second A = 10
Loop: First A = 10
Loop: Second A = 20

So we define the global variable “A” and set it to zero (0) – it’s outside all “blocks”.
In “setup()”, the first “Serial.print” shows that the value of “A” can be read.
We then change “A” to 10, and print it.
In “loop()”, we first show that the changed value of “A” can actually be read as well as it was changed in “setup()”.
And in the next lines we change it to 20 and print it again.

Number Representations

There a tons of different numbering systems to represent numbers. You can take a peek at this Wiki List of Numeral Systems. For programming however, we commonly use the following 3 systems most often: Decimal, Hexadecimal and Binary numbering (in that order). But it will be rare that we use anything but decimal numbers. So what are these “numbering” systems?

Decimal Numbering

The decimal numbering system is the kind of numbering we use in our daily life. It’s a system based on ten digits: 0, 1, 2, 3, 4, 5, 6, 7, 8, and 9. Since we have 10 digits, this system is called “Decimal” system (Deci meaning 10).

Yes I confident that you already know how counting works, but we need go through “how counting” works, as it will be helpful when explaining the other numbering systems. So here we go …

When we count, we go 0, 1, 2, 3, 4, 5, 6, 7, 8, and 9. For the next number (9+1) however, we run out of symbols, so we reset the 9 to a 0 (zero) and increase the number before the 9 by one. What number before the 9 I hear you say? Well, we can imagine an infinite number of zero’s in front of which ever number we have. They wouldn’t mean anything and not change the number value either. So instead of trying to type an infinite number of zero’s, I’ll start with just 3 zero’s …

So when we count: 0001, 0002, … , 0008, 0009, 0010, 0011, 0012, … , 0018, 0019, 0020, 0021, … 0099, 0100, 0101, … etc.

Each time one of our numbers wants to go beyond 9, we reset it to 0 (zero) and increase number before it by one.

Make sense?

So if we get to number 0999 and we want to increase this by one, then we have to reset the last number to 0 (0990), and increase the previous number by one (0990), which results in that number being reset as well (0900), which will increase the previous number again (0900). That number again resets to 0 (0000) and the number before that increases with 1 as well, so we end up with 1000.

Are you with me so far? OK, hold that thought, we will need it again!

And we also know that displaying a decimal number is straight forward as well withSerial.print(nummer);.
We can also write that as: Serial.print(nubmer, DEC);, where DEC indicates that we want it printed as a decimal number. With this method (DEC), “number” can be anything, but works best with whole numbers. Floating point number can give unexpected results.

Binary Numbering

The binary numbering system uses only the digits: 0 and 1. We have only 2 digits: hence the name “binary”, meaning “two”.

In contrast what you’d expect, the binary numbering does not find it’s origin with computers. It’s been around for a very very very long time. You can read the history on the Wiki page – and it most certainly is an interesting read!

That a side, the binary numbering system is very suitable for computers, since they only work with true or false, yes or no, or: on or off.

When counting in a binary numbering system, we work exactly the same as with a decimal numbering system, we just have way less digits to work with.

So, right away adding some imaginary zero’s, we start counting: 0000, 0001 and then we run out of digits. So reset number to zero and increase previous by one, and we continue counting: 0010, 0011, and again we run out of digits, so we rinse and repeat. 0100, 0101, 0110, 0111, 1000, 1001, 1010, 1011, 1100, 1101, 1110, 1111.

Knowing that this is how counting works, with help of a table, like the one below, how we can convert a binary number to a decimal number:

Binary Counting
 Binary number  Decimal number
0000  0
0001  1
0010  2
0011  3
0100  4
0101  5
0110  6
0111  7
 1000  8
 1001  9
 1010  10
 1011  11
 1100  12
 1101  13
 1110  14
 1111  15

There are easier tricks than to write a complete table, well, besides the calculator on your computer of course.

If you’re familiar enough with calculating “to the power”, then the following might make sense to you. Say we have a 16 bit (a bit, being each position that can be either zero or one) number. Often such a number would be displayed in groups of 4, so for example: 1101 1000 0000 0101. How would we convert this “quickly”?

Each position (counting from the right to the left, with the first position being zero) has a value of:
“2 to the power the position” times 0 or 1, depending on the value in that position.

We use “2” because the Binary numbering system has only 2 “numbers” to work with.

So if we look at a short 4 bit number (this is called a nibble!): 1010.

Binary Conversion
 Position 3 Position 2  Position 1  Position 0
 1  0  1  0
 23 = 2×2×2 = 8  22 = 2×2 = 4  21 = 2  20 = 1
 1×8  0x4  1×2  0x1
 = 8  = 0  = 2  = 0

The result is the sum of these numbers (add): 1010 binary = 8+0+2+0 = 10 decimal.

Most do not even remember this trick, since most of our computer calculators and programming languages can do it for us.

One thing to remember: a byte is 8 bits and if all bits are 1, we get 1111 1111, which is right away the maximum value of a byte: 255.

You can use binary numbers in your code, by typing “0b” (zero-b) in front of it. For example: 0b1010

Printing a binary number can be done as such, if we’d want to print the binary number 1010: Serial.println(0b1010);
However, this will convert it right away to a decimal number, since this would be the same as Serial.println(0b1010, DEC);

To print this binary number as a binary number, we use: Serial.println(0b1010, BIN);
This would also print a decimal number as a binary number: Serial.println(10, BIN); would print “1010”.

Hexadecimal Numbering

So we have seen Decimal, and Binary. But what is a Hexadecimal Number?

Note: when referring to hexadecimal numbers, folks often say just “hex” for short.

In the Hexadecimal we have 16 digits: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, and F. (Hex = 6  and  Deci = 10)

Counting works just the same as with the other two numbering systems.

As an example, with leading zero’s: 0001, 0002, … , 0009, 000A, … 000F, 0010, 0011,… 001F, 0020, 0021,… etc.

Conversion is a little bit harder, although it kind-a looks similar to what we do with binary conversions.

Let’s say we have the hexadecimal number 2FA. Counting from right to left, starting with zero: multiply each number with 16 to the power of the position and add these results up to get the decimal number. We use “16” because the hexadecimal system has 16 “numbers”.

Let me put that in a table:

Hexadecimal conversion
 Position 2  Position 1  Position 3
 2 × 162  F × 161  A x 160
 = 2 × 256  = 15 (F) × 16  = 10 × 1
 = 512  = 240  = 10

So, 2FA Hexadecimal equals 512+240+10 = 762 decimal.

We can use hexadecimal numbers in our code, just by adding “0x” (zero-x) in front of it, for example: 0x2FA

We can also print those values, and as we have seen with the binary numbers: Serial.println(0x2FA); will print it as a decimal number. Printing it in a hexadecimal format can be done with Serial.println(0x2FA, HEX);. This again would work for decimal numbers and binary numbers as well.

Printing Numbers

Just a quick paragraph in which we show how we can work with Decimal, Hexadecimal and binary numbers.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
void setup() {
  Serial.begin(9600);

  int decNumber = 10;
  int hexNumber = 0x2FA;
  int binNumber = 0b10001010;

  Serial.println("All numbers as decimal:");
  Serial.println(decNumber);
  Serial.println(decNumber, DEC); // same as previous line
  Serial.println(hexNumber);
  Serial.println(hexNumber, DEC); // same as previous line
  Serial.println(binNumber);
  Serial.println(binNumber, DEC); // same as previous line

  Serial.println("All numbers as Hexadecimal:");
  Serial.println(decNumber, HEX);
  Serial.println(hexNumber, HEX);
  Serial.println(binNumber, HEX);

  Serial.println("All numbers as Binary:");
  Serial.println(decNumber, BIN);
  Serial.println(hexNumber, BIN);
  Serial.println(binNumber, BIN);  
}

void loop() {
  // leave empty for now
}

The output of this example (notice that adding “, DEC” is not required):

All numbers as decimal:
10
10
762
762
138
138
All numbers as Hexadecimal:
A
2FA
8A
All numbers as Binary:
1010
1011111010
10001010

Operators

Now that we know about data types, variables, their scope, and that we can print and use them, time to look at what is called “Operators“.

An Operator is a symbol that does something with the data.

An operator is (typically) a symbol that does something with the data.
We have seen already one of those by using a “+” for adding up two numbers. The “+” is an arithmetic operator for calculations.

For Arduino Programming, we know basically 6 “groups” of operators (see also the Arduino Reference pages).
You can focus on Arithmetic Operators for this part, but in the next part we will look at other operators, like those used for comparing information.

Arithmetic Operators

As seen before, operators can be used for calculations – these are called Arithmetic Operators.
Most of these you will know, but some of them are using different symbols than the ones you usually use.

For example, I learned in school to write division like so:  12 : 4 = 3   (in some countries “÷” is being used)
However in the C language this is written as:  12 / 4 = 3

The same goes for multiplying. I learned, like most, to do it this way:  3 × 4 = 12  (sometimes a “.” is being used)
In C this is written as: 3 * 4 = 12

Arithmetic Operators
 Symbol  Purpose
=  Assign
+  Adding
 Subtracting
*  Multiply
/  Division
%  Modulo

The odd guy, for some, will be the “modulo” operator.
Modulo is actually the remainder of a division. As an example, if we divide 5 by 2 using long division, then the answer is 2 (2×2=4) and a remainder of 1 since 5 – 4 = 1, and 1 cannot be divided by 2.
So the “modulo” of 5 divided by 2 is:  5 % 2 = 1.

Just to give you some other examples:
If we divide 10 by 5 then the answer is exactly 2 and there is no remainder when doing long division, so 10 % 5 = 0.
If we calculate 33 % 7 = 5, since 33 divided with long division by 5, results in 4 (4×7=28) and the remainder is 5 (33-28=5).

The other odd guy, assign (=), is basically “copying” the value to a given variable.

These are you basic calculation operators, but there are more. Remember; a program is basically a bunch of instructions to shuffle and work with data. So we do not just add and subtract … we also compare …

Comparison Operators

When working with data with Arduino Programming, when we want to make decisions, comparing becomes pretty important.
Below I’ll show you a list of operators used for comparison, for example to see if two things are the same (equal) or if one number is greater than the other, etc.

In a next section we will go through ways of comparing, so for now, you do not yet need to memorize these.

Also keep in mind that a comparison always results in either a “true” of “false” answer.

Comparison always results in either a “true” of “false” answer – a boolean

So for example:  5 > 2  will result in a “true” and  5 < 2 will result in a “false”.
But … what do those symbols “<” and “>” mean? Well, let’s look at this little table:

Comparison Operatos
 Symbol  Purpose
==  is Equal to
!=  is not Equal to
<  less than
>  greater than
<=  less than or equal to
>=  greater than or equal to

Remembering these symbol (less than and greater than) can be hard, but one of these tricks might help you remember them.

Trick 1: If we look at the “less than” symbol “<” then you could see this as a slightly tilted to the left “L” … the “L” from “Less”.

"Less Than", Rotated "L"

“Less Than”, Rotated “L”

Trick 2: Another trick would be that the left size of the symbol is “small” and the right side is “big”, so the item in front of “<” is “small” and the one after “<” is “big”. The same goes, just the other way around, with the “>” symbol.

"Less Than" - Small vs Big opening

“Less Than” – Small vs Big opening

Yet another trick is seeing the symbol as a Pac Man mouth. Pac Man is hungry and wants to eat the biggest item. So when we see 5 > 2, then the “mouth” is open towards the largest item.

Up to you which one you remember easiest (I prefer the first one).

A small example to see a comparison operator in action. Remember that a comparison operator always results in either “true” or “false” and that “true” (1) and “false” (0) are stored as numbers. So if we print a boolean we will see the number and not “true” or “false”.


1
2
3
4
5
6
7
8
9
10
11
12
boolean A;

void setup() {
  Serial.begin(9600);

  A = 5 < 2;
  Serial.print("A = ");
  Serial.println(A);
}

void loop() {
}

This example will do the following:

We define “A” as a “boolean” (a variable that is either “true” or “false”).
We then use the “<” comparison operator – in other words, we compare 5 with 2 and see if 5 is less than 2, which is obviously not the case and results in the answer “false”.
After that we print the value of “A” which will print a “0” (zero). Remember that booleans are stored as numbers (false = 0, and true = 1).

More details about comparing in the next chapters …

Boolean Operators

Just like comparison can be a bit daunting at this point of your Arduino Programming experience, the so called boolean operators (operators only used with booleans) can be a bit daunting as well, but we will get to the fine details of these guys.

Boolean Operator
 Symbol  Purpose
 &&  AND
 ||  OR
 !  NOT

Let me try to explain these, even though we will not use them right away.

AND (&&)

The AND operator checks if two values are both true.

Say we have 2 boolean values, let’s say “LooksLikeADuck” and “SoundsLikeADuck“.
To determine if we are dealing with a “Duck“, both need to be true.
So we are dealing with a Duck if LooksLikeADuck AND SoundsLikeADuck are true.

DuckLooksLikeADuck && SoundsLikeADuck.

If one of the two variables, or even both variables, are false then we’re not dealing with a Duck.

Below a table of combinations. Here we see: both values must be true to get true as a result. AND results in “true” when both variables are “true”.

And Results
 Value1  Value2  Result of Value1 AND Value2
 true  true  = true
 true  false  = false
 false  true  = false
 false  false  = false

OR (||)

The OR operator looks if at least one value is “true”.

Let’s take again 2 variables, say “DarkOutside” and “After9PM“.
To see if the lights should be on (variable: “LightsOn“) at least one of these variables needs to be true.

So LightsOn when it’s DarkOutside OR After9PM.

LightsOn = DarkOutside || After9PM.

Again a little table with examples, where we see that the result will only be false if BOTH variables are false as well. So OR will result in “true” when at least one of the variables is “true”.

Or Results
 Value1  Value2  Result of Value1 OR Value2
 true  true  = true
 true  false  = true
 false  true  = true
 false  false  = false

NOT (!)

The NOT operator flips a boolean, so it changes “true”→”false” or “false”→”true”

The boolean operator NOT (!) can be seen as a flip switch. Flipping the switch will change to the opposite. The same goes for booleans, as “NOT” changes a boolean to it’s opposite value.

As an example, when the “LightsOn” is true, then NOT “LightsOn” will result in a false (lights off).
But if the “LightsAreOn” is false, the NOT “LightsOn” will result in true (lights on).

Or maybe in other words: NOT true = false, and NOT false = true.

!true = false
!false = true

I don’t think we need a table for this, but for completeness:

NOT Results
 Value1  Result of NOT Value1
 true  false
 false  true

A little experimenting

As seen in the previous paragraph (Comparison Operators), this can be tested with a small piece of code.


1
2
3
4
5
6
7
8
9
void setup() {
  Serial.begin(9600);
 
  Serial.print("The answer is: ");
  Serial.println(true && false);
}

void loop() {
}

In this example code, we test the “AND” (&&) boolean operator.

Keep in mind again that booleans are stored as a number (true=1, false=0). This code results in “false”, so it will print “0”.

In line 5 you can place any of these boolean operators, to see what they do. Some examples for line 5:


Serial.println(true && true);   // AND; true and true  = true  = 1
Serial.println(true || true);   // OR ; true or true   = true  = 1
Serial.println(false || false); // OR ; false or false = false = 0
Serial.println(false || true);  // OR ; false or true  = true  = 1
Serial.println(!true);          // NOT; not true       = false = 0

Compound Operators

Compound Operators can be used frequently to keep code writing to a minimum. But they can be confusing as well as the might degrade the readability of your code.

A Compound Operator basically combines two or more operations into one, but again, they can be tricky to work with.
Also note that I am not mentioning all compound operators here.

A Compound Operator basically combines two or more operations into one …

Compound Operators
 Symbol  Purpose  Example
 ++  increase value  A++; // increase the value of A by 1 and return the old value of A
++A; // increase the value of A by 1 and return the new value of A
 —  decrease value  A–; // decrease the value of A by 1 and return the old value of A
–A; // decrease the value of A by 1 and return the new value of A
 +=  compound addition  A += B; // the same as A = A + B;
 -=  compound subtraction  A -= B; // the same as A = A – B;
 *=  compound multiplication  A *= B; // the same as A = A * B;
 /=  compound division  A /= B; // the same as A = A / B;
 %=  compound modulo  A %= B; // the same as A = A % B;

 

This is a what they call “shorthand” so we have to type less when coding.
I’m sure you understand now why this can be harder to read, and in the end we do not gain much with it.
Especially for beginners: avoid if possible.

Just a quick example:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int A = 0;

void setup() {
  Serial.begin(9600);
 
  Serial.print("Setup: A = ");
  Serial.println(A);
}

void loop() {
  Serial.begin(9600);
 
  A += 1; // the same as: A = A + 1;
 
  // print the values to the serial monitor
  Serial.print("Counting in the loop():  A = ");
  Serial.println(A);

  delay(1000);
}

Your output will look like this:

Setup: A = 0
Counting in the loop(): A = 1
Counting in the loop(): A = 2
Counting in the loop(): A = 3
Counting in the loop(): A = 4
Counting in the loop(): A = 5
Counting in the loop(): A = 6
Counting in the loop(): A = 7
...

Now if you change line 13 to A = A + 1; , and you compile your program, you will notice 2 things.
First of, the compiled code will be equal in size as when you used A += 1;  …
But you will also notice that A = A + 1; is much easier to read.

So again, especially when beginning programming, avoid these compound operators.
At a later time it’s great to know what they do though, as quite a few programmers use this as a shorthand.

Pointer Access Operators and Bitwise Operators

These two groups are too complex at this point to go through, so I’m skipping them.
Once you have become a more advanced programmer, you’ll start looking for these … 

OK,… we’ve dealt with a lot of information here,… data … go play and experiment with the examples presented here before you continue to the next chapter of our Arduino Programming articles.

If you have questions, just ask them below in the comment section, and keep in mind: There are no stupid questions! We all had to start at some point!

Next chapter: Arduino Programming for Beginners – Part 4: Decisions

 

Donation options


Donations are very much appreciated, but not required. Donations will be used for web-hosting expenses, project hardware or a motivational boost (a drink or snack). Thank you very much for those have donated already! It's truly AwEsOmE to see that folks like our articles and small applications.

Comments


There are 12 comments. You can read them below.
You can post your own comments by using the form below, or reply to existing comments by using the "Reply" button.

  • Feb 8, 2017 - 11:27 AM - Stan Comment Link

    Hi. I read every sentences more than 2 (cus of its in English!) and sometimes i read more than 5 to get it in ma mind. But sometimes it just dont happen! :) so Here we go ; in normal life math ” = ” means equal to as for example 2 + 1 = 3. But in C world we use it to Assign a value for a variable and if we want to say Equal in C world then we use “==” (double). So its a lil different from real life math. “=” is assign value for variable and “==” is a real equal for C platform. My logic is true as the article says already?  If so then whats different between Assign and Equal? What changes if i type ” int led = 1 ; ” or ” int led == 1 ; ” . I know second code will not work but i tryna get the logic ; whats differenxe between Assign and Equal becauae in the end it gives a value to the variable name..  i doubt if i cld make the sense that i intended to !

    Reply

    Stan

    • Feb 8, 2017 - 11:46 AM - hans - Author: Comment Link

      Hi Stan!

      Well, that’s a good question, and I can understand the confusion …

      The difference between “assign” (=) and “equal” (==) is this:

      = is for assigning a value,
      == id for comparing two values (see the comparison operator tables).

      So “int led = 1;” defines the variable “led” as an integer and assigns (=) it the value “1”.

      You second example, “int led == 1;” however won’t work, but if we’d try to read this it would say: define the variable “led” as an integer, however you would not be assigning it a value, instead it’s comparing the value of “led” with “1”. Obviously the compiler won’t like this as it makes no sense.

      Does that makes sense? 

      Reply

      hans

      • Feb 8, 2017 - 12:02 PM - Stan Comment Link

        Umm so if we say int led==1; then we compare and say led is equal to 1 but there is no assignment so code will not work because there is no Value and nothing to Do but just an equality defining.. true? :(

        Reply

        Stan

      • Feb 8, 2017 - 3:09 PM - hans - Author: Comment Link

        Ehm, if I understand you correctly: yes 

        So “led==1” can only result in 1 of two values: true or false.
        In your example, “led==1” would be replaced with one of these values.
        So the sentence would become “int false;” or “int true;” which makes no sense for the compiler. 

        Note different programming languages handle this differently. One reason why I prefer Pascal. 

        Reply

        hans

        • Feb 8, 2017 - 3:22 PM - Stan Comment Link

          Hmm . Hehe i dont think i will ask about pascal!!  I will continue on C. :) but i realy getting the logic. Thank you Hans. 🤓

          Reply

          Stan

          • Feb 8, 2017 - 3:35 PM - hans - Author: Comment Link

            haha, one language at a time 
            And … you’re most welcome!

            hans

  • Feb 8, 2017 - 11:49 PM - Stan Comment Link

    Umm i got another confusion about the Order of coding… in this example we make a basic boolean function and print it ; 

    boolean A;

    void setup() {

      Serial.begin(9600);

    A = 5 < 2; 

      Serial.print(“A = “);

      Serial.println(A);

    }

    void loop() {

    }

    First we tell there is a Boolean type data and we give a variable name (A) and we give a value (5 < 2) then we tell to print A , then so it checks and shows as false or true. Very nice. But i still cant decide whats the order of it. What if i write “boolean A; ” and also “A = 5< 2; ”  Above void setup? Or what of i write them Into void setup. I clearly getting the Logic but i yet dont know what to put where to write an example on my own which is so sad!

    Reply

    Stan

    • Feb 9, 2017 - 8:53 AM - hans - Author: Comment Link

      Hi Stan,

      well, we can define a variable (A in your example) anywhere we’d like. However, the location where we define the variable will determine it’s “scope”. We can define outside of every function (so outside of void setup() and void loop()), then this means the variable is known and accessible anywhere in the code. However, if we define the variable inside a function then the variable will only be know within the function.

      In the end, it depends on where the variable needs to be seen. So if you need “A” in all functions, then your example is the easiest way to use it. However, if you’d need “A” only in void setup(), then you’d define it in void setup() and the variable “A” will only exist there.

      There are a lot of reasons why we use these so called “scopes“. One would be using only “local” variable (defined within a function) to avoid that the variable by accident gets changed in another function. A reason to define a “global” variable (know throughout the entire program) is because we do need the variable in several different functions.

      Please note that a “local” variable, say a variable defined inside a function, ceases to exist once we exit that particular function.

      If you would write 

      boolean A = 5<2;

      before any of the functions, then this would work. However, it would not make much sense unless you write it specifically that way, so that at a later point you want to be able to “read” why the value of “A” was “false”. It would be more efficient to just write:

      boolean A = false;

      The reason to use A = 5<2; in your code is because in your code you might be doing some sorts of calculation or comparison where “5” and/or “2” are replaced by other variables.

      Reply

      hans

      • Feb 9, 2017 - 11:09 PM - Stan Comment Link

        Hi Hans. Well i know about variable locations as Global and Local in ur magnificant article and i totaly get it. I just wanted to know why u seperate and write boolean A; above void setup but define A as A = 5<2; in void setup. So i guess its just ur personal choice it ok. I got it. But i dont think i will define it like boolean A = 5< 2; .  Because first i want to define boolean data type as bolean A; and then give a value as A=5<2 ; .Becauae i will use data types for arduino first to tell the variables as Global variables above void setup and give values to them in void setup. So i think we ok about this as in my need

        Reply

        Stan

        • Feb 10, 2017 - 8:36 AM - hans - Author: Comment Link

          The datatype is indeed boolean, but you have to keep in kind that comparing “5<2” will result in a boolean (true or false) as well. See it as a calculation.

          For example, let’s say

          int ANumber;
          ...
          ANumber = 1 + 2; // this results in ANumber having the value 3 // since it is the outcome of the calculation "1+2".

          So you can type all kinds of calculation after the “=” symbol.
          The compiler will do this calculation first and then store the outcome in the variable.

          One could have written this more complex as well:

          if(5<2) { 
            A = true;
          }
          else
          {
            A = false;
          }

          Obviously writing it this way is much more efficient:

          A = 5<2;
          Reply

          hans

          • Feb 10, 2017 - 8:48 AM - Stan Comment Link

            Buon your exaample you wrote ;

            boolean A; 

            to above void setup and you wrote ;

            A = “5<2”

            Now you say i need write;

            boolean A = “5<2” ?

            Stan

          • Feb 10, 2017 - 8:59 AM - Stan Comment Link

            Ok umm i say u wrote boolean A above void setup and u wrote A=”5<2″ Into void setup so i would like to ask of i write these to together into void setup OR together Above void setup. Becauae if i cant so i would like to know why

            Stan



Your Comment …

Friendly request to not post large files here (like source codes, log files or config files). Please use the Forum for that purpose.

Please share:
*
*
Notify me about new comments (email).
       You can also use your RSS reader to track comments.


Tweaking4All uses the free Gravatar service for Avatar display.
Tweaking4All will never share your email address with others.