Whether you're just starting out or have some experience with microcontrollers, understanding Arduino variable types is essential for effectively programming your Arduino projects.
Data types define how information is stored in variables
and manipulated in memory. This tutorial will provide an overview of the
main Arduino data types and demonstrate how you can declare them with
simple code snippets.
You can use Arduino Data types to define the type of data
that a variable can hold. Processors work on defined boundaries and for
the 8-bit Arduino Uno this is a byte boundary. it is an 8-bit processor.
The processor has to know how many bytes that each type of information
If types did not exist then you would be limited to using 8
bits and only able to store values from -128 to 127 ! By using the
integer type you can use and manipulate values from -32,768 to 32,767.
(the type 'long', allows even larger whole numbers).
Even though the processor is only capable of working with 8
bit entities, it uses a carry flag to allow information to be "carried
over" to the next byte for calculation. It means you can have arithmetic
operations on large numbers that occupy more than a single byte of
As a programmer you need to be aware of the "type" of a variable so that is capable of holding the values you expect to use.
Types allow the compiler to allocate the right amount of
memory for the variable and to perform the correct arithmetic operations
As well as whole number arithmetic, another type is 'float', that while still operating using 8bits, treats those bits in an entirely different way allowing floating-point-number calculation. In addition you can use character types (type 'char') that code the 8 bit data into numbers that represent characters.
In the Arduino programming environment, variables allow you
to store and work with different pieces of data within your sketches.
Before declaring a variable, you need to specify its data
type which tells the microcontroller how much memory space to allocate
and what type of data can be stored there.
Common Arduino variable types are:
The basic unit of memory in any processor is a byte but in fact in C/C++ programming the byte type is not usually defined.
The 'char' type is the usual way of writing (In non-Arduino code) that you want to use a single byte of data for your variable:
In Arduino code you can write:
Note: if you want to use the word byte in code other than Arduino, you can define your own type as follows:
typedef char byte;
Now you can write (in any C/C++ programming environment):
There are three fundamental whole number (or integer types):
In the Arduino Environment these are of length:
Now the next thing to know about them is that they all come in two flavours!
Using a method called two's complement
you can easily do addition and subtraction (by only adding!). [the
method is to invert all the bits in the bytes and then add 1 - this will
make the number negative. Try it and see i.e. choose a number say
11 then perform 2's complement on another number (3 say). Add them
together and you will get a result of 8].
Now, the only reason for saying the above is that it is quite easy to allow integer types to hold negative or positive numbers (the left most bit - if set - indicates a negative number). Here are the range of values for the three integer types:
char: -128 to 127
int -32,768 to 32,767
long: -2,147,483,648 to 2,147,483,647
int 0 to 65,535
long: 0 to 4,294,967,295
So, you can choose to tell the compiler that you only want positive numbers...
unsigned char myUnsignedByte;
unsigned int myUnsignedInt;
unsigned long myUnsignedLong;
...or both negative and positive numbers (the default where you don't need to write the word signed - it is implied):
signed char myUnsignedByte;
signed int myUnsignedInt;
signed long myUnsignedLong;
It all depends on your application.
For instance if you needed to process numbers above 32768 but below 65535 you would use an unsigned int.
You could ask the question why not use a 'long' type variable?
The answer is you could but it would be less efficient (slower and would use more memory).
Oddly enough the C/C++ language does not specify how many
bits are to be used in an integer type. This makes the language more
flexible because it can cope with different processor architectures.
For instance if you use a 32 bit processor, it is more work
to split the 32 bits into blocks of 16 so an integer will probably be
represented by 32 bits; so a bit of memory is wasted but it will be far
faster, and the 32bit microcontroller probably has lots of SRAM memory
This sounds fine, but when you come to moving a program from
one processor to a different one, it may or may not work. This sounds
counter intuitive but here's an example.
Lets say you have made a counter using a unsigned int and
you know that the range of values that the counter can adopt are 0 ~
65535. Your program relies on this operation i.e. that increasing the
value when you get to 65535, resets the counter to zero (the 16 bit int
hold a number bigger than this).
Now, moving to a 32 bit processor may allow the range of
values from 0 ~ 4,294,967,295 i.e. entirely different operation. Note, I
say may because it depends on how the compiler implements type int.
You have to know about the number ranges represented using
each specific Arduino variable type so that your program will work. For instance
number greater than the maximum allowed positive value for a signed int
will result in a
negative number (because of how the number is interpreted).
When moving to different processor architectures, the bit size
of the fundamental types may be different, as the C/C++ standard does not
Written by John Main who has a degree in Electronic Engineering.
Note: Parts of this page were written using chatgpt as a research assistant.
Have your say about what you just read! Leave me a comment in the box below.
Don’t see the comments box? Log in to your Facebook account, give Facebook consent, then return to this page and refresh it.