0% found this document useful (0 votes)
68 views

Hallberg Gary - First Steps With Arduino (Arduino Short Reads. Book 1) - 2020

1. Hallberg Gary - First Steps with Arduino (Arduino Short Reads. Book 1) - 2020

Uploaded by

Tihomir Mihaylov
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
68 views

Hallberg Gary - First Steps With Arduino (Arduino Short Reads. Book 1) - 2020

1. Hallberg Gary - First Steps with Arduino (Arduino Short Reads. Book 1) - 2020

Uploaded by

Tihomir Mihaylov
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 93

First Steps with Arduino

Book 1 of the Arduino Short Reads Series

Gary Hallberg

North Border Tech Training


First Edition
Copyright © 2020 Gary Hallberg and North Border Tech Training
All reserved. This book or any portion thereof may not be reproduced or used in any manner whatsoever
without the express written permission of the publisher except for the use of brief quotations in a book
review.
First Published, 2020
Contents
About the Arduino Short Reads Series ..................................................................................................... 5
Foreword.................................................................................................................................................... 6
Prerequisites for this Book ........................................................................................................................ 8
Download the Code ................................................................................................................................... 9
Chapter 1: What is Arduino ..................................................................................................................... 10
Understanding your Arduino Uno .......................................................................................................13
Arduino Limits ......................................................................................................................................15
Summary .............................................................................................................................................. 16
Chapter 2: Essential Components ............................................................................................................ 17
Video Material for Chapter 2 ................................................................................................................ 17
A Computer to run the Programming Environment............................................................................ 17
A Breadboard ....................................................................................................................................... 19
Opensource Hardware ......................................................................................................................... 21
USB Cable ............................................................................................................................................ 23
Sourcing Components ......................................................................................................................... 23
The Multimeter .................................................................................................................................... 24
Summary .............................................................................................................................................. 26
Chapter 3: Installing the Arduino IDE .................................................................................................... 27
The Cloud Based IDE ........................................................................................................................... 27
Installing the IDE onto a Windows Based Machine ........................................................................... 27
Installing the IDE onto a Raspberry Pi Machine ................................................................................ 28
The IDE Home Screen ......................................................................................................................... 28
Summary .............................................................................................................................................. 34
Chapter 4: Digital Output Pins, LEDs and Resistors .............................................................................. 35
Parts needed for this Chapter .............................................................................................................. 35
Experiment 1: Blink ............................................................................................................................. 35
Voltage, Current and Resistance ......................................................................................................... 37
Ohm’s Law ........................................................................................................................................... 38
The Resistor ......................................................................................................................................... 39
The Light Emitting Diode (LED) ......................................................................................................... 41
Experiment 2: Turning on an External LED ....................................................................................... 43
Experiment 3: Traffic Lights ............................................................................................................... 46
Summary .............................................................................................................................................. 50
Chapter 5: Digital Inputs and Switches .................................................................................................. 52
Parts needed for this Chapter .............................................................................................................. 52
Reading Input from a Switch............................................................................................................... 52
Experiment 4: Turn on an LED on a Button Press ............................................................................. 54
Debouncing a switch ............................................................................................................................ 57
Experiment 5: Latching the LED and Debouncing the Switch ........................................................... 57
Experiment 6: Debouncing a Switch ................................................................................................... 59
Experiment 7: Using Internal Pull-up Resistors ................................................................................. 61
Summary .............................................................................................................................................. 63
Chapter 6: Reading Analog Inputs .......................................................................................................... 64
Parts needed for this Chapter .............................................................................................................. 64
Analog to Digital Conversion ............................................................................................................... 64
The Potentiometer ............................................................................................................................... 65
The Potential Divider ........................................................................................................................... 66
Experiment 8: Reading the Potentiometer Value ............................................................................... 69
Thermistors ........................................................................................................................................... 71
Experiment 9: Temperature Measurement with High Low Alert ...................................................... 73
Summary .............................................................................................................................................. 78
Chapter 7: Pulse Width Modulation ....................................................................................................... 79
Parts needed for this Chapter .............................................................................................................. 79
An Overview of Pulse Width Modulation ............................................................................................ 79
Experiment 10: LED Brightness Control ............................................................................................ 80
Experient 11: The RGB LED ................................................................................................................ 82
Photocells ............................................................................................................................................. 86
Experiment 12: A Night Light .............................................................................................................. 87
What no Motors! .................................................................................................................................. 89
Summary .............................................................................................................................................. 90
Epilogue ................................................................................................................................................... 91
About the Author ..................................................................................................................................... 92
About the Arduino Short Reads Series

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 is an Opensource family of microcontrollers that can be easily programmed to drive


electronics. There is an extensive range of inexpensive sensors and output devices that can be controlled
by the Arduino board. It is ideal as an educational tool or be the central component of any number of
technology and IoT projects. The Opensource element of the design means that the controller can also
be integrated into any commercial projects and so the platform has appeal to educational
establishments, hobbyists and industry.
The first Arduino boards were released in 2006, although work on the project had started some years
earlier. As with all hardware, the product set has gone through many incarnations some of which are
retired now. The ‘classic’ Arduino board is generally accepted to be the Uno. This was first released in
2010 and was based on the Atmel ATmega328P microcontroller unit (MCU). The Arduino Uno has the
classic layout and header pin arrangement. The current version of the Uno is rev3 and it is this version
that is used throughout this book. The Arduino Uno is the board type that most students first start with.
Figure 1-1 is an image of an Arduino Uno. This image has the classic Dual Inline version of the
ATmega328P. It is this version and layout that most clone manufacturers replicate with their boards.
You will also see that there is a version of the Uno Rev3 that uses a surface mount version of the
ATmega328P. This board is directly compatible with the classic dual in line version and a little cheaper.
Figure 1-1 The Arduino Uno
Image source: Arduino.cc
Other noteworthy boards are the Arduino Mega 2560 and the Arduino Micro. An image of the Arduino
Mega 2560 can be seen in Figure 1-2.
Figure 1-2: The Arduino Mega 2560
Image source: Arduino.cc
The Arduino Mega 2560 employs a larger MCU, the Atmel ATmega2560. This larger MCU has 54
general Input/Output (I/O) pins compared the Uno’s 14 and 4 serial interfaces compared to the Uno’s
1.
Figure 1-3 is an image of the Arduino Micro.

Figure 1-3: The Arduino Micro


Image source: Arduino.cc
The Arduino Micro uses the Atmel ATMega32U4 MCU and provides 20 I/O pins. The board has a tiny
form factor and as you can see the from the figure. It is designed to be inserted into solderless bread
boards or header sockets.
The Arduino Leonardo is worth of mention as this has some specific and interesting uses that will be
explored in a later book of this series. The Arduino Leonardo is a microcontroller board based on the
ATmega32u4. It has 20 digital input/output pins of which 7 can be used as PWM outputs and 12 as
analog inputs. The Leonardo differs from other Arduino boards as the ATmega32u4 has built-in USB
communications. This eliminates the need for a secondary processor. This allows the Leonardo to
appear to a connected computer as a USB device such as mouse or keyboard. An Arduino Leonardo is
shown in Figure 1-4.

Figure 1-4: The Arduino Leonardo


Image source: Arduino.cc
As mentioned earlier, there are many more board types. Some have specialist form factors or are
enhanced with features such as built in WiFi and Bluetooth. As a useful exercise, it would be good for
you to take a closer look at the official Arduino website to see what other boards are available. Visit
https://www.arduino.cc/.
For now, we need to take a closer look at the Arduino Uno as this will most likely be your first type of
board and is used throughout this book.

Understanding your Arduino Uno


Figure 1-5 shows the Arduino Uno and identifies the various component parts of the system. It is not
important at this stage to understand their functions as these will be explored in the later exercises.
Figure 1-5: The Arduino Uno Component Parts
Image source: Arduino.cc with annotations by the author
Referring to Figure 1-5, we can look around the Arduino Uno and start to understand the functions of
the component parts. Along the top is a row of header pins. These are general I/O, PWM and
communication buses.
When we refer to a general I/O pin we have a pin that can be set to read a digital input and or a deliver
a digital output. They are numbered 2 to 13. A digital high state will be represented by a voltage level of
5V and a digital low by 0V. If a pin is set to be an input, it will read the voltage state from a senor or a
switch. If it is set to be an output, then it will supply a voltage of 5V when high and 0V when low. A pin
in an output state can be used to drive displays, lights, motors etc.
You will notice that pins 3, 5, 6, 9, 10 and 11 have a tilde (~) symbol next to them. This means that these
pins support Pulse Width Modulation (PWM) as an output option. PWM will be covered in chapter 7.
Pins A0 to A5 are analog inputs. These are useful for reading data from analog sensors such a
potentiometers, temperature or distance sensors.
The Arduino can be powered via the USB port. This does have limitations covered later in this chapter.
The unit can also be powered by the 7-12VDC barrel connector. If powered using an external power
supply, that supply voltage will be presented on the Vin pin and can be used to power external
electronic. The 5V and 3.3V supply those voltages, respectively. The ‘GND’ pins or ground pins provide
reference for all voltages and that too is covered later.
Some pins have dual or specialist functions. These pins can be used for I2C communications, serial
communications and interrupts. These functions are beyond the scope of this book but are covered in
later books of this series.

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

Table 1-1: The Arduino Uno Limits


For most of the time you will be powering your Arduino units via the USB port and the supply voltage
will be fixed at 5V from the USB port. Damaging your board by over voltage is not a major risk. However,
you should note that each pin can only supply a maximum 40mA of current. Drawing too much current
from a pin can damage the board. We will talk about voltage and current in chapter 4. Some devices
like Light Emitting Diodes (LEDs) are fine to driven directly by the Arduino pin, but components like
motors will draw much more current so driving these components directly by and Arduino pin could
damage your board. Also note that the Arduino UNO is only albe to supply 200mA in total, so not all
pins can be in a high state and drawing 40mA at the same time.
Also note the memory available on the Arduino Uno. It has 32Kbytes of memory in which to store a
program and only 2Kbytes of memory to store variables. This is one feature that differentiates MCUs
from computers. A modern computer in the form of a laptop may have a multicore Central Processing
Unit (CPU) with 4Gbytes on memory for storing variables (RAM) and 1TB of memory for storing
programs and data.
Put quite simply, MCUs are designed to control machinery. They read inputs from sensors and switches,
and in turn control output devices such as relays, solenoids, displays and the like. These devices,
therefore, need little in the way of human interaction. Simple switches and displays are the only I/O
devices needed. Think about how much processing and storage the complex graphical interfaces of the
modern computer needs and what complex tasks they are needed for. The world of the microcontroller
is much simpler. However, the Internet of Things is changing that paradigm to some degree and the
modern MCU requires much more in the way of connectivity and so there is a wide range of cards and
shields that augment the base function of the Arduino to provide features like WiFi and Bluetooth
communications. An Arduino shield is a component that is designed to plug directly into the I/O pins
of the Arduino to provide extra functionality. An example of a shield is shown in Figure 1-6.

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.

Video Material for Chapter 2


The associated video for this chapter can be viewed here (https://bit.ly/3gHg6u2).

A Computer to run the Programming Environment


In Chapter 3 we will take a closer look at the Arduino programming environment. Generically, such
programs are called Integrated Development Environments or IDEs. However, you will need some form
of computer to run the Arduino IDE. Luckily, the computer does not need to be powerful or expensive.
The IDE can run on Windows or Linux operating systems. In Figure 2-1, I am running the Arduino IDE
on a Raspberry Pi 4 computer. It works fine and so there are low cost, accessible options open to you if
your budget is tight. Details of how to load the IDE on Windows based machines and the Raspberry Pi
is covered in Chapter 3.
Figure 2-1: The Arduino IDE Running on a Raspberry PI 4 Computer
Image Source: The author
Figure 2-2 shows a more conventional setup with the Arduino board connected to a Windows laptop
via the USB cable.
Figure 2-2: An Arduino Connected to a Windows Laptop
Image Source: The author

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.

Figure 2-5: Breadboard Jumper Wires


Image Source: The Web (public domain)

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.

Figure 2-6: An Elegoo Uno next to an Authentic Arduino Uno


Image Source: The author
Having said that, beware that counterfeit Arduino products are available. These bear the Arduino logo
and look the same as authentic boards. They may work but may be made of substandard components
and sold at inflated prices. The rule is, always buy from a reputable seller.
USB Cable
The other thing you will need is a USB-A male to USB-B male cable to connect your Arduino to your
computer. One is shown in Figure 2-7.

Figure 2-7: A USB-A Male to USB-B Male Cable


Image Source: The author

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.

Figure 2-9: My Collection of Various Multimeters


Image source: The author
An automatic component tester is an alternative to a multimeter if you just want to test components
and check their values. These cost about $20 to $30. I built the one pictured in Figure 2-10 from a kit
and it is my preferred tester. I simply insert any comment and it detects what the component is and
measures any associated values. All I need do is press the button.
Figure 2-10: A Component Tester Built from a Kit
Image source: The author

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.

The Cloud Based IDE


The official Arduino Website offers a cloud-based IDE and tool set that can be accessed via a standard
Web browser. This will operate on any PC with an Intel based processor and running Windows or Linux
operating systems.
The tool set is aimed more at professionals and advanced users who may be working in teams on the
same project. Having a cloud-based IDE means that all teams members can access the project and
having a centralized repository means that team members are always working on an up to date copy.
For somebody just starting out in the area, I would recommend you use the standalone version of the
IDE that will be installed on your local machine.

Installing the IDE onto a Windows Based Machine


First go to the Arduino software download webpage using the following URL:
https://www.arduino.cc/en/Main/Software
Figure 3-1 shows the area of the website where you need to click to download the installer. There are
other options open to you, but assuming you have rights to install software on your PC, then choose the
installer.
Figure 3-1: The IDE Download Options for Windows
Image source: Arduino.cc
Once the installer has downloaded, simply click on the file and the program will install.

Installing the IDE onto a Raspberry Pi Machine


You can install the Arduino IDE onto any Linux based machine, but the installation may be too complex
for the user with no experience and so is beyond the scope of this book. However, installation onto a
Raspberry Pi running Linux is straightforward. The Raspberry Pi should be a model 3 or model 4 and
should be running Raspberry Pi OS Debian Buster or newer. Simply following the instructions below
with an open terminal.
sudo apt-get update && sudo apt-get upgrade
sudo apt-get install Arduino
That is all there is to it and you are ready to go.

The IDE Home Screen


Once the program has loaded, you will be presented with the screen shown in Figure 3-2.
Figure 3-2: The IDE Home Screen
Image Source: Arduino IDE
It looks simple and it is. At this point we will only look at the key functions to get you started.
Figure 3-3 focuses on the main controls.
Figure 3-3: The Main IDE Controls
Image source: The Arduino IDE with annotations by the author
The first point to note is that the code written for Arduino is referred to as a Sketch and we will take a
closer look at the default code later in this chapter.
Operations to open and close Sketches are obvious. The only button the note is the one that runs the
Sketch. Simply press that to upload code to the Arduino and the Arduino will run it.
Let us take a closer look at the default code in Listing 3-1. This is present for all new Sketches.
void setup() {
// put your setup code here, to run once:

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.

Figure 3-4: Selecting the Board Type


Image source: Arduino IDE
You will need to ensure that the correct ‘COM’ port is selected. Like all USB devices, it is simply a serial
port and is treated as such by your PC and so the IDE must know which communications port or ‘COM’
port your Arduino is attached to. Figure 3-5 shows what part of the IDE menu to select. Ensure that
your Arduino board is connected to your PC via a USB cable.
Figure 3-5: Selecting the COM Port
Image source: Arduino IDE
If your Arduino board is connected to your PC, you will be able to select the button at the righthand
side of the ribbon. This button activates the serial monitor. The serial monitor allows you to see
information sent from the Arduino board to the PC and allows you to send input to the Arduino boards.
More on the serial monitor in Chapter 6. Figure 3-6 shows how to access the serial monitor.
Figure 3-6: The Serial Monitor Button
Image source: Arduino IDE
There is one other aspect of the Arduino IDE to highlight that will be relevant for later books in this
series. Some sensors and motors have predefined software that should be loaded as part of your Sketch.
To do this you will need to load the relevant library from the cloud-based repository. There is a menu
item in the IDE that allows you to manage libraries. Figure 3-7 shows from where libraries can be
managed.
Figure 3-6: Managing Libraries
Image source: Arduino IDE

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.

Parts needed for this Chapter


• Arduino Uno or clone board
• Full or half size breadboard
• 6 x 220Ω resistors
• 2 x red LEDs
• 2 x yellow LEDs
• 2 x green LEDs
• Jumper wires

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

modified 8 May 2014


by Scott Fitzgerald
modified 2 Sep 2016
by Arturo Guadalupi
modified 8 Sep 2016
by Colby Newman

This example code is in the public domain.

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 loop function runs over and over again forever


void loop() {
digitalWrite(LED_BUILTIN, HIGH);
delay(1000);
digitalWrite(LED_BUILTIN, LOW);
delay(1000);
}

Listing 4-1: The Blink Sketch


Source: From the Arduino IDE examples
The Arduino Uno has a built in LED. It is built into pin 13 on authentic Arduino boards, but can be
different on some clone boards. All the program does is turn the LED on for 1 second and then off for 1
second and repeats forever. There are some useful things to note though.
The code starts with a comment block. The ‘/*’ marks the start of the block and ‘*/’ marks the end of
the comment block. All the text in between the markers is treated as comment by the complier and
ignored. A compiler converts the program as we see it into a binary format or machine code to be loaded
onto the Arduino.
You will notice some command preceded by ‘//’. These are one-line comments that can placed on their
own line or after a piece of active code. Commenting is useful in helping us understand our own code
and help others when we work in teams. Please get into the habit of using comments. Try to place a
comment per line. There is one line of active code in the setup area:
pinMode(LED_BUILTIN, OUTPUT);
This sets the I/O pin to output and this is needed to drive an LED with 5V when the pin is high. When
the pin is low the LED will be off as the voltage will be 0V. The ‘OUTPUT’ text is preceded by
‘LED_BUILTIN’. ‘LED_BUILTIN’ is a predefined constant with a numerical value of 13. This line tells
the compiler that Arduino pin 13 will be set to output. An alternative way to express this line is:
pinMode(13, OUTPUT);
The semicolon, ‘;’ terminates the line of code.
Let us look at the main code block in the loop area.
digitalWrite(LED_BUILTIN, HIGH);
delay(1000);
digitalWrite(LED_BUILTIN, LOW);
delay(1000);

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!

Voltage, Current and Resistance


We will go on now to create our first circuit and turn on an LED external to the Arduino board. However,
we do need to understand a little more about voltage, current and their relationship to each other.
Electricity is all around us. Electronics is about controlling this natural force to do useful things for us.
Electricity in a bolt of lightning is no different to what sometimes gives you a shock when you touch a
metal surface. In both these scenarios there is a stored charge of electricity. A good place to start is
understanding what charge is.
It starts with an Atom. Figure 4-1 is a crude illustration of the components of Lithium atom.
Figure 4-1: Components of a Lithium Atom
Image source: The author
The Nucleus of the atom is made up of three protons and three neutrons. Orbiting the nucleus are three
electrons. Protons are positively charged; neutrons have no charge and electrons are negatively
charged. In this state with three protons and three electrons, the Lithium atom has no overall charge as
the number protons and electrons balance.
It is, however, possible to dislodge electrons in an atom. In this case, the atom will have a net positive
charge and is referred to as a positive ion. It is also possible for an atom to capture a free moving
electron. In this case, the atom will have a net negative charge and is referred to as a negative ion. We
can collect positively and negatively charge ions on surfaces. The natural state would be for the extra
electrons of the negatively charged ions to be attracted to the positively charge ions. For this to happen
there needs to be a conductor between the positive and negative surfaces. Electrons can flow easily
through metals, gasses and a vacuum. These media are conductors. Without a conductor, the free
electrons cannot flow, and they form a static charge. It is this flow of free electrons that is the basis of
electric current.

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.

The Light Emitting Diode (LED)


Before we go onto the exercise, we first need to understand what an LED is and why we need a resistor.
An LED is a Light Emitting Diode. Like all diodes, it is a unidirectional device that allows current to
flow in one direction only. If the diode is reserved the current is blocked. An LED, like all diodes are
semiconductors. We will not go into any depth as to how semi-conductors work, but it is enough to
know that when electrons fill holes in positive ions, they emit energy in the form of light. All
semiconductors do so, but the light energy is exceedingly small. However, we can engineer the materials
in the LED to increase the quantity of light emitted.
Like all electronic components, the LED has a symbol and is shown in Figure 4-4.

Figure 4-4: The Symbol for an LED


Image source: The author
LEDs have two terminals called the Anode and the Cathode. If a positive voltage is connected to the
Anode and the Cathode connected to a negative terminal or ‘ground’, a current will flow through the
LED and it will emit light. If the LED is swapped around so that the Cathode is connect to the positive
terminal, the current will be blocked by the LED and it will not emit light.
Figure 4-5 is a picture of an LED. They come in ranges of colors, mainly: red, green, yellow and blue.
Figure 4-5: An LED
Image source: The Web (public domain) with annotations by the author
We will need to limit the current through the resistor. If current is flowing from Anode to Cathode, the
LED will behave like a piece of wire creating short circuit. The LED will burn out and the Arduino board
will most likely be damaged too due to the high current draw. Most LEDs have a current rating of 20mA
(0.020A) and the I/O pin of the Arduino is limited to 40mA. Let us use ohms law to select a resistor
value. Refer to Figure 4-6.

Figure 4-6: Selecting a Resistor Value for an LED


Image source: The author
We only have one unknown in the circuit in Figure 4-6. We desire a target current no greater than
20mA. I can also tell you now that when we pass current through a red LED, there will be voltage drop
of about 2V across that device. Do not worry about why this is so for now. This means with a 5V supply
and the Cathode of the LED connected to 0V, a voltage of 2V will be present on the Anode of the LED.
This means that 3V will be present across the resistor. So, the equation we need to solve is below:
𝑉 3
𝑅= = = 150𝛺
𝐼 0.02
150Ω is a preferred resistor value, but 220Ω is commonly used as it provides adequate light levels at
lower current consumption. Also bear in mind that some LED types will have a lower forward voltage
drop and so will draw more current. Therefore, we will go with 220Ω.

Experiment 2: Turning on an External LED


Let us take the ‘blink’ program a step further. In this Experiment, we will connect an External LED to
an Arduino pin and blink it on and off.
Go ahead and build the breadboard Layout shown in Figure 4-7.

Figure 4-7: The Breadboard Layout to Blink an LED


Image source: Created in Fritzing
All electronic circuits have a schematic and Figure 4-8 is the schematic associated with the breadboard
layout shown in Figure 4-7. Take some time to become familiar with the components and relate them
to your breadboard layout.
Figure 4-8: The Schematic to Blink and LED
Image source: Created in Fritzing
Open a new Sketch and type or load the code as in Listing 4-2.
/*
Flashing an external LED
Copyright 2020 Gary Hallberg
Licensed under MIT https://github.com/ghallberg-nbtt/shiny-
guide/blob/master/LICENSE
*/

const int LED=9; // Define LED for pin 9


void setup()
{
pinMode (LED, OUTPUT); // Set the LED pin as an output
}

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
}

Listing 4-2: The Sketch to Blink an External LED


Code source: The author
First, we need to define a more user-friendly notation for the pin to which we will connect the LED. We
can use just the I/O pin numbers but tracking that would be difficult in complex code. The line below
sets the integer constant LED to the value of 9.
const int LED=9;
Notice that this line resides outside of both the setup and loop areas. By doing that we make the constant
value LED available to all parts of the code.
Next, we need to set I/O pin 9 as output using the line of code below. This line is placed in the setup
area as we only need to execute this once.
pinMode (LED, OUTPUT);
Inside the loop area, we place the line below to blink the LED on and off for 1 second by setting the I/O
pin ‘HIGH’ and then ‘LOW’.
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

Run your version of the Sketch and check it operates as planned.


As an extra exercise, why not measure the current drawn from the Arduino I/O pin. From our
calculations the current would be 13.6mA using a 220Ω resistor and assuming that the voltage drop
across the LED is 2V. I want to encourage an engineering approach to learning and being familiar with
tools of the trade is very important. If you do not have a multimeter, then you can watch the short video
associated with this task (https://bit.ly/2ZaW9Wz). If you have a meter, first measure the voltage drop
across the LED. Set the multimeter to measure DC voltage and then connect the multimeter leads across
LED. Then set the meter to measure DC current. When measuring current the meter must be connected
in line with components and not across components. Figure 4-9 indicates how the meter should be
connected in both voltage and current mode.
Figure 4-9: Measuring the Current Drawn and the Voltage Drop across the LED
Image source: The author

Experiment 3: Traffic Lights


I want to stick with the concept of using just the I/O pins of the Arduino in output mode to control an
LED. This exercise is a little more engaging and will introduce you to the concept of software
engineering and the use of functions within your code. We will build a sequence for a pair of traffic
lights as they would be deployed in the UK. Maybe you could modify the code for your country’s own
sequence.
First let us understand what a software function is. A function is basically a block of code that adds
modularity to the program. This makes the code easier to read, easier to support, more concise and we
can make changes to a function without having to trawl through the main code or other functions.
There are in fact two functions in the basic Arduino program structure. These are the ‘setup’ and
‘loop’ functions. Let us consider just the ‘setup’ function.
void setup() {
}
The keyword ‘void’ means that this function will not return any value. We can create functions that
return values such as an integer, string or Boolean etc. Having and empty bracket set ‘()’ means that
we are not passing any values to the function. We can do this and will look at this in later books, but for
now let us focus on the basics. The code for the function is contained within the curly brackets ‘{}’.
For this Experiment we will need 6 LEDs and 6 220Ω resistors. Rather than just write some code let us
design the code from the top down and modularize it with functions. Table 4-1 summarizes our traffic
light sequence.
Traffic Light 1 Traffic Light 2
Red 1 Amber 1 Green 1 Red 2 Amber 2 Green 2
Sequence 1 High Low Low Low Low High
Sequence 2 High High Low Low High Low
Sequence 3 Low Low High High Low Low
Sequence 4 Low High Low High High Low

Table 4-1: The Traffic Light Sequence


We will want the sequence the repeat forever. Listing 4-3 shows the resultant code.
/*
Traffic Lights
Copyright 2020 Gary Hallberg
Licensed under MIT https://github.com/ghallberg-nbtt/shiny-
guide/blob/master/LICENSE
*/
// Some Comments removed to aid readability
// Download code for full comments

const int RED1 = 2; // Define Red Light for traffic light


const int AMBER1 = 3; // Define Amber Light for traffic light 1
const int GREEN1 = 4; // Define Green Light for traffic light 1
const int RED2 = 8; // Define Red Light for traffic light
const int AMBER2 = 9; // Define Amber Light for traffic light 2
const int GREEN2 = 10; // Define Green Light for traffic light 2

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).

Figure 4-10: The Breadboard Layout for the Traffic lights


Image source: Created in Fritzing
Figure 4-11: The Associated Schematic for the Traffic Lights
Image source: Created in Fritzing

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.

Parts needed for this Chapter


• Arduino Uno or clone board
• Full or half size breadboard
• 1 x pushbutton switch
• 1 x 220Ω resistors
• 1 x 10KΩ resistor
• 1 x LED
• Jumper wires

Reading Input from a Switch


When we set an I/O pin of an Arduino board to read input, it will be looking for 5V on the pin to
represent a logic high and 0V to represent a low. That input can be generated from all sorts of periphery
electronics, but for educational purpose and to provide some human input, it is obvious to first use a
switch. Although switches are simple devices, there still are some considerations that you must account
for when using them.
Switches come in all sorts of shapes and sizes, some make a contact when pressed, some break a contact.
Some are rotary, some toggle and some are pushbutton. Some are double pole meaning that they have
two set of contacts. Since we can do a lot in software with an Arduino, we generally only need simple
momentary contact switches for use with our Arduino projects. The switch in Figure 5-1 is typical of
what is used for Arduino projects and it is well worth having a few to hand. These are small and have
leads spaced to fit into breadboards.
Figure 5-1: A Simple Push Button Switch
Image source: The Web (public domain)
The first thing we need to do is to ensure that the switch presents a definite logical high or low. Consider
the circuit in Figure 5-2.

Figure 5-2: A circuit with Floating Input


Image source: The author
When the switch is pressed in Figure 5-2 the contact is made. The Input pin of the Arduino will be
connected directly to 0V or ground. This is a definite logic low. However, when the switch is released,
the contact is open. Will the Arduino pin be set high or low? The reality is, it can float between both
high and low states and provide erroneous input to the Arduino. This is something you can experiment
with.
To remedy this situation, you can use what is called a pull-up resistor. You can connect a resistor
between the Arduino I/O pin and the positive supply of 5V. When the switch is released the resistor will
allow the I/O pin to be pulled to 5V. When the switch is closed the pin will be pulled to 0V. We will have
a definite high or low presented to the pin. We need to choose a resistor value that will pull up the pin
when the switch is open. If the value is too high, the pin will not be pulled up. It is behaving like the
open circuit of the floating pin. If we make the resistor value too low, then the circuit will draw a lot of
current and drain power source such as batteries quicker. A pull up resistor value of 10KΩ is fine. I
would recommend no lower than 4.7KΩ. Figure 5-3 shows a circuit with a pull-up resistor.

Figure 5-3: A Circuit with Pull-up Resistor


Image source: The author
As an alternative, you can use a pull-down resistor and show in Figure 5-4.

Figure 5-4: A circuit with Pull-down Resistor


Image source: The author
With a pull-down resistor the Arduino input pin will be pulled to 0V or ground until such time that the
switch contact is closed. It is then pulled high. In effect, all that happens is that the logic presented to
the input pin is inverted between the pull-up and pull-down scenarios. Since we can initiate action on
logic high or low states within the Arduino, then it really does not matter which approach you choose.
I prefer to use pull-up resistors.

Experiment 4: Turn on an LED on a Button Press


Build the breadboard layout as shown in Figure 5-5 and the associated schematic is shown in Figure 5-
6.
Figure 5-5: The Breadboard Layout to Turn on an LED with a Switch
Listing source: Created in Fritzing
Figure 5-6: The Associated Schematic to Turn on an LED with a Switch
Listing source: Created with Fritzing
Copy or type the Sketch as presented in Listing 5-1 and run the code.
/*
Switch on LED
Copyright 2020 Gary Hallberg
Licensed under MIT https://github.com/ghallberg-nbtt/shiny-
guide/blob/master/LICENSE
*/
// Some Comments removed to aid readability
// Download code for full comments

const int SWITCH = 2; // Define switch as pin 2


const int LED = 8; // Define LED as pin 8
// variables will change:
int buttonState = 0; // variable for reading the pushbutton

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.

Figure 5-7: Characteristics of Switch Bounce


Image source: The author
We could use standalone electronic to debounce the switch, but the Arduino allows us to address the
problem with software.

Experiment 5: Latching the LED and Debouncing the Switch


First, we will build a Sketch without any code to debounce the switch. We will reuse the circuit in Figure
5-5.
We will first generate a Sketch that toggles the LED after a button press without debouncing the switch.
The Sketch is listed in Listing 5-2.
/*
Toggle LED
Copyright 2020 Gary Hallberg
Licensed under MIT https://github.com/ghallberg-nbtt/shiny-
guide/blob/master/LICENSE
*/
// Some Comments removed to aid readability
// Download code for full comments

const int SWITCH = 2; // Define switch as pin 2


const int LED = 8; // Define LED as pin 8

// variables will change:


boolean previousButton = HIGH;
boolean currentButton = HIGH;
boolean ledOn = false;

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.

Experiment 6: Debouncing a Switch


Using the same circuit as in Experiments 4 and 5, we can modify the previous Sketch to debounce the
switch. Load the Sketch in Listing 5-3 and re-run the program. It should behave as before but be 100%
reliable.
/*
Toggle LED with debounce
Copyright 2020 Gary Hallberg
Licensed under MIT https://github.com/ghallberg-nbtt/shiny-
guide/blob/master/LICENSE
*/
// Some Comments removed to aid readability
// Download code for full comments

const int SWITCH = 2; // Define switch as pin 2


const int LED = 8; // Define LED as pin 8

// variables will change:


boolean previousButton = HIGH;
boolean currentButton = HIGH;
boolean ledOn = false;

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

if (previousButton != currentButton) // If switch pressed


{
delay(5); // Wait 5ms
currentButton = digitalRead(SWITCH); // Read switch again
}
// 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-3: Toggle an LED with Switch Debounce
Code source: The author
There is just one small block of code that has been added.
if (previousButton != currentButton)
{
delay(5);
currentButton = digitalRead(SWITCH);// Read switch again
}

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).

Experiment 7: Using Internal Pull-up Resistors


There is one more experiment I want you to look at in this chapter. Remove the 10KΩ pull up resistor
from the circuit to give you the simplified layout in Figure 5-8.

Figure 5-8: The Circuit without a Pull-up Resistor


Image source: Created in Fritzing
On the face of it, we have created a floating input, but the Arduino board has some internal resistors
that can be enabled to do the job of a pull-up resistor. Load the Sketch shown in Listing 5-4.
/*
Toggle LED with debounce and internal pullup
Copyright 2020 Gary Hallberg
Licensed under MIT https://github.com/ghallberg-nbtt/shiny-
guide/blob/master/LICENSE
*/
// Some Comments removed to aid readability
// Download code for full comments

const int SWITCH = 2; // Define switch as pin 2


const int LED = 8; // Define LED as pin 8

// variables will change:


boolean previousButton = HIGH;
boolean currentButton = HIGH;
boolean ledOn = false;

void setup()
{
pinMode (SWITCH, INPUT_PULLUP);
pinMode (LED, OUTPUT);
}

void loop()

{
currentButton = digitalRead(SWITCH); // Read the switch state

if (previousButton != currentButton) // If switch pressed


{
delay(5); // Wait 5ms
currentButton = digitalRead(SWITCH); // Read switch again
}
// 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-4: Digital Input using Internal Pull-up Resistors


Code source: The author
The only change here is in the pinMode declaration.
pinMode (SWITCH, INPUT_PULLUP);
The value of the internal pull-up resistor will be between 20KΩ and 50KΩ depending on the micro-
controller used. There are some people that consider these resistors to be weak and will not use them,
but really it is something you should try over time and make your own judgement.

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.

Parts needed for this Chapter


• Arduino Uno or clone board
• Full or half size breadboard
• 1 x 10KΩ potentiometer
• 3 x 220Ω resistors
• 1 x 10KΩ resistor
• 1 x red LED
• 1 x green LED
• 1 x blue LED
• 1 x NTC thermistor
• Jumper wires

Analog to Digital Conversion


First, we need to understand how the Arduino converts an analog input into a digital value.
The process of converting an analog voltage value into a representative digital value is called
quantization. Consider the graph in Figure 6-1.

Figure 6-1: Analog Signal Quantization


Image source: The author
Let us take a closer look at Figure 6-1. The blue line is the analog waveform that varies in voltage level
over time. To digitize this signal, we will need to take a periodic sample of the voltage level and associate
it with a number representing the voltage level. The sample at period 1 has a level of 16, period 2 14 and
so on. Table 6-1 shows the complete set of samples for all 9 periods.
Sample Period Decimal Level Binary Level
1 16 10000
2 14 01110
3 18 10010
4 20 10100
5 11 01011
6 10 01010
7 13 01101
8 11 01011
9 8 01000

Table 6-1: Our Quantization Example


Our decimal number levels are converted to a binary number. For this example, we only need 5 bits to
represent the analog voltage range. It is this binary bit stream that is used as the basis of the quantized
or digitalized signal.
Looking at Figure 6-1, we should be aware of some limitations. You can see a dip in the voltage between
period 5 and 6. This dip falls in between a sample period and so is missed. Likewise, the peak falls
between period 3 and 4. Therefore, the quantized signal is only ever an approximation to the actual
analog waveform. The difference between the digitized waveform and the analog waveform is referred
to as the quantization error.
We can reduce the quantization error by using an Analog to Digital Converter (ADC) with more bit
levels and by increasing the sample rate. Sample rates for music would be in the order of 44100 per
second and have 16-bit encoding allowing 65536 levels. These values could be much higher but would
lead to a more expensive component. The Arduino is not used for audio sampling and so has a low cost
12bit ADC that delivers 1024 levels. I will not discuss the sample rate, as the ADC is not used for audio
or real time sampling (music, video etc.). It generally only reads the value of an analog sensor when it
needs to. The sample rate would be dictated by the Sketch and the processes that the Sketch needs to
do before acquiring a new sample.

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.

Figure 6-3: The Inner Working of a Potentiometer


Image source: The Web (public domain) with annotations by the author

The Potential Divider


We will use the potentiometer as a device to provide an analog input. First, we need to understand how
potential dividers works. Potential is the voltage difference between two points. This could be between
battery terminals, or even an electrically charged cloud and the ground. Our circuits have a positive 5V
supply and 0V reference also called ‘ground’. Therefore, the potential between the two points is 5V.
Resisters have the property of dropping voltage across themselves. Let us consider Figure 6-4. It shows
a basic two resistor based potential divider.
Figure 6-4: A Potential Divider
Image source: The author
The voltage (Vout) can be calculated with the following formula.
𝑉𝑖𝑛𝑅1
𝑉𝑜𝑢𝑡 =
𝑅1 + 𝑅2
It follows that if R1 and R2 are of the same value, then Vout will be half of Vin. We should be able to
visualize how a potentiometer can be connected to provide a variable output voltage (Vout) of between
0V and 5V. We can then connect Vout to one of the Arduino board’s analog input pins. The
potentiometer’s wiper will be connected to the pin. If you have a multimeter, it is worth taking some
measures from the potentiometer to put some of the theory into practice. Figure 6-5 shows the voltage
output of the potentiometer when the wiper is at half distance across the resistive track. The supply
voltage is 5V from the Arduino pin.
Figure 6-5: A Multimeter Showing the Voltage Output
Image source: The author
The type of pot I will use in this book are 10KΩ in value and of the miniature type that can be used with
solderless breadboards as shown on Figure 6-6. You can use any potentiometer you have to hand but
try to ensure it is about 10KΩ in value.
Figure 6-6: A Miniature Breadboard Mounted Potentiometer
Image source: The author

Experiment 8: Reading the Potentiometer Value


Build the Breadboard layout as in Figure 6-7.
Figure 6-7: The Breadboard Layout to Connect a Potentiometer to an Analog Input
Image source: Created in Fritzing
Next load the Sketch as shown in Listing 6-1.
/*
Read from Pot
Copyright 2020 Gary Hallberg
Licensed under MIT https://github.com/ghallberg-nbtt/shiny-
guide/blob/master/LICENSE
*/

const int POT=0; // Pot wiper connected to analog pin 0


int val = 0; // Variable to hold the reading from the POT

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.

Figure 6-8: The Output from the Serial Monitor


Image source: The author
You should see that when the wiper is at one extreme, it is connected to the 0V rail and the digitized
value is 0. When the wiper is at the other extreme, it is connected to the 5V rail and the digitized value
is 1023.
The serial monitor is initialized by the line of code below:
Serial.begin(9600);
We use the ‘analogRead’ function to read the value from the pot instead of ‘digitalRead’.
Subsequently, the value of the pot is printed to the serial monitor by the line below.
Serial.println(val);
Potentiometers are useful, but not so interesting. Let us look at a temperature sensor with an analog
output so we can build a more meaningful project.

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.

Figure 6-9: Characteristics of an NTC Thermistor


Image source: The author
The symbol for a thermistor is shown in Figure 6-10 along with details of how it will be connected to
your Arduino along with a picture of a typical bead thermistor. They are used in series with a normal
resistor to create a potential divider and the output voltage will be connected to the analog pin of the
Arduino. The value of resistor will affect the voltage output and so it is extremely important to consult
the manufacturers datasheet to get an accurate temperature reading. For the next exercise, I will be
using a 2mm bead thermistor and it requires a 10KΩ resistor to make up the potential divider. As an
exercise you could measure the resistance change of your thermistor by connecting a multimeter to the
leads of the device and gripping the thermistor with you finger and thumb. You can even place some ice
is a glass and test the resistance closer to 0C. Like my, thermistor, many are generic without a
manufacturing datasheet and so you may need these measurements to calibrate the thermistor to give
a valid temperature range in the resultant software.
Figure 6-10: A Bead Thermistor and Connectivity
Image source: The author

Experiment 9: Temperature Measurement with High Low Alert


In this experiment you will build a project that will use a thermistor in a potential divider configuration
to pass an analog voltage to the Arduino. The Arduino will convert the voltage to a temperature value
in Kelvin. The project will have a switch that allows the user to display the temperature in Celsius or
Fahrenheit. The resultant temperature will be sent as text to the serial monitor. Finally, we will also
incorporate three LEDs that will indicate a high temperature, normal temperature and low
temperature. This sounds a lot, but there is little here that you have not seen before, and it shows that
with a few basic skills you can make an Arduino board perform some useful and complex tasks. Start
by building the breadboard layout shown in Figure 6-11.
Figure 6-11: The Breadboard Layout for our Thermometer with Alarms
Image source: Created in Fritzing
Next load the Sketch as in Listing 6-2.
/*
Thermistor control
Copyright 2020 Gary Hallberg
Licensed under MIT https://github.com/ghallberg-nbtt/shiny-
guide/blob/master/LICENSE
*/
// Some Comments removed to aid readability
// Download code for full comments
const int temperaturePin = 0;
const int ledLow = 8;
const int ledNormal = 9;
const int ledHigh = 10;
const int resistorValue = 10000;
const int SWITCH = 2;

// Variables will change


boolean previousButton = HIGH;
boolean currentButton = HIGH;
boolean celsiusSelected = HIGH;
float tempC = 0.0;
float tempF = 0.0;

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 );

// Is Celsius or Fahrenheit selected?


currentButton = digitalRead(SWITCH);
if (previousButton != currentButton)
{
delay(5);
currentButton = digitalRead(SWITCH);
}

if (previousButton == HIGH && currentButton == LOW)


{
celsiusSelected = !celsiusSelected;
}
previousButton = currentButton;

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);
}

Listing 6-2: The Sketch for our Thermometer


Code source: The author
Run the code and open the serial monitor. You should see the temperature in Celsius. If you press the
button for longer than 0.5 seconds, the temperature will display in Fahrenheit. We will talk about the
reason for holding button that long when we look at the code. I set the high and low ranges between
25C and 20C. You may need to adjust these for your ambient temperature. If your room temperature is
between these values, then the green LED should be lit. Hold the thermistor between your finger and
thumb and the temperature will rise quickly. The red LED should light. Then take a glass with some ice
and cool the thermistor down. The blue LED will light once the low threshold is passed.
Let us now take a closer look at the code. This is our most complex Sketch to date, but there is little that
is new here. We will focus just the parts that are new.
You will see that we declared two floating point variables for the temperature in Celsius and the
temperature in Fahrenheit.
float tempC = 0.0;
float tempF = 0.0;

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.

Parts needed for this Chapter


• Arduino Uno or clone board
• Full or half size breadboard
• 3 x 220Ω resistors
• 1 x 10KΩ resistor
• 1 x RGB LED (ideally Common Cathode)
• 1 x Clear LED
• 1 x Cadmium sulfide photocell
• Jumper wires

An Overview of Pulse Width Modulation


So, what is PWM? Essentially, what we do is allocate a regular period over which we want the Arduino
pin to be in a high state. The Pulse Width is a measure of the time that the pin is set high over that
period. We call this the duty cycle of the waveform. Figure 7-1 illustrates the scenario of 0%, 25%, 50%,
75% and 100% duty cycle.
Figure 7-1: A Diagram showing PWM Duty Cycle
Image source: The author
We can see that for a duty cycle of 0%, the pin is set low, for 25% the pin is high 25% of the time so on
an so forth until we have a duty cycle of 100% when the pin is constantly high. So, we can see that the
output voltage is not analog but is either high or low. However, the period is so small that we can trick
the brain into thinking that components such as LEDs are dimmable. The PWM period within the
Arduino is about 2ms. This equates to a frequency of 500Hz.

Experiment 10: LED Brightness Control


Let us reuse the breadboard layout shown in Figure 4-7 where we first lit an external LED. You can see
that the LED is connected to pin 9 of the Arduino. You can see that this pin has a tilde symbol (~). This
means that the pin support PWM. Load or type the Sketch as shown in Listing 7-1.
/*
Brightness control for LED
Copyright 2020 Gary Hallberg
Licensed under MIT https://github.com/ghallberg-nbtt/shiny-
guide/blob/master/LICENSE
*/

const int LED = 9; // Define LED for Pin 9


void setup()
{
pinMode (LED, OUTPUT); // Set the LED pin as an output
}

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);
}

Listing 7-1: A Sketch to Control the Brightness of an LED


Code source: The author
Let us focus on the parts of the code that are new to you. This is the first time you have seen the ‘for’
loop. A ‘for’ loop will execute the code within the brackets a set number of times. This means we need
to set up a counter within the ‘for’ loop.
for (int i = 0; i < 256; i++);
Our counter is an integer value called ‘i’. It is first set to 0. We want to execute the loop whilst the value
of ‘i’ is less than 256. In other words, ‘i’ will have the value of 255 on the final pass. ‘i++’ tells the ‘for’
loop to increment ‘i’ by 1 after each pass.
We then execute a ‘analogWrite’ function to control pin 9 and specify the duty cycle.
analogWrite(LED, i);
Notice we do not pass a percentage value to the ‘analogWrite’ function. The duty cycle is represented
by an 8-bit digital value that we express in decimal form. Therefore, the value is between 0 and 255. 0
being 0% and 255 being 100%.
After the LED reaches maximum brightness, the next ‘for’ loop dims the LED. I have then simply
added direct values to turn off the LED (0%), and light it to 25%, 50%, 75% and 100%.

Experient 11: The RGB LED


An RGB LED is a LED with four leads. It houses red, green and blue LEDs in one package and can have
a Common Anode or Common Cathode. A Common Anode LED uses 5V on a common pin and the
Common Cathode LED connects the common pin to ground. What you can do with this LED is vary the
intensity of each color to mix the emitted light such that it appears as any color. These devices are
especially useful when used in a matrix to make up color display, or as a single light to indicate alarms
status. You could substitute this one device for the three LEDs used in Experiment 9.
I am using a Common Cathode RGB LED. You are using a Common Anode type then check the pin
configuration. You will also need to invert the logic in the Sketch. The pinouts of a Common Cathode
RGB LED are shown in Figure 7-2.
Figure 7-2: Common Cathode RGB LED Pinouts
Image source: The Web (public domain) with annotations by the author
Build the breadboard layout as in Figure 7-3.
Figure 7-3: Breadboard Layout for RGB LED Control
Image source: Created in Fritzing
Load or type in the Sketch as shown in Listing 7-2.
/*
RGB LED
Copyright 2020 Gary Hallberg
Licensed under MIT https://github.com/ghallberg-nbtt/shiny-
guide/blob/master/LICENSE
*/
// Define Pins
const int BLUE = 6;
const int GREEN = 9;
const int RED = 10;

// 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);
}
}

Listing 7-2: The Sketch to Control and RGB LED


Code source: The author
We will not look at this code in detail as there is only one function that is new to us. However, do read
it through and ensure that you fully understand each part. The Sketch first turns all the LED colors off
and then turns on the red LED to full brightness. The red is then faded as the green intensifies. The
green is then faded as the blue is intensified. The Sketch then goes on to produce some random colors
before repeating the cycle.
The only function new to you is the random number generator. The lines of code below generate random
numbers for each color between 0 and 255.
int randRed = random(255);
int randGreen = random(255);
int randBlue = random(255);

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

Experiment 12: A Night Light


In this experiment we will use a photocell to control the light intensity of a clear LED. Although this is
a simple project, it does require a degree of engineering design and introduces an especially important
function for use in Arduino Sketches and is a fitting exercise to end our journey through this book.
We will start by building the breadboard layout shown in Figure 7-5.
Figure 7-5: The Breadboard Layout for the Night Light
Image source: Created in Fritzing
Load or type the Sketch as in Listing 7-3. At this stage, see if you can design your own Sketch from
scratch. What we want to do at this stage is measure the analog output values for both low and high
light extremes. Check the value in the serial monitor at a comfortable room light. We will want the LED
to be off at this light level. Next check the low light setting. You can simply place cover over or pinch
the photocell to reduce the light hitting it. At this level we will want the LED to be fully on.
/*
Nightlight Calibration
Copyright 2020 Gary Hallberg
Licensed under MIT https://github.com/ghallberg-nbtt/shiny-
guide/blob/master/LICENSE
*/

// Define constant values


const int LIGHT=0; // Photocell on Analog Pin 0
// Define variables
int val = 0; // Holds the analog reading from photocell

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

void loop()
{
val = analogRead(LIGHT); // Read the light sensor
Serial.println(val);
delay (500);
}

Listing 7-3: The Sketch to Calibrate the Nightlight


Code source: The author
My measurements indicated a high value of 840 and a low value of 430. I also measured the resistance
of the photocell at that fell between 7.5KΩ for low light and 1.5KΩ for normal room light. If I wanted to
widen the range of analog values, then I could reduce the biasing resistor from 10KΩ to 4.7KΩ within
the potential divider, but I will stick with 10KΩ. I will set my actual values just inside the measured
limits. I.e. I will set the low level to 440 and the high level to 830.
We will move on to the full Sketch now, but we must consider the fact that the ADC returns a value
between 0 and 1023 and the PWM output can only support values between 0 and 255. Therefore, we
do not have a 1:1 mapping between the analog input and the PWM output. The Arduino programming
language does provide a convenient function to do this mapping. This is the ‘map’ function. In our
Sketch we will want to map the low light level to a PWM output of 255 and the high light level to PWM
output of 0. The function will look like the one below:
val = map(val, 440, 830, 255, 0);
We can reuse the variable ‘val’. ‘val’ is the ADC value from the photocell. It will be proportionally
mapped to the new value between 0 and 255 and ‘val’ is overwritten with this new value for use as the
PWM output integer. There is one more point to consider. The map function does not constrain values
so if we recorded a value higher than 840, the map function will return a value below 0. This would
clearly cause and error in our code. Therefore, we must also use the ‘constrain’ function to constrain
the value of ‘val’ to between 0 and 255.
val = constrain (val, 0, 255);
These are two important functions in the Arduino programming language. Now try the full Sketch to
control the nightlight. Review the code to ensure you fully understand it.

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.

You might also like