Hallberg Gary - First Steps With Arduino (Arduino Short Reads. Book 1) - 2020
Hallberg Gary - First Steps With Arduino (Arduino Short Reads. Book 1) - 2020
Gary Hallberg
The idea underpinning the Arduino short reads series is to provide a comprehensive, easy to follow
tutorial set and reference guide for anybody wanting to learn about Arduino and basic electronics.
Having a short reads series means that students and hobbyists can select key topics of interest in the
field with minimal outlay. The series aims to provide an easy introduction to all topics of interest and
expand on these topics to provide a broader and deeper understanding of that focus area. The books
are currently only available in Kindle format to provide an inexpensive package backed up by video
content and interactive social media.
The series is aimed at youngsters and adults interested in getting into electronics and it takes a modern
approach combining the use of the inexpensive software driven Arduino controller board with a
multitude of sensors and discreet electronic components. The experiments in this series of books are
easy to follow, inexpensive to implement and compelling for all interested in STEM education. I hope
to inspire anybody looking for a future career in technology or to simply to have fun.
The first book of this series looks at the Arduino microcontroller and explains its operation and purpose.
Experiments look to show you how to set up the programming environment and drive LEDs as well as
read input from switches, thermistors and photocells. Book 1 will give you a solid foundation of how
some basic electronic components work and how to use them to make simple designs.
Further books Arduino short read series are available or still being written, and will focus on the
following:
• Book 2 – Working with Displays (published)
• Book 3 – Controlling Motors (published)
• Book 4 – Range Finding, Object Detection and Object Avoidance
• Book 5 – Building a Simple Rover
There will be more books to follow the first 5 covering a wide range of focus topics so watch this space!
If you find this series of books useful then please leave your review and rating on
Amazon.
Follow North Border Tech Training on Facebook and Twitter for the latest news and
insights as to how this series will develop.
Foreword
It was a quite different world when I started to code and learn about electronics. As a child I would
spend my pocket money at the Tandy store and buy a few resistors one week, a few capacitors another
and a few transistors after that. I would buy magazines to learn how to build basic projects with my
collection of components. All great fun and it set me on my path to a future career. In the early 1980’s
my parents bought me what was then an expensive item. A Commodore 64 computer. I was hooked.
STEM education, if it even existed, was vastly different then compared to now. The presence of
computers in schools was very new and the notion of Information Technology in its infancy. It was that
infancy that inadvertently meant that technology teaching was successful. When computers entered the
classroom, there were no software packages at all. All you could do was program these early personal
computers yourself using the BASIC language and develop programs to solve specific problems. My
computer programming skills taught in school and coupled with my knowledge of electronics meant I
was well placed to enter a career at the very start of the information revolution. In that respect I believe
my generation was truly fortunate, as the way Information Technology (IT) was taught was later to
change.
It was apparent to me in the late 1990’s that IT education had moved away from teaching coding to
using computers with commercial software packages. This is understandable given the demands
employers placed on prospective employees having keyboard skills. The upshot was that plenty of
people were able to use computers, but too few people were able to program them.
Looking forward from now, technology will play a far greater role in modern society. For example, 5G
mobile has been introduced. This, coupled with the Internet of Things, increased automation and
Artificial Intelligence, will lead to a new technology revolution. There must be a change in grass roots
education to inspire and educate people to take on these challenges with the skills necessary to develop,
build and support this new infrastructure. The ideal of Science, Technology, Engineer and Mathematics
(STEM) education is there to fulfill this need.
So where does Arduino fit into all of this. Microcontrollers have been at the heart of many electronic
projects years before Arduino was conceived. However, they were relatively expensive and difficult to
program using 2nd generation languages such as assembler. A group of post graduate students in Italy
set out to create a platform what was both inexpensive to build and easy to program. The idea was that
non-engineers could use this device for electronic projects. Making the platform opensource also meant
that any manufacturer could make and sell the hardware. Take up of the platform was significant and
some 300,000 units were believed to have been sold by mid-2011 and some 700,000 by 2013. Arduino
is now an integral part of STEM education, along with other initiatives such as Raspberry PI and BBC
micro:bit.
I hope the reasons for this success become apparent through the course of this book and others in the
series. I hope you learn much and enjoy the journey.
Gary Hallberg, North Border Tech Training
Prerequisites for this Book
There are no prerequisites of this book. It is written for the total beginner with no previous knowledge
of Arduino, coding or electronics.
Download the Code
You can download the Arduino Code for the exercises in this book from GitHub using the link below.
https://github.com/ghallberg-nbtt/shiny-guide
I recommend that you do this as I have removed some of the comments from the code in the book
listings to aid readability in print form. I strongly recommend that you comment your code heavily to
facilitate understanding and to become familiar with best engineering practice.
Chapter 1: What is Arduino
Arduino Limits
All electronic devices have limits and we need to aware of those limits. If we exceed them, then we can
destroy the component. We often state these limits in terms of minimum and maximum voltage,
maximum current and maximum power dissipation. The limits for the Arduino Uno are shown in table
1-1.
Microcontroller ATmega328P
Operating Voltage 5V
Input Voltage (recommended) 7-12V
Input Voltage (limit) 6-20V
Digital I/O Pins 14 (of which 6 provide PWM output)
PWM Digital I/O Pins 6
Analog Input Pins 6
DC Current per I/O Pin 20mA
DC Current for 3.3V Pin 50mA
Flash Memory 32 KB (ATmega328P) of which 0.5 KB used by
bootloader
SRAM 2 KB (ATmega328P)
EEPROM 1 KB (ATmega328P)
Clock Speed 16 MHz
LED_BUILTIN 13
Length 68.6 mm
Width 53.4 mm
Weight 25g
Figure 1-6: An Arduino Board Fitted with the Adafruit Wave Shield.
Image source: Adafruit Industries
Summary
This chapter is an introduction to Arduino and the most significant boards within the Arduino
ecosystem. You have become familiar with the function of microcontrollers and you have had an
introduction to the purpose of the header pins of the Arduino Uno. You have learnt that the Arduino
Uno is the most widely supported Arduino board and this should be your first choice of board to use.
The Arduino Uno is the variant of board that is used throughout this book. You are aware that the
Arduino Uno has limits in terms of what it can deliver in voltage and current.
Chapter 2: Essential Components
In this chapter we will take a closer look at the essential components needed to start your journey with
Arduino.
A Breadboard
A breadboard is a common and very inexpensive prototyping tool onto which you can build your
electronics and even mount an Arduino Micro or Nano. The breadboards that we are interested in fall
into two categories. The full size and half size variants. There are many other sizes to suit both smaller
and much larger projects. If you need to choose one size, then go for the full-size variant as some of the
projects in the later books in this series will require the space. Its handy to have a half size version as
well to mount on small platforms such as some robot chassis.
An image of a half size with a full size beadboard can be seen in Figure 2-3.
Figure 2-3: Half and Full-Size Breadboards
Image Source: The author
The full-size breadboard provides 830 tie-points. There are 4x 100 tie-point distribution strips
providing 4 power rails. The distribution strips run along the top and the bottom of the breadboard,
two each side. 630 tie points are in the central portion of the board. You will notice a gap along the
center line of the board. Integrated Circuit components are connected along this center line, with their
pins inserted in the holes either side. Half size breadboards provide 400 tie points also with 4
distribution rails.
Figure 2-4 will help better visualize how the connections are made in a breadboard.
Figure 2-4: Breadboard Connections
Image Source: Created in Fritzing with annotations by the author
You will also need some breadboard jumper wires. These wires are terminated with bare wire pins at
each end and are inserted into the holes of the breadboard. A few wires with a socket at one end and a
pin at the other are also useful to make connections to sensors and components that will not be located
on the breadboard. Figure 2-5 shows some breadboard jumper wires.
Opensource Hardware
It is worthwhile taking a closer look at the concept of Opensource hardware. The Arduino hardware was
developed by the project and was made Opensource. What this means is that the schematics were made
available to everybody and any manufacturer is free to reproduce these schematics in their own
products. Consequently, there are many manufacturers of clone Arduino boards. This is perfectly fine,
and you may want to use a clone board. Clone versions of the Uno are about one third of the price of an
authentic Arduino board. However, be aware that some clone boards do use low quality components
and quality assurance is lacking with some manufacturers. Always buy from reputable outlets. I often
use clone Uno boards from Elegoo. I have had no issue with these over several years. Adafruit Industries
offers a great range too. Figure 2-6 shows an Elegoo Uno R3 next to an authentic Arduino Uno R3. You
can see that the board layout and size are identical. The Elegoo product is treated as an authentic
Arduino Uno in the IDE the two can be interchanged on any project. Clone boards are often made
available as part of starter kits and these kits are great for acquiring all the components needed for the
projects in this book and others in one purchase.
Sourcing Components
The components needed for this book and the subsequent books are very inexpensive and widely
available. This issue is that resistors cost a few cents each. You may live close to a store that sells such
components, but most people will have to mail order them in. Buying few is impractical due to postage
costs and buying in bulk is a waste. In my opinion, the best way to begin is to buy an Arduino starter
kit. Authentic Arduino kits are quite expensive, but there are many cheaper kits available from clone
manufacturers. These kits will have a board, cable, breadboard, plentiful basic components and an array
of sensors that can be used for the experiments in other books of this series. At the start of each chapter
I will set out exactly what will be needed. I bought a starter kit some years ago and one is depicted in
Figure 2-8.
Figure 2-8: An Arduino Starter Kit from a Clone Manufacturer
Image Source: Elegoo Inc.
The Multimeter
A multimeter is not strictly essential to successfully complete the projects in this book. However, I want
to encourage readers to take an engineering approach to the exercises. This means gaining deeper
understanding of how components work. A multimeter is a useful tool to be able to characterize the
behavior of some of the components we use and so help develop that deeper knowledge. Also, some
components are small, and it is hard to read their values. Measurements will confirm the value and
whether a component is working.
Digital multimeters provide a great range of features for a small price. As somebody new to electronics,
you only need a basic meter. These can be as low as $10 and will measure voltage, current and
resistance. Spending in the order of $35 you can buy a unit that will measure capacitance, frequency
and temperature and will also test transistors and diodes. You will notice that digital multimeters
specify the number of counts. Generally, the higher the count, the more expensive the device. Counts
for a digital multimeter specify the display resolution rather than accuracy. For example, a multimeter
may have 6000 counts. What this means is that the unit will measure 5.999V, but when it measures 6V
the display will lose a digital and show 6.00V. Most projects undertaken by the hobbyist do not need a
great degree of accuracy and have a wide range of voltage tolerances. I personally would go a meter with
a lower count and more features than a high-count meter with fewer features for the same price. Like
the Arduino boards, always buy from a trusted source. Some cheap units are imported with poor
batteries that have already leaked and corroded the contacts before the product has even been used.
Figure 2-9 shows my collection of multimeters. I still like to use an analog meter simply because the
world can seem a little too digital at times and there is something nice about a moving coil meter.
Summary
In this chapter we looked at the essential components needed for Arduino projects. You learnt that you
need some form of Personal Computer or laptop. It does not have to be high powered. In fact, the IDE
can be run on a Raspberry Pi model 3 or model 4. Arduino has an IDE that needs to be loaded onto the
computer. You learnt what a breadboard is and why it is important. We also looked at what Opensource
means and why some clone Arduino boards are good value, but also to be aware of counterfeit boards.
You were provided with some guidance as to how to source electronic components. Finally, it is
recommended that you acquire a multimeter as it has may uses in adding deeper engineering learning
to your projects. It is also an invaluable troubleshoot tool. You have some guidance as to which
multimeter to look for and you have a basic understanding of digital multimeter counts.
Chapter 3: Installing the Arduino IDE
In this chapter we will look at how to install the Arduino IDE onto Windows and Raspberry Pi
computers and we will look around the IDE to give you enough information to get started.
void loop() {
// put your main code here, to run repeatedly:
}
Listing 3-1: The Default Sketch Code
There are two areas. One is labelled as setup and the other loop. Let us not worry about the brackets
and void statements at this stage. Code that needs to be run at the start and executed only once should
be placed in the setup area. This would include setting the I/O pins of the Arduino as input or output
and initializing the serial monitor. All other code should be place in the loop area. The loop as the name
implies will run forever unless terminated in code, power removed from your Arduino or the Arduino’s
reset button is pressed.
When you connect a board to the IDE via a USB cable, you will need to tell the IDE what type of board
it is. As shown in Figure 3-4, select Tools > Board and ensure your board type is selected.
Summary
In this chapter you learnt about the purpose of the Arduino IDE and how it can be obtained. You learnt
how to load the software on a Windows based computer and a Raspberry Pi model 3 or model 4.
You learnt the function of the key elements of the IDE and that Arduino programs are called Sketches.
You learnt how to associate a board type with the IDE and how to associate a COM port with the board.
You looked briefly at the default code and learnt that the setup area is for code that only needs to execute
once, and all other code should be placed in the loop area.
Chapter 4: Digital Output Pins, LEDs and
Resistors
In this chapter you will learn how to set the general purpose I/O pins of an Arduino Uno to digital
outputs. These outputs pins will be used to power Light Emitting Diodes (LEDs). So as not to burn out
the LEDs, you will learn the purpose of resistors, current, voltage and their relationship.
Experiment 1: Blink
When we start to learn a new computer language, we always tend to start with a ‘Hello World’ type of
program. It is always a simple program that prints ‘Hello World’ to the screen. In the Arduino
programming language, we have ‘blink’. Blink is usually the first program that we load onto our boards
when first getting started. Here in this book is no exception.
Rather than type the code you can load it from the examples section of the IDE. Select File >
Examples > 01.Basics > Blink. The program from the IDE is shown in Listing 4-1. A few comments
are removed to make it read better in print.
/*
Blink
Turns an LED on for one second, then off for one second, repeatedly.
Most Arduinos have an on-board LED you can control. On the UNO, MEGA and
ZERO
it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN is
set to
the correct LED pin independent of which board is used.
If you want to know what pin the on-board LED is connected to on your
Arduino
model, check the Technical Specs of your board at:
https://www.arduino.cc/en/Main/Products
http://www.arduino.cc/en/Tutorial/Blink
*/
// the setup function runs once when you press reset or power the board
void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
}
The first thing note is that the code will loop forever. The line:
digitalWrite(LED_BUILTIN, HIGH);
will send pin 13 into a high state and turn on the built in LED.
There is then a delay of 1000ms (equivalent to 1 second) and the LED is turned off. After another delay
of 1 second, the code loops.
That is all there is to it.
Connect your Arduino to your PC via a USB cable and click the arrow button on the IDE ribbon the
upload and run the Sketch.
Congratulations, your first successful program!
Ohm’s Law
So, what is the relationship between Voltage and current? You can view a static charge as voltage. It is
the electrical potential for current flow from positive charge to negative charge. Before we look at any
equations, let us think about two scenarios. A store of charge could be a battery. It has positive and
negative terminals. If we place a conductor such as a metal wire directly between the battery terminals.
The battery will discharge very quickly in the form of a short circuit. This would normally be
accompanied by a flash and lots of heat, so do not try this at all. I am just envisioning one extreme! The
battery would discharge very quickly and so the electrons will be flowing extremely quickly from the
negative terminal to the positive terminal. Therefore, the current will be extremely high. At the other
extreme, let us not connect anything between the terminals. The battery will hold its charge. No
electrons will flow and so the current is zero. In all electrical and electronic circuits, we want to control
the flow of electrons to the positive terminal. We want to provide resistance to the flow so that battery
does not discharge too fast. That is the basic function of a resistor.
Georg Simon Ohm was the first to quantify the relationship between voltage, current and resistance.
Take the circuit diagram in Figure 4-2 as an example.
Figure 4-2: A Circuit to Define Ohm’s Law
Image source: The author
The electrical potential between the positive and negative terminals is quantified by the voltage, V. A
resistor, R, will restrict the current that will flow from positive to negative. The current flow is indicated
by the letter ‘I’. The resistor has a standard symbol and is represented by the zig zag. It can also be
represented by a rectangular box.
If the resistance is constant, then the current that flows is directly proportional to the voltage. It can be
represented by the equation below that is ohms law.
𝑉
𝐼=
𝑅
In electronic circuits, voltage is measured in Volts and is represented by the letter ‘V’. Current is
measured in amperes and is represented by the letter ‘A’. Resistance is measured in ohms and is
represented by the symbol ‘Ω’. We often use the letter ‘I’ in diagrams to represent current as it signifies
the intensity of the flow of electrons, but the unit is amperes.
This theory will give you a solid foundation to a better understanding of electronics. You will use it all
the time. We will put it into practice in Experiment 2.
The Resistor
In the previous section you were introduced to the concept of resistance. This is realized in the form of
the resistor. The resistor is the most common electronic component. Figure 4-3 is an illustration of two
modern resistors and shows how their resistance value is encoded onto them.
Figure 4-3: Two Resistor Types and their Color Coding
Image source: The author
In the example shown in Figure 4-3, there are two common types of resistor. Carbon Film resistors are
normally beige in color and have a total of 4 color bands to identify the value and tolerance of the
resistor. The other type is a Metal Film resistor. These are normally deep blue in color and have a total
of five bands to identify the value and tolerance.
Tolerance is a measure of the accuracy to which the resistor is manufactured. Metal Film resistors are
usually within +/- 2% of their nominal resistance value and the Carbon Film type +/- 5%. For hobby
electronics (in fact most professional projects too) +/- 5% is fine.
In the example shown in Figure 4-3, both types of resistor are 220Ω. For the Carbon Film resistor, the
first two bands identify the first two digits of the value, red and red equates 2 and 2. For the Metal Film
resistor type, the first three bands identify the first three digits of the resistor value. Red, red and black
equates to 2, 2 and 0.
The third and fourth band respectively, are multipliers. The Carbon Film resistor the third color is
brown, so the first two digits are multiplied by 10. This equates to a total value of 220Ω. For the Metal
Film resistor, the color of the fourth band is black and so the first 3 digits are multiplied by 1 to indicate
a total value of 220Ω.
You will find that resistors are manufactured in a standardized set of values rather than any value. These
are called preferred values. There are more preferred values for the Metal Film resistors compared to
Carbon Film resistors. As an extra exercise, look on the Web to better understand the preferred resistor
vales and practice reading the color codes.
Now on to look closer at Light Emitting Diodes.
void loop()
//repeat forever
{
digitalWrite(LED, HIGH); // Set the LED pin high
delay (1000); // On for 1 second
digitalWrite(LED, LOW); // Set the LED pin high
delay (1000); // Off for 1 second
}
void setup()
{
pinMode (RED1, OUTPUT); // Set the pin as an output
pinMode (AMBER1, OUTPUT); // Set the pin as an output
pinMode (GREEN1, OUTPUT); // Set the pin as an output
pinMode (RED2, OUTPUT); // Set the pin as an output
pinMode (AMBER2, OUTPUT); // Set the pin as an output
pinMode (GREEN2, OUTPUT); // Set the pin as an output
}
void loop()
//repeat forever
{
sequence1(); // Call sequence 1
sequence2(); // Call sequence 2
sequence3(); // Call sequence 3
sequence4(); // Call sequence 4
}
void sequence1() {
digitalWrite(RED1, HIGH); // Set the Red light 1 high
digitalWrite(AMBER1, LOW); // Set the Amber light 1 low
digitalWrite(GREEN1, LOW); // Set the Green light 1 low
digitalWrite(RED2, LOW); // Set the Red light 2 low
digitalWrite(AMBER2, LOW); // Set the Amber light 2 low
digitalWrite(GREEN2, HIGH); // Set the Green light 2 high
delay (1000); // Delay 1 second
}
void sequence2() {
digitalWrite(RED1, HIGH); // Set the Red light 1 high
digitalWrite(AMBER1, HIGH); // Set the Amber light 1 high
digitalWrite(GREEN1, LOW); // Set the Green light 1 low
digitalWrite(RED2, LOW); // Set the Red light 2 low
digitalWrite(AMBER2, HIGH); // Set the Amber light 2 high
digitalWrite(GREEN2, LOW); // Set the Green light 2 low
delay (1000); // Delay 1 second
}
void sequence3() {
digitalWrite(RED1, LOW); // Set the Red light 1 low
digitalWrite(AMBER1, LOW); // Set the Amber light 1 low
digitalWrite(GREEN1, HIGH); // Set the Green light 1 high
digitalWrite(RED2, HIGH); // Set the Red light 2 high
digitalWrite(AMBER2, LOW); // Set the Amber light 2 low
digitalWrite(GREEN2, LOW); // Set the Green light 2 low
delay (1000); // Delay 1 second
}
void sequence4() {
digitalWrite(RED1, LOW); // Set the Red light 1 low
digitalWrite(AMBER1, HIGH); // Set the Amber light 1 high
digitalWrite(GREEN1, LOW); // Set the Green light 1 low
digitalWrite(RED2, HIGH); // Set the Red light 2 high
digitalWrite(AMBER2, HIGH); // Set the Amber light 2 high
digitalWrite(GREEN2, LOW); // Set the Green light 2 low
delay (1000); // Delay 1 second
}
Listing 4-3: The Traffic Light Code
Code source: The author
You can now see that code in the main loop function is very concise. It simply calls the light sequence
in the order that we want them. It is also easy to change the lights for any sequence and the delay just
by editing the code in the relevant function. Hopefully, you can see the benefits of structuring your
code in this way.
Figure 4-10 is the breadboard layout for this experiment and Figure 4-11 is the associated schematic.
Time to build the circuit and test the code. You can see a demonstration of this project working in the
short video here (https://bit.ly/32bQKAP).
Summary
This was a big chapter with some especially important concepts. You learnt how to set Arduino I/O pins
as outputs and blinked the internal LED of the Arduino board. You learnt of the relationship between
voltage, current and resistance using ohms law and learnt about two types of resistor and how to read
their values. You learnt about the characteristics of an LED and you put this knowledge to work by
blinking an external LED. You learnt about the basics of using a multimeter to check your ohms law
calculations.
Finally, you built a more complex LED based project to control a sequence of traffic lights and applied
some top down software design techniques to produce structured and modular code using the concept
of functions.
Chapter 5: Digital Inputs and Switches
In this chapter we will look at how to configure the Arduino board to accept digital inputs from a switch.
You will learn about some important mechanical limitations of switches and how to negate the effect of
those limitations with Arduino Code. You will also learn about the importance of pull up and pull-down
resistors.
void setup()
{
pinMode (SWITCH, INPUT); // Set the pin 2 as input
pinMode (LED, OUTPUT); // Set the pin 8 as output
}
void loop()
//repeat forever
{
buttonState = digitalRead(SWITCH); // read button
// check if the pushbutton is pressed.
if (buttonState == LOW) {
// turn LED on:
digitalWrite(LED, HIGH);
} else {
// turn LED off:
digitalWrite(LED, LOW);
}
}
Listing 5-1: The Sketch to Turn on an LED with a Switch
Code source: The author
Debouncing a switch
Turning a light on when we press a switch only to turn it off when we release it, is all well and good. It
would be more useful if we are able to turn the light on and then turn the light off when we press the
switch again. That will be out next experiment.
However, this gives rise to an interesting characteristic of switches. A switch is a mechanical device.
What happens when we press the switch is that the contacts bounce. For a fraction of a second the
contact is made and broken until such time as the switch contacts settle. If this were to happen when
we press the switch once to turn on the light and then again to turn it off, the bounce would lead to a
random state as to whether the light will be on or off after each button press. Figure 5-7 illustrates the
behavior of switch showing the bounce action.
void setup()
{
pinMode (SWITCH, INPUT); // Set the pin 2 as input
pinMode (LED, OUTPUT); // Set the pin 8 as output
}
void loop()
{
currentButton = digitalRead(SWITCH); // Read the switch state
// Detect a button press
if (previousButton == HIGH && currentButton == LOW)
{
ledOn = !ledOn; // Toggle the LED state
}
previousButton = currentButton; // Reset button value
digitalWrite(LED, ledOn); // Change the LED state
}
Listing 5-2: A Sketch to Toggle and LED
Code source: The author
The key to understanding how this works is to visualize the fact the code is continually scanning for a
button change. You will need to declare a few Boolean variables with initial states. Boolean variables
have two states, ‘HIGH’ or ‘LOW’, or even ‘true’ or ‘false’. In fact, ‘HIGH’ and ‘true’ are predefined
constants with the value of 1. Likewise, ‘LOW’ and ‘false’ have the numerical value of 0. The Boolean
variables for our example are shown below:
boolean previousButton = HIGH;
boolean currentButton = HIGH;
boolean ledOn = false;
We need to detect changes in the state of switch, so we need to record the current button state and the
previous button state. Since we are using pull up resistors the state of the switch will be high until the
button is pressed. Therefore, the variables are set to ‘HIGH’ at the program start. We will also want to
toggle the state of the LED and this will be initially off and so we have set a Boolean variable ‘ledOn’ to
‘false’.
Now let us look at the main loop function.
currentButton = digitalRead(SWITCH); // Read the switch state
// Detect a button press
if (previousButton == HIGH && currentButton == LOW)
{
ledOn = !ledOn; // Toggle the LED state
}
previousButton = currentButton; // Reset button value
digitalWrite(LED, ledOn); // Change the LED state
First, the Sketch will read the button state. We next have a condition that will only change the state of
the LED if the button is pressed. The ‘if’ statement resolves a Boolean expression and if ‘TRUE’ toggles
the LED. The expression is:
previousButton == HIGH && currentButton == LOW
The double equals sign ‘==’ means ‘is equal to’ and the double ampersand (‘&&’) means logical AND. If
the previous button was ‘HIGH’ and the button has not been pressed, then the current button state will
be ‘HIGH’ too. This means the condition is ‘FALSE’ and so the LED is not toggled.
If the button is pressed, the Arduino pin will be set to a low state the previous button state is ‘HIGH’ and
the current button state is ‘LOW’. The Boolean expression is ‘TRUE’ so the code within the if statement
is executed and the LED toggled.
ledOn = !ledOn;
The ‘!’ symbol mean invert the current value of ‘ledOn’ and make it the new value of ‘ledOn’.
The previous Button state will be changed to ‘LOW’ and the new LED state is written to the output pin
to which the LED is connected. We need to set the previous button value to be current button value to
ensure that we make no changes to the LED state whilst the button is depressed. Only after we have
released the button and depressed it again, can the Boolean expression be ‘TRUE’ and we can again
toggle the LED.
Run the code. You will see that it works most of the time, but keep pressing, eventually you will see that
the LED flashes momentarily and does not toggle due to switch bounce. Now let us debounce the switch.
void setup()
{
pinMode (SWITCH, INPUT); // Set the pin 2 as input
pinMode (LED, OUTPUT); // Set the pin 8 as output
}
void loop()
{
currentButton = digitalRead(SWITCH); // Read the switch state
Bear in mind this program is scanning extremely fast for the button change and can read the switch
bounce as a valid state change. Now, after we read the switch, we ensure that the logic state has changed
from HIGH to LOW with the ‘if’ statement. The program then waits 5ms. This is enough for the switch
to settle and then we simply read the switch again.
A video demonstration for the switch debounce can be found here (https://bit.ly/2ANgZlK).
void setup()
{
pinMode (SWITCH, INPUT_PULLUP);
pinMode (LED, OUTPUT);
}
void loop()
{
currentButton = digitalRead(SWITCH); // Read the switch state
Summary
In this chapter you learnt how to configure the Arduino general purpose I/O pins to accept digital
inputs. You used switches to generate the digital inputs and learnt about the importance of pull-up and
pull-down resistors. You learnt how to debounce a mechanical switch with some simple code. In the
programming environment, you were introduced to the ‘if’ statement that allows you to place
conditions into your code to take branch actions based on the outcome of Boolean expressions.
Chapter 6: Reading Analog Inputs
Having the ability to read analog voltages on an input really opens a whole set of possibilities for your
Arduino based projects. There are many sensors that provide an analog voltage output. There are analog
sensors to measure temperature, water levels, distance from an object to name but a few.
The Potentiometer
The potentiometer or variable resistor is one of the most useful components. They are used in all sorts
electrical devices to adjust levels such as volume, tone, brightness and contrast. Before we go on to
Experiment 8 in which will look at potentiometers (or ‘pots’ for short), we will first take a closer look at
these devices.
The symbol for a potentiometer is shown in Figure 6-2. There are two variants of the symbol to consider
‘a’ and ‘b’.
Figure 6-2: Two Symbols for Variable Resistors or Potentiometers (Pots)
Image source: The author
Variant ‘a’ implies a component with two leads. In fact, it will have three. Variant ‘b’ is a three-lead
device. All potentiometers have two leads connected to a resistive material like any other resistor but
manufactured in the form of a track. They also have a third lead connected to wiper and this wiper
contacts the track. A spindle allows a human (or machine) to rotate the wiper so providing a variable
resistance between the end terminals and the wiper. Figure 6-3 shows the construction of a
potentiometer.
void setup()
{
Serial.begin(9600); // Initialize the serial monitor
}
void loop()
{
val = analogRead(POT); // Read the pot value
Serial.println(val); // Print the value to the serial monitor
delay(500); // Wait 0.5 seconds before next reading
}
Listing 6-1: A Sketch to Read an Analog Input
Code source: The author
Run the Sketch and open the serial monitor by clicking the serial monitor button on the righthand side
of the IDE’s ribbon. Turn the potentiometer wiper and the digitalized value should appear in the serial
monitor window as in Figure 6-8.
Thermistors
There is an array of different temperature sensors that can be controlled by the Arduino. Some more
complex and more accurate than others. By far the simplest and most inexpensive is the thermistor. All
resistors vary their resistance with temperature, with a thermistor the material is modified to produce
large variations in resistance for small variations in temperature. This change can be as much as 100Ω
per degree. There are two type of thermistors. Negative Temperature Coefficient (NTC) thermistors
reduce their resistance as the temperature rises and Positive Temperature Coefficient (PTC)
thermistors increase their resistance as the temperature rises. PTC thermistors can be used for
resettable thermal fuses, choking back the current as the temperature rises.
One drawback of thermistors is that their change in resistance is not linear with temperature. This can
be compensated for in software but can be tricky to do.
Figure 6-9 is a graph based on the properties of an NTC thermistor from Murata Electronics. You can
see that the area between -25C and +25C is highly nonlinear and so this will affect accuracy if not
compensated for.
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode (SWITCH, INPUT_PULLUP);
pinMode (ledLow, OUTPUT);
pinMode (ledNormal, OUTPUT);
pinMode (ledHigh, OUTPUT);
}
void loop() {
// put your main code here, to run repeatedly:
int tempReading = analogRead(temperaturePin);
double tempK = log(resistorValue * ((1024.0 / tempReading - 1)));
tempK = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * tempK *
tempK )) * tempK );
if (celsiusSelected) {
tempC = tempK - 273.15;
Serial.print ("Temperature :");
Serial.print (tempC);
Serial.println ("C");
} else {
float tempF = ((tempK - 273.15) * 9.0) / 5.0 + 32.0;
Serial.print ("Temperature :");
Serial.print (tempF);
Serial.println ("F");
}
//Set Alarm LEDs
if (tempK > 303.1) {
// High alarm at > 25C
digitalWrite (ledHigh, HIGH);
digitalWrite (ledNormal, LOW);
digitalWrite (ledLow, LOW);
} else if ((tempK <= 303.1) && (tempK >= 298.1)) {
// Normal light between 25C and 20C
digitalWrite (ledHigh, LOW);
digitalWrite (ledNormal, HIGH);
digitalWrite (ledLow, LOW);
} else {
// Low alarm less than 20C
digitalWrite (ledHigh, LOW);
digitalWrite (ledNormal, LOW);
digitalWrite (ledLow, HIGH);
}
previousButton = currentButton;
delay (500);
}
A floating-point variable is one that may have a non-integer value, i.e. it can have a fraction associated
with it. The temperature could be 23.45C. If we declared the temperature as an Integer value, then we
would only record 23C.
Everything else in the declaration and setup parts we have covered before in this book. Let us focus now
on the main loop.
First, we take a reading from the thermistor connected to the Arduino on analog pin 0. The value is held
in the variable ‘tempReading’. We declared ‘tempReading’ as an integer value locally within the main
loop.
Next, we declared a double length Integer to calibrate the reading from the sensor taking into account
the resistor value chosen to make up the potential divider. Note this is not the actual temperature in
Kelvin, but programming allows to reuse the variable ‘tempK’. Having one variable to do a job of two
saves memory space but can be come at the expense of readability of the code. We set a constant value
called ‘resistorValue’ to 10000 early in the code.
double tempK = log(resistorValue * ((1024.0 / tempReading - 1)));
You will be wondering where this formula came from. There are a lot of examples of how to use various
components with the Arduino. The NTC thermistor is one of those. It makes sense to reuse the work
that is placed in the public domain for engineers to reuse. Well worth checking the examples on the
official Arduino site (http://www.arduino.cc).
Next, we need to take the resultant ‘tempK’ and convert it to an actual temperature in Kelvin. Again,
there is a standard formula to do this.
tempK = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * tempK * tempK
)) * tempK );
We now have a temperature in Kelvin. The next phase of the code looks to the switch to see if Celsius
or Fahrenheit is selected. Pressing the switch will toggle between the two. Therefore, we can reuse the
code from the toggle LED exercise and add the debounce code.
Notice that we have added some extra text to print to the serial monitor to make the serial monitor
output more user friendly.
Also note we have added an ‘else’ to the ‘if’ code. We need the ‘else’ statement because there are
two definite actions we want to execute on checking of the button. If Celsius is selected, then print the
temperature in Celsius. Else Fahrenheit must have been selected so print the temperature in
Fahrenheit.
The next section of code deals with the alarms. We are using a set of nested ‘if’ and ‘else if’
statements with an explicit ‘else’ in last place to catch the low alarms status. Notice that we have used
the ‘>’ to signify greater than and ‘>=’ to signify great than or equal to. Finally, ‘<=’ means less than or
equal to.
We have added a 500ms delay to the code. This is important so that we do not overwhelm the serial
monitor that is set to only process data at 9600 baud or 9600 bits per second. At that rate we could
easily pass data to the serial monitor faster than it can process it. This delay is the reason why we need
to press the Celsius/Fahrenheit button for over 0.5 second for it to work. Bear in mind that this code is
drawn from the code we set to toggle the LED. In that Sketch there was no delay and the program was
scanning the button so fast that it could detect the switch bounce. Here, we have added a delay.
Therefore, there is a chance we will press and release the button within that 500ms period. Therefore,
we must hold it for it for least that duration. We could initiate an ‘interrupt’ in the code to initiate the
button press immediately, but that topic is beyond the scope of this introductory book.
You can see a demonstration video of this experiment that can be found here (https://bit.ly/3ffrIUR).
Summary
In this chapter you learnt about reading analog voltage inputs from external sensors. You were
introduced to the concepts of Analog to Digital Conversion (ADC) and quantization techniques. You
learnt about the limitations of quantization and how you can minimize quantization errors. You learnt
about potential dividers and what role they play in interfacing analog sensors to the Arduino. You
looked at variable resistors that are also called potentiometers. You looked at an analog sensor in the
form of a thermistor and learnt about NTC and PTC types.
On the coding side you were introduced to more variable types (‘double’ and ‘float’) and looked at
more complex ‘if else’ conditions to add branches to your code. You were guided toward using
datasheets and public domain code examples to find complex formulae that may be needed to generate
useful output from uncalibrated analog sensors.
Chapter 7: Pulse Width Modulation
So far, we have looked at how to use digital outputs, digital inputs and analog inputs. The final area to
learn about at the introductory level is to look at how to write analog signals to a pin using the
‘analogWrite’ function. The issue here is that we cannot write an analog voltage to a pin of an Arduino
Uno. The Arduino Duo does have a Digital to Analog converter on board, but the Uno does not.
However, we do have available a clever technique called Pulse Width Modulation. This can be used to
trick the eyes and brain into thinking a component such as an LED is being controlled by an analog
voltage. PWM can also be used to control the speed of a DC motor.
void loop()
{
for (int i = 0; i < 256; i++) // step up brightness
{
analogWrite(LED, i); // control LED
delay(10);
}
for (int i = 255; i >= 0; i--) // step down brightness
{
analogWrite(LED, i); // control LED
delay(10);
}
// step through 0%, 25%, 75% and 100% duty cycle
analogWrite(LED, 0); // 0% duty cycle
delay (1000);
analogWrite(LED, 63); // 25% duty cycle
delay (1000);
analogWrite(LED, 127); // 50% duty cycle
delay (1000);
analogWrite(LED, 191); // 75% duty cycle
delay (1000);
analogWrite(LED, 255); // 100% duty cycle
delay (1000);
}
// define variables
int redValue;
int greenValue;
int blueValue;
void setup()
{
pinMode(RED, OUTPUT);
pinMode(GREEN, OUTPUT);
pinMode(BLUE, OUTPUT);
// main loop
void loop()
{
// Turn off all LEDs at start
digitalWrite (RED, LOW);
digitalWrite (GREEN, LOW);
digitalWrite (BLUE, LOW);
for (int i = 0; i < 256; i++) // step up brightness of red color
{
analogWrite(RED, i); // red LED control
delay(10);
}
for (int i = 255; i >= 0; i--) // step down brightness of red color and
step up green
{
analogWrite(RED, i); // red LED control
analogWrite(GREEN, (255 - i)); // green LED control
delay(10);
}
for (int i = 255; i >= 0; i--) // step down brightness of green color
and step up blue
{
analogWrite(GREEN, i); // green LED control
analogWrite(BLUE, (255 - i)); // blue LED control
delay(10);
}
delay (1000);
// Random colors
for (int i = 0; i < 30; i++) // step through 30 times
{
// Generate random numbers for each color
int randRed = random(255);
int randGreen = random(255);
int randBlue = random(255);
analogWrite(RED, randRed); // red LED control
analogWrite(GREEN, randGreen); // green LED control
analogWrite(BLUE, randBlue); // blue LED control
delay(1000);
}
}
Photocells
I want to go on to one last exercise before concluding this book. We shall build a night light controlled
by the ambient light level. This is an easy project to make, but it will also introduce you to an especially
important function and we will discuss that later. First, we need to look closer at the light sensor and
that is the photocell. Photocells are also called Light Dependent Resistors (LDRs) or photoresistors.
Photocells are passive components that decrease their resistance when exposed to light. They are found
in all sorts of devices such light meters, night lights and light triggered alarms. In the dark, the
resistance of a photocell could be in the Megaohm range and as low as a few hundred ohms in the light.
Photocells come in many forms and can be made of different materials. The most common and lowest
cost variants are made with cadmium sulfide. Just like the thermistor, we will bias the photocell with a
10KΩ resistor to form a potential divider. Figure 7-4 show this arrangement with a picture of a typical
photocell.
Figure 7-4: A Photocell and Connectivity
Image source: The author
void setup()
{
Serial.begin(9600);
}
void loop()
{
val = analogRead(LIGHT); // Read the light sensor
Serial.println(val);
delay (500);
}
What no Motors!
I mentioned that PWM was a good technique for controlling the speed of DC motors. The obvious
exercise would be to drive some motors. The reason I did not include this exercise in this book is because
DC motors cannot be controlled directly from Arduino pins. The motors would draw too much current
and generate current when the pin goes low. Therefore, they need extra electronic circuitry to protect
the Arduino board. Since the objective in this book is to introduce the reader to the basics, I chose not
to cover this subject here. The subject does merit its own book given the numerous types of motors
available and is covered in Book 3 – Driving Motors.
Summary
In this chapter you learnt that you cannot write an analog voltage to an output pin of an Arduino Uno
but can use a technique called Pulse Width Modulation to emulate a true analog output. You learnt that
the technique is good for controlling the intensity lights and to control the speed of DC motors.
Although you cannot drive a DC motors directly from an Arduino output pin. You learnt about RGB
LEDs and about photocells. Finally, you understand the importance of the ‘map’ and ‘constrain’
functions when dealing analog input and outputs.
Epilogue
So, we have come to the end of this part of the journey and I hope to have given you a good grounding
in the basic capabilities of the powerful Arduino platform. There are many examples on the Web of how
to use the Arduino microcontroller for some very interesting projects, but the purpose of this book is to
give you all of the basic information you need in one place to get you started and present it in a clear
and systematic way. In the subsequent books in the series we will use this base knowledge to look at
other focus areas and create ever more challenging, creative and interesting projects. Whatever your
goals are, I hope to have inspired you and helped you some way to achieving those goals.
If you like this book and the series of books, please leave a review on the Amazon website. For the latest
news on other books in the series you can following my Facebook page, Twitter or follow me as an
author on Amazon.
About the Author
Gary Hallberg has over 34 years of experience in the telecommunications and data communications
industries. He started his career working with circuit switched voice and data technologies in PDH and
SDH environments and then moved on to work with early packet switched networks using Frame Relay
and ATM. His career shifted focus to IP routing when the Internet started to grow, designing large scale
service provider networks using leading edge equipment from vendors such as Juniper and Cisco. Gary
attained Cisco Certified Professional status during this time. Presently, he is working for a global
equipment vendor with a focus on Ethernet networks and is at the forefront of network evolution,
providing infrastructures for SD-WAN, Network Functions Virtualization, SDN and 5G backhaul. Gary
has a Bachelor of Engineering degree in electronic engineering and a Master of Philosophy degree in
robotics and manufacturing.