Kickstart To Arduino Nano Get Cracking With The ArduinoNanoV3, NanoEvery, and Nano33IoT
Kickstart To Arduino Nano Get Cracking With The ArduinoNanoV3, NanoEvery, and Nano33IoT
Get Cracking with the Arduino Nano V3, Nano Every, and Nano 33 IoT
Ashwin Pajankar
● This is an Elektor Publication. Elektor is the media brand of
Elektor International Media B.V.
PO Box 11, NL-6114-ZG Susteren, The Netherlands
Phone: +31 46 4389444
● All rights reserved. No part of this book may be reproduced in any material form, including photocopying, or
storing in any medium by electronic means and whether or not transiently or incidentally to some other use of this
publication, without the written permission of the copyright holder except in accordance with the provisions of the
Copyright Designs and Patents Act 1988 or under the terms of a licence issued by the Copyright Licencing Agency
Ltd., 90 Tottenham Court Road, London, England W1P 9HE. Applications for the copyright holder's permission to
reproduce any part of the publication should be addressed to the publishers.
● Declaration
The Author and Publisher have used their best efforts in ensuring the correctness of the information contained in
this book. They do not assume, and hereby disclaim, any liability to any party for any loss or damage caused by
errors or omissions in this book, whether such errors or omissions result from negligence, accident, or any other
cause.
All the programs given in the book are Copyright of the Author and Elektor International Media. These programs
may only be used for educational purposes. Written permission from the Author or Elektor must be obtained before
any of these programs can be used for commercial purposes.
Elektor is part of EIM, the world's leading source of essential technical information and electronics products for pro
engineers, electronics designers, and the companies seeking to engage them. Each day, our international team develops
and delivers high-quality content - via a variety of media channels (including magazines, video, digital media, and social
media) in several languages - relating to electronics design and DIY electronics. www.elektormagazine.com
●4
Contents
Contents
Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Dedication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Chapter 1 • I
ntroduction to the Arduino Platform and the Arduino Nano . . . . . . . 11
The Microcontroller . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Arduino . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Arduino Software . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
Arduino Counterfeits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
●5
Kickstart to Arduino Nano
Jumper cables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
Resistors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
Pushbuttons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
Arduino Serial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
Analog Input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
Chapter 4 • P
ulse Width Modulation and Driving Unipolar Stepper Motors with
Digital I/O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
Working with the 28BYJ-48 Unipolar Stepper Motor and the ULN2003A Motor Driver . . 92
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
Chapter 5 • P
lotting Geometric Art on an External Display . . . . . . . . . . . . . . . . . 103
●6
Contents
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
Using the DS18B20 Temperature Sensor Jointly with the RTC . . . . . . . . . . . . . . . . . 179
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
●7
Kickstart to Arduino Nano
●8
Acknowledgements
Acknowledgements
I wish to thank my friend Anuradha for encouraging me to author this book. I also want
to express my heartfelt gratitude towards Ferdinand TeWalvaart, Jan Buiting, Alina Neacsu,
and Shenja Panik from the Elektor team for guiding me through each phase of the publi-
cation process. This is my second book with Elektor International; Media and it is a great
experience to perform with their publishing team. Finally, I want to show appreciation to
everyone directly and indirectly associated with this project.
Dedication
This book is dedicated to the memory of Prof. Govindarajulu Regeti (July 9, 1945 — March
18, 2021)
●9
Kickstart to Arduino Nano
Preface
I have been working with the Arduino since 2016 and I believe it to be an excellent platform
not only to learn electronics but also to deploy real-life production systems. Using Arduino
boards, I have produced and deployed many real-world applications such as IoT enabled
electrical infrastructures at home and workplaces, web-enabled weather monitoring sys-
tems, and a robot for welcoming guests in the reception area of my former employer.
I always wished to write a step-by-step and detailed book on one of the most prominent
family of microcontroller boards by Arduino, the "Nano". In this book, I have covered three
members of this family: Arduino Nano V3, Arduino Nano Every, and Arduino Nano 33 IoT,
in happy unison with the Arduino IDE 1.x and Arduino IDE 2 RC5 for the purpose of demon-
strating the C and C++ code. I have written the book in a step-by-step and detailed way
to explain concepts, build required circuits, and finally write the code. The book covers mor
than 60 examples to address a variety of major concepts related to the world of electronics
and the Arduino Ecosystem in particular.
This book required me to find and digest loads of documentation, attend online tutorials,
write code, and post on online forums when I was stuck with some problem. This result ac-
counts for hundreds of manhours of work I spent to finish the project. I have referred many
online sources for code and images. I also mentioned those sources with all the licenses
whenever and wherever I borrowed and modified the source codes and images.
I finished writing the draft of the book when India (my current resident country) and the
world is gradually recovering from the COVID-19 pandemic. This project and the guidance
provided by the Elektor team gave me a great sense of purpose and motivation to continue
exploring the world of knowledge on Arduino. I hope all the readers will like and enjoy this
book as much as I enjoyed writing it. Happy learning and exploring!
Reader Notice. An archive file (.zip) comprising the software examples and Fritzing-
style circuit diagrams discussed in the book may be downloaded free of charge from
the book's product and resources page on www.elektor.com (search for: book title and
author).
● 10
Chapter 1 • Introduction to the Arduino Platform and the Arduino Nano
Chapter 1 • I
ntroduction to the Arduino Platform and
the Arduino Nano
Welcome to the very first chapter. In case you have not read the Table of Contents and the
Preface, I strongly recommend that you do so before commencing with this chapter. Let's
begin the journey to the amazing world of the Arduino Platform and its Ecosystem. This is
an introductory chapter, so you will be learning a lot of concepts needed to build sufficient
background to begin with Arduino. This chapter addresses the following topics:
• the microcontroller
• Arduino
• Arduino is for Everyone
• the Arduino Ecosystem
• the Arduino Nano and Arduino Nano Every
• powering Nano and Nano Every microcontroller boards
• the Arduino IDE
• working with the Boards Manager
• working with the Arduino Nano Every
• working with the Arduino Nano
After reading this chapter, you are all set to explore the Arduino Platform and Ecosystem.
The Microcontroller
A microcontroller is usually a tiny, complete computer system on a single integrated cir-
cuit (abbreviated as IC). An MCU (MicroController Unit) can have one or more processors,
memory, and programmable Input/Output (IO) within a single IC package. In most cases,
there are two types of memory included on the chip. The first one is Programmable mem-
ory, usually EEPROM (Electrically Erasable Programmable Read-Only Memory), OTP (One
Time Programmable) ROM, ferroelectric RAM, or NOR flash. Also, MCUs also have a small
amount of RAM (Random Access Memory) where programs are loaded and executed. In
short, an MCU is a microprocessor with Program Memory, RAM, and Programmable IO on
a single chip. The main difference between microprocessors and MCUs is in their appli-
cations. Microprocessors are general-purpose processors used in desktop computing and
general-purpose computing. MCUs are usually used in embedded systems and tasked to
performing some sort of physical action. For example, MCUs can be employed in printers,
vehicle dashboards, or engine controls in cars and aircraft.
● 11
Kickstart to Arduino Nano
Arduino
Arduino (https://www.arduino.cc) is an open-source MCU platform, meaning it has open-
source and free software and open-source hardware. It usually combines an MCU on a sin-
gle PCB with other features. Arduino is a popular family of MCU based MCU-based boards.
Earlier, the Arduino group had also produced a series of Linux-based computers. However,
by now they seem to have discontinued them and are solely focusing on MCUs. The Arduino
family has a lot of members, and they can be categorized into three subfamilies as follows:
https://www.arduino.cc/en/hardware#classic-family
https://www.arduino.cc/en/hardware#mkr-family
You can also read more about the SAM D21 family at
https://content.arduino.cc/assets/mkr-microchip_samd21_family_full_datasheet-
ds40001882d.pdf
● 12
Chapter 1 • Introduction to the Arduino Platform and the Arduino Nano
We will discuss the Arduino Nano and Arduino Nano Every boards in detail throughout
this book.
You can read more about the Nano family at the URL:
https://www.arduino.cc/en/hardware#mkr-family
• Portenta H7
• Portenta X8
• Portenta Machine Control
You can read more about the Pro family at the URL
https://www.arduino.cc/pro/hardware
• inexpensive
• cross-platform
• simple, clear programming environment
• open-source and extendable software
• open-source and extendable hardware
You will explore these features in detail in this book in the upcoming chapters.
● 13
Kickstart to Arduino Nano
hardware components that can be interfaced with Arduino. Even you can develop your own
library once you are comfortable with the coding of the Arduino platform. Let's dive deeper
into the ecosystem of Arduino and explore all the components.
Arduino Software
The Arduino organization has published a free and open-source software and IDE known
as the Arduino IDE, a desktop application for Linux, Windows, and macOS. It comes with
many libraries and example programs for learning the programming "on" the Arduino plat-
form. It supports C and C++ syntax tailor-made for the Arduino platform. All the members
of Arduino family can be programmed with this IDE. It is freely available for download and
use. Also, it is open-source. Many people have created their own libraries and made them
available for everyone.
Arduino Counterfeits
These are based on the official boards and bear the Arduino logo, except they are not
manufactured, marketed, or sold by Arduino. These products are known as fakes or coun-
terfeits. You can guesstimate their status from the quality of components and build. Do not
buy and encourage counterfeits. They are illegal and unethical products.
The Arduino Nano is the elementary and oldest member of the Arduino Nano family. The
current revision is Arduino Nano 3.x. The Arduino Nano Every is a pin-to-pin compatible
upgrade for Arduino Nano with a faster processor and more memory. You can use both
indiscriminately in your projects. Let's compare the specifications of both boards.
● 14
Chapter 1 • Introduction to the Arduino Platform and the Arduino Nano
PWM pins 6 5
Input Voltage 7 V to 12 V 7 V to 18 V
Memory SRAM 2 KB 6 KB
Flash 32 KB 48 KB
Width 18 mm 18 mm
Length 45 mm 45 mm
You can check the official pages at arduino.cc for more information on Nano, see
https://store-usa.arduino.cc/products/arduino-nano
https://docs.arduino.cc/hardware/nano
http://ww1.microchip.com/downloads/en/DeviceDoc/ATmega48A-PA-88A-PA-
168A-PA-328-P-DS-DS40002061A.pdf
You can check the official pages at arduino.cc for more information on the Nano Every,
here:
https://store-usa.arduino.cc/products/arduino-nano-every
https://docs.arduino.cc/hardware/nano-every
● 15
Kickstart to Arduino Nano
You can download the ATmega4809 Datasheet from the following URL:
https://content.arduino.cc/assets/Nano-Every_processor-48-pin-Data-Sheet-
megaAVR-0-series-DS40002016B.pdf
After checking the above URLs, you must have realized that the Arduino Nano Every is bet-
ter than the Arduino Nano. It is even cheaper, so, for all your projects I would recommend
using an Arduino Nano Every.
https://content.arduino.cc/assets/Pinout-NANO_latest.pdf
and
https://content.arduino.cc/assets/Pinout-NANOevery_latest.pdf.
They are shared under creative commons license which can be found at https://creative-
commons.org/licenses/by-sa/4.0/deed.en. I have modified them for using here in this
chapter.
Figure 1-1: Pinouts of Arduino Nano Every (left) and Arduino Nano (right).
In Figure 1-1, at the bottom, the legend explains the meaning of the colors. You need to
focus on Digital Pins, Analog Pins, Ground, Power, and LED pins in this diagram.
● 16
Chapter 1 • Introduction to the Arduino Platform and the Arduino Nano
In Figure 1-2, please focus on the Serial Communications pins allocated to I2C (SDA and
SCL), SPI (SS, MOSI/COPI, MISO/CIPO, SCK), and UART (RX and TX),
In Figure 1-2, the top section shows the Nano Every pin functions, and the middle section,
those of the Arduino Nano.
You can study the meaning of additional pins from Figure 1-3.,
● 17
Kickstart to Arduino Nano
Figure 1-3: Bottom views of the Arduino Nano Every and Arduino Nano boards.
Let's fathom the meanings of the pins shown and described in the diagrams. The pin de-
scriptions of the Nano and Nano Every are almost identical with a few exceptions. Let's see
that in detail.
Digital Pins – The pins from D0 through D13 are 14 digital input output pins in all. They
operate at 5 volts logic swing Each pin can provide or receive a maximum current of 40
mA. Each pin also has an internal pull-up resistor with a value of 20-50 k-ohms which is
disconnected by default.
● 18
Chapter 1 • Introduction to the Arduino Platform and the Arduino Nano
UART – These are D0 (RX) and D1 (TX)., used to receive (RX) and transmit (TX) TTL serial
data. These pins are connected to the pins of an onboard FTDI USB-to-TTL Serial converter
chip.
PWM – In the Nano, pins D3, D5, D6, D9, D10, and D11 provide an 8-bit PWM output. In
the Nano Every, there are only five pins allocated to PWM: D3, D5, D6, D9, and D10.
SPI – SPI communication is provided by D10 (SS), D11 (MOSI/COPI), D12 (MISO/CIPO),
and D13 (SCK) on both boards.
The Nano and Nano Every each have 8 analog inputs (A0 through A7). Each pin provides 10
bits of resolution that enables 108 = 1024 different values for input. The default range for
the operational voltage for these pins is 0 V to 5 V. You can change the upper range from
5 V to your desired value by programming.
In the Nano, pins A0 to A5 can also be configured as digital pins D14 through D19.
In the Nano Every, pins A0 to A7 can also be configured as digital pins D14 through D21.
I2C – This functionality is provided by the pins labelled A4/D18 (SDA) and A5/D19 (SCL).
They support I2C using the Two Wire Interface (TWI) and use the Wire library.
These are all the important pins on both MCU boards. There are more pins and more mean-
ings to the pins. However, I will not be covering most of those concepts, as they are really
out of the scope of this book.
● 19
Kickstart to Arduino Nano
Figure 1-4: USB Micro B and USB Mini B cables. Image provided by Andrej A. Antonov
under the license https://creativecommons.org/licenses/by-sa/3.0/deed.en
You can power these boards by plugging one end of the USB cable to the MCU board and
the other end to a 5-V battery pack, power supply, or the USB port of a computer. You can
also power the boards through their VIN pins, but I do not recommend it yet to the be-
ginning readers. Powering through the USB is the best and hassle-free way to power your
Arduino.
● 20
Chapter 1 • Introduction to the Arduino Platform and the Arduino Nano
Options for macOS and Linux distributions are also available. Once you click an appropriate
option, the appropriate installation package for your platform will be downloaded. I have a
64-bit Windows computer and consequently downloaded the file arduino-ide_2.0.0-rc5_
Windows_64bit.msi. rc5 i.e., Release Candidate 5. You can see the file at the bottom
bar of your Chrome browser, as well as under the Downloads option in the browser. You
can find the physical file in the Downloads directory of your user in the OS. Launch (run)
the file and it will show a window like in Figure 1-6.
● 21
Kickstart to Arduino Nano
Click on the button Run. It will configure the IDE and show a progress bar as shown in the
Figure 1-7.
Wait for the installation to finish. Once done, this progress bar disappears, and you can
check for the IDE using the Windows Search feature. Enter the word Arduino and it will
show the option for it. Click on it. It will show the Arduino IDE splash screen. When you run
the IDE for the very first time, the Windows Firewall shows you options as in Figure 1-8.
Check both the boxes in both windows and click on the button Allow access. The splash
screen for the IDE is as shown in Figure 1-9.,
● 22
Chapter 1 • Introduction to the Arduino Platform and the Arduino Nano
After some time, the splash screen disappears and the IDE is launched. The default window
is shown in Figure 1-10.
Before continuing, let's change the preferences. Go to the File menu in the menu bar at
the top and choose the option Preferences. It opens a window (Figure 1-11).
● 23
Kickstart to Arduino Nano
Tick all the checkboxes here and change the path under the textbox labeled Sketchbook
location. You can use the button Browse to choose the location instead of typing it.
The next set of changes are my personal preferences for reducing eye strain. I increased
the size of the font used and changed the theme to Dark mode. The preferences window
looks like the one shown in Figure 1-12 after the changes.
● 24
Chapter 1 • Introduction to the Arduino Platform and the Arduino Nano
This is how you can change preferences for the IDE. After changing the preferences to
those shown in Figure 1-12, the IDE window looks as shown in Figure 1-13.
● 25
Kickstart to Arduino Nano
By default, the file is named with a naming convention which combines current date and a
character in alphabetical order. For example, the current file has been assigned a name by
default and it is sketch_apr15a. If you create a new file using the option under the File
menu, then the new file is assigned the name sketch_apr15b (Figure 1-14).
Note that the name assigned to this sketch is just temporary and not yet saved to your
disk. You can save it by pressing CTRL + S on the keyboard or from the Save option under
the File menu. You can give it another name if you wish. The option Save and Save As,
when clicked, opens the location which you entered in the preferences by default. You can
also save at any other valid location by browsing the filesystem.
● 26
Chapter 1 • Introduction to the Arduino Platform and the Arduino Nano
Again, be sure to download the correct version based on your computer's architecture.
In my case, it is arduino-1.8.19-windows.exe. Launch it and it shows a window like in
Figure 1-16.
Click on the button I Agree. It will show options (Figure 1-17). Check all the checkboxes.
Click on the Next button. It shows the window where you can select a directory for instal-
lation (Figure 1-18).
● 27
Kickstart to Arduino Nano
Finally, click on the button Install and your PC starts copying the files to the disk. Figure
1-19 is a screenshot of the installation in progress.
The process creates an icon on the desktop. Also, in the Windows Menu, you can see two
options now, Arduino (stable version) and Arduino IDE (corresponding to 2.0 Release can-
didate), as shown in Figure 1-20.
● 28
Chapter 1 • Introduction to the Arduino Platform and the Arduino Nano
The current stable version you just installed does not have the "dark" theme that you
selected in the Release Candidate version (2.0 RC5). Open the stable version you just in-
stalled, and it shows the splash screen Figure 1-21.
● 29
Kickstart to Arduino Nano
I will be mostly using Arduino IDE 2.0 RC5 to explain all the code demonstrations. However,
if you are planning to use IDE version 1.8.19 and if there is anything specific to it, then I
will explain it in detail with screenshots. Go ahead and change the preferences to your liking
for IDE 1.8.19.
NOTE: After the book is published, both versions of the Arduino IDE are subject to updating
after some time. However, the instructions mentioned in the book cover both versions and
will also apply to the future updates of both versions unless there is some major change in
the user interface (which is very unlikely).
After installation, you can launch the IDE from the Raspberry Pi OS Menu and under the
Programming section as shown in Figure 1-23.
● 30
Chapter 1 • Introduction to the Arduino Platform and the Arduino Nano
The entire interface is the same as in version 1.8.19 running on a Windows OS.
Figure 1-24, provided by Cedar101 under Public Domain Creative Commons License at
https://creativecommons.org/publicdomain/zero/1.0/deed.en), is a screenshot of an in-
stance of Arduino IDE 1.8.5 running on a macOS.
● 31
Kickstart to Arduino Nano
Figure 1-25: Boards Manager in the shortcut menu bar within IDE 2.0 RC5.
Clicking it will open the Boards Manager to the right of this shortcut menu bar as shown in
the Figure 1-26.
● 32
Chapter 1 • Introduction to the Arduino Platform and the Arduino Nano
Figure 1-26: Boards Manager alongside the vertical shortcut menu bar within IDE 2.0 RC5.
You can also open it from the main menu bar under the menu Tools -> Board -> Boards
Manager as shown in Figure 1-27.
● 33
Kickstart to Arduino Nano
In IDE version 1.8.19, the interface window for the Boards Manager is a bit different as you
can see from Figure 1-28.
In both interfaces (Figures 1-26 and 1-28), you can see the option for searching a board.
In the search bar, type megaAVR and press the Enter key (Figure 1-29).
● 34
Chapter 1 • Introduction to the Arduino Platform and the Arduino Nano
Figure 1-29: Installing the megaAVR on IDE version 1.8.19 and IDE 2.0 RC5.
Doing so will show all the options for installation. Install Arduino megaAVR Boards. The
system will prompt you to install drivers as shown in the Figure 1-30.
● 35
Kickstart to Arduino Nano
In case you have difficulty identifying the COM port, check the Device Manager applica-
tion on Windows. Figure 1-33 shows a screenshot just before an Arduino Nano board got
attached.
● 36
Chapter 1 • Introduction to the Arduino Platform and the Arduino Nano
In IDE version 1.8.19, you also have to choose an additional option as shown in Figure
1-35.
● 37
Kickstart to Arduino Nano
Now, save the default program (also known as "sketch") to the location of your choice.
Name it as you like. The system creates a folder with the given name automatically and
saves the program file with the same name as the folder (user-given name). The program
file has the .ino extension by default.
You can even check the board information by selection that option from the Tools menu as
shown in the Figure 1-36.
Now, let's compile/verify and upload the code. Do not worry about the contents of the
sketch/program. We will study them in detail in the next chapter. Check the following (Fig-
ure 1-36) image to see the shortcuts in both the version of IDEs,
● 38
Chapter 1 • Introduction to the Arduino Platform and the Arduino Nano
The first row corresponds to the options in IDE 2.0 RC5, and the second row to IDE ver-
sion 1.8.19. The check mark is the button for Compile/Verify. The right pointing arrow is
the button for Upload. The page symbol is the button for New Sketch. The Up arrow is
the button for Open and the down arrow for Save. The Debug button is disabled for the
Nano and Nano Every so you will not be using it. Click the check mark to compile/verify the
sketch. Once verified, it shows the following message in the output window:
Now, click the Upload button. Once the sketch is uploaded, it shows the following message
in the end,
Reading | #########################################
######### | 100% 0.00s
● 39
Kickstart to Arduino Nano
Once done, it shows a window with the message: Success. If your computer is still not
able to detect the Nano board, disconnect and connect it again. At this point, the computer
should be able to detect the board without any issue. The process of verification and up-
loading the sketch/program is identical for the Arduino Nano. However, you have to choose
the board within IDE 2.0 RC5 as shown in Figure 1-38.
Figure 1-38: Choosing the Arduino Nano board within IDE 2.0 RC5.
The process of selecting the board within IDE version 1.8.19 is exactly the same. However,
additional options are offered. You have to select the bootloader for your board as shown
in Figure 1-39.
● 40
Chapter 1 • Introduction to the Arduino Platform and the Arduino Nano
You have to try the bootloaders from the list in order to find the one that matches your
board. The rest of the process of compiling and uploading a sketch to a board is the same
as you have learned for the Nano Every.
Summary
In this chapter, you got yourself acquainted with the Arduino ecosystem, the Arduino Nano
board, and the Arduino Nano Every board. Moreover, you learned the basics of working
with stable and upcoming versions of Arduino IDE. You learned how to install a new board.
You learned how to verify/compile a sketch and upload it to a board.
As an exercise, explore the various options in the menu within both versions of the IDE.
Check for the keyboard shortcuts for Verify and Upload.
In the next chapter, you will learn to play with simple electronic components and write
programs for them. It will be a detailed and hands-on chapter on electronics and program-
ming.
● 41
Kickstart to Arduino Nano
In the previous chapter, you learned the basics of the Arduino Ecosystem, a couple of
boards in the Nano Family, and the basics of the current stable as well as next Release
Candidate versions of the Arduino IDE. In this chapter, you will learn the basics of writing
programs/sketches with Arduino IDE and working with electronics. Here's a list of topics
you will learn about in this chapter:
After absorbing this chapter, you should be comfortable with the basics of Arduino pro-
gramming and a few electronic components.
prog00.ino
void setup() {
// put your setup code here, to run once:
void loop() {
// put your main code here, to run repeatedly:
I have copied and pasted the code as it is, without any modifications. The is the bare
minimum code required to compile (or verify, again, these two words can be used inter-
changeably) the sketch. As you can see, there are two blocks of code, setup() and loop().
To define your basic program, both blocks are a must for a sketch. Now, try to remove the
setup() block and compile the sketch, and you will find the following error message in the
Output section,
● 42
Chapter 2 • Playing with Electronics
Similarly, if you remove the loop() section and try to compile, the compilation will be un-
successful again with the following message,
This is the bare minimum of code required for any compilation —it will always be there in
any sketch anyone writes for Arduino.
When any sketch is uploaded to a board, it is stored to the board's Flash memory. Even
after disconnecting the board from the computer (or any other power source), the code will
be retained by the Flash memory, and it won't be erased until you upload a new sketch.
Every time the board is powered on, the setup() section is executed once. After that, the
loop() section continues to run as long as the board is powered. If the board is disconnected
powered off, it stops running the code (obviously!). When you connect the board to a power
source again, the entire process is repeated.
prog00.ino
/*
This Program is written by Ashwin Pajankar
for Elektor on 20-APR-2022
*/
Let's examine it line by line. The code that begins with /* and ends with */ represents a
multi-line comment. Programmers usually use comments to provide additional information
about the code. Similarly, the lines that begin with // are single-line comments. I have
mentioned in the previous chapter that most of the Arduino boards have an on-board LED.
● 43
Kickstart to Arduino Nano
It is connected to digital pin 13 in the Arduino Nano family. The function pinMode() initial-
izes a digital pin as an INPUT or OUTPUT. In this chapter, you will learn their usage. You
have to write the pin number and INPUT or OUTPUT as arguments. The built-in constant
LED_BUILTIN refers to the on-board LED. So, you do not have to change the code when you
upload it to the different boards. LED_BUILTIN will always point to the on-board LED. The
function digitalWrite() sends either HIGH or LOW to the specified digital pin which means
1 or 0, respectively.
Note: You can check the details of built-in constants at this url:
https://www.arduino.cc/en/reference/constants.
Now, select the board and port from the Tools menu, then upload the code. You will see a
small LED near the micro-USB port lighting up. It is orange-colored which distinguishes it
from the power indicator LED which lights up green.
As you have learned, the loop() part runs forever, and thus as long as the board receives
power, this on-board LED (along with the power indicator LED) will always light unless you
upload some other program to the board.
Now, disconnect the Arduino board from the computer and power it with a power bank as
shown in Figure 2-1 (Image by Santeri Viinamäki under the https://creativecommons.org/
licenses/by-sa/4.0/deed.en license).
Figure 2-1: A power bank is a good power source for your Arduino experiments.
Once you power the board again, the LED will light again. This is because the system is
running the same program you uploaded earlier. It was uploaded to its flash memory and
will not be erased if you turn the power off — it will be rewritten only when you upload new
code to it.
● 44
Chapter 2 • Playing with Electronics
Congrats, you just wrote and uploaded your own first custom sketch to the board. Let's
create a new file and name it prog01.ino. This should be the contents of the file:
prog01.ino
int blink_duration = 1000;
void setup()
{
pinMode(LED_BUILTIN, OUTPUT);
}
void loop()
{
digitalWrite(LED_BUILTIN, HIGH);
delay(blink_duration);
digitalWrite(LED_BUILTIN, LOW);
delay(blink_duration);
}
From here on, I will use comments in the code as I am explaining the relevant functions. It
is considered good practice to add comments to the code (along with separate and detailed
documentation) to aid readers and fellow programmers in understanding what your code is
supposed to do. You will also benefit from your own comments after a few months as you
revisit your projects. You certainly do not wish to stare at an alien piece of code!
The function delay() pauses the execution of the sketch for the given amount of time stated
in milliseconds. You have also defined an integer variable in the beginning. This variable can
be accessed in any block of code in the same sketch, as it is a global variable. However,
the variables defined in the loop() and the setup() sections can only be accessed within the
respective sections. They are known as local variables. Now, upload the code and you will
see the LED connected to the digital pin 13 blinking.
Note: You can read more about the function delay() at this url:
https://www.arduino.cc/reference/en/language/functions/time/delay/
https://www.arduino.cc/en/Reference.digitalWrite
● 45
Kickstart to Arduino Nano
Shown here is a type MB 102 830-points breadboard. All the holes in the breadboard
provide electrical contact. You can see four rows of horizontal lines, two marked in blue
and two in red. Every "point" in those lines is connected to all the points in the same line.
So, if you connect an electrical component to the point on the far left in a line, you get the
same electrical signal at the far-right end of the same line. These lines are known as pow-
er-supply lines or the power bus lines. They will be used to distribute the supply voltage or
"power" across the board. The red line will have the positive supply voltage, and the blue
one carries the Ground or 0-V potential.
The middle part is divided into two sections. Each section is comprised of rows and col-
umns. Now, unlike the power bus lines, the points in a single row are not connected. Here,
they are connected column-wise. Two sections are separate, and they do not have any
electrical contact. In both sections, there are columns comprising of five contact points in
each column. If you look carefully, the rows and columns are marked with letters (A, B,
C, D, E, F, G, H, I, and J) and numbers (1 through 63), respectively. This means that the
points in column 1 are divided into two groups. The first group is A1, B1, C1, D1, and E1.
The second group is F1, G1, H1, I1, and J1. All the points in a column group are electrically
connected to each other.
● 46
Chapter 2 • Playing with Electronics
Figure 2-3: A breadboard with a lone DIP integrated circuit plugged in.
This image makes the purpose of the gap between two sections obvious. You will also
mount your Arduino Nano boards on the breadboard in similar fashion. You can see how the
points are internally connected in a mini breadboard pictured in Figure 2-4.
Figure 2-4: A half breadboard and its internal connections at the back side.
● 47
Kickstart to Arduino Nano
There is another type of similar-looking breadboard which is known as the type "GL 12"
breadboard having 840 points. I will be demonstrating almost everything with a type B
102 830-point breadboard and smaller breadboards — an example is shown in Figure 2-5.
You can safely use an MB 102-style power supply with an MB 102 830-point or a mini bread-
board shown in Figure 2-4. Figure 2-6 shows a power supply mounted on a breadboard.
● 48
Chapter 2 • Playing with Electronics
The supply module fits perfectly on the compatible breadboard. It also has a jumper plug
to choose between 3.3 V (also represented by 3V3) and 5 V. These are the most frequently
used voltage levels. The power supply proper can be powered with a barrel jack with 2.1
mm center-pin positive plug adapter as shown in Figure 2-7.
● 49
Kickstart to Arduino Nano
You can also connect a 9 V block battery to a connector and connect it to a male 2.1 mm
barrel jack as shown in Figure 2-8.
This arrangement can be used as a field or portable power supply for your Arduino projects.
Jumper cables
In order to connect the contact points of breadboard with each other and various electronic
components, you can use jumper cables. Figure 2-9 pictures a collection of male-to-male
jumper cables (image by oomlout under https://creativecommons.org/licenses/by-sa/2.0/
deed.en license).
● 50
Chapter 2 • Playing with Electronics
Figure 2-9 shows a female-to-female jumper cable (image by oomlout under https://crea-
tivecommons.org/licenses/by-sa/2.0/deed.en license),
The third type is the male-to-female jumper cable. You will be using all of these types of
jumper cable throughout the demonstrations in this book.
● 51
Kickstart to Arduino Nano
The inventors of the blue LED won the Nobel Prize (https://www.nobelprize.org/prizes/
physics/2014/press-release/). LEDs come in different configurations and with different
colors.
Resistors
Resistors are passive electrical elements with two wire or solder ends, and they offer elec-
trical resistance. They are used to divide voltages and limit the current in the circuits. Figure
2-12 (image by Afrank99 under https://creativecommons.org/licenses/by-sa/2.5/deed.en
license) shows a few resistors.
● 52
Chapter 2 • Playing with Electronics
You can calculate the value of the resistance offered by the resistor by reading the marked
color codes. This page:
https://www.digikey.in/en/resources/conversion-calculators/conversion-
calculator-resistor-color-code
offers a ready-made tool for this task. in the project descriptions, I will always mention the
values of the resistors used in construction of the relevant circuit.
Pushbuttons
Pushbuttons are momentary switches. Applying pressure with your finger closes the con-
tacts enabling current to flow. The switches used in our projects are usually rectangular
in shape. Two opposite sides have two contact points each. When you apply pressure, the
internal switch lever is pushed downwards and all the contact points on the same side are
connected to each other. These pushbuttons are manufactured in such a way that they can
easily be used on breadboards. Figure 2-13 shows the collection of pushbuttons I have in
my drawer.
● 53
Kickstart to Arduino Nano
You will be working with a lot of electrical components and you will learn about them when-
ever appropriate throughout this book. Everything presented so far should be enough to
get started with the basics of building a circuit.
Arduino comes with a large set of functions. They are known as built-in functions. Many
third-party developers create collections of user-defined custom functions for various pur-
poses such as interfacing with hardware. These code chunks are known as libraries.
You can also define your own custom function. Let's modify the previous code example
(prog01.ino) and create a user-defined function for the blink functionality (prog02.ino):
prog02.ino
int blink_duration = 1000;
● 54
Chapter 2 • Playing with Electronics
delay(duration);
digitalWrite(pin, LOW);
delay(duration);
}
void setup()
{
pinMode(LED_BUILTIN, OUTPUT);
}
void loop()
{
blink(LED_BUILTIN, blink_duration);
}
In prog02.ino, you have defined a separate function to implement the blinking of an LED.
You have to state the number of the digital pin to which an LED is connected to (here, a
built-in constant is stated), and the duration of the blink as an argument. You can also add
default arguments to this function definition. If you do not state any arguments while call-
ing the function, the system will assume the default arguments. Refer to sketch prog03.
ino:
prog03.ino
int blink_duration = 1000;
void setup()
{
pinMode(LED_BUILTIN, OUTPUT);
}
void loop()
{
blink();
}
You will continue using the skeleton of this sketch and employ similar coding standards
throughout this book.
● 55
Kickstart to Arduino Nano
1. Mount the power supply on the breadboard and power it with a power adapter.
2. Connect the smaller leg (cathode) of an LED to the GND (Ground) pin and the
longer leg (anode) to an end of a resistor with a value of 470 ohms. Connect the
other end of the resistor to the positive voltage. You can use any of the available
voltage levels (3V3 or 5 V).
3. Switch on the power supply and the LED will light up.
Congrats! You have built your first digital circuit; it's shown in Figure 2-15.
Now, after reading the description and observing the image, you must have understood
that it is difficult to show circuits using only words and photographs. That's why I am go-
ing to use a tool known as Fritzing (read more at https://fritzing.org/) to show the circuit
diagrams. If you wish, you can also purchase this tool costing 8 euros. However, it is worth
every single cent you pay for it. In the code bundle released for this book, I have included
the Fritzing circuit files for your reference if you wish to work with them. Figure 2-16 is the
Fritzing-style "circuit diagram".
● 56
Chapter 2 • Playing with Electronics
You can find the Fritzing parts for the breadboard and Arduino Nano Every board at the
following URLs:
1. http://omnigatherum.ca/wp/?p=262
2. https://docs.arduino.cc/hardware/nano-every
From here on, I will mostly use Fritzing images to represent circuits. I will also add the URLs
of the Fritzing files for the parts that do not come with Fritzing.
Let's make this circuit a little bit more sophisticated. Let's add a pushbutton. Figure 2-17
shows a (Fritzing) circuit with a pushbutton
● 57
Kickstart to Arduino Nano
● 58
Chapter 2 • Playing with Electronics
Let's connect an external LED to the digital pin 13. Connect the anode of the LED to digital
pin 13 and then connect the cathode of the LED to the GND pin through a 470 ohm resistor.
After this, upload the sketch prog03.ino to the Nano board. The LED will start blinking.
NOTE: I am using the Arduino Nano Every for most of the demonstrations in this book.
Feel free to use the Arduino Nano instead. Just remember to select the correct board from
the Tools menu.
● 59
Kickstart to Arduino Nano
All the resistors are 470 ohm types You can turn on all the LEDs under software control
with the aid of prog04.ino:
prog04.ino
void setup()
{
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
}
void loop()
{
digitalWrite(2, HIGH);
digitalWrite(3, HIGH);
digitalWrite(4, HIGH);
digitalWrite(5, HIGH);
digitalWrite(6, HIGH);
digitalWrite(7, HIGH);
digitalWrite(8, HIGH);
digitalWrite(9, HIGH);
}
● 60
Chapter 2 • Playing with Electronics
Alternatively, you can make them blink (flash) with the following code:
prog05.ino
void setup()
{
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
}
void loop()
{
digitalWrite(2, HIGH);
digitalWrite(3, HIGH);
digitalWrite(4, HIGH);
digitalWrite(5, HIGH);
digitalWrite(6, HIGH);
digitalWrite(7, HIGH);
digitalWrite(8, HIGH);
digitalWrite(9, HIGH);
delay(1000);
digitalWrite(2, LOW);
digitalWrite(3, LOW);
digitalWrite(4, LOW);
digitalWrite(5, LOW);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
digitalWrite(8, LOW);
digitalWrite(9, LOW);
delay(1000);
}
Isn't this program too long? You can reduce the length of the program by using arrays and
loops as follows:
prog06.ino
int pins[8] = {2, 3, 4, 5, 6, 7, 8, 9};
void setup()
{
for ( int i=0; i<=7; i++ )
● 61
Kickstart to Arduino Nano
pinMode(pins[i], OUTPUT);
}
void loop()
{
This is a very compact way of writing programs. You are storing all the pin numbers in an
array and then accessing them with loops to get the desired results.
You can modify the earlier sketch to make the LEDs blink in succession. This is known as
the LED chaser effect. The sketch is as follows.
prog07.ino
int blink_duration = 50;
void setup()
{
for ( int i=0; i<=7; i++ )
pinMode(pins[i], OUTPUT);
}
void loop()
{
for ( int i=0; i<=7; i++ )
blink(pins[i], blink_duration);
}
● 62
Chapter 2 • Playing with Electronics
You can also implement a 4-bit binary counter by using only the first four LEDs connected
to pins D2, D3, D4, and D5:
prog08.py
int pins[8] = {2, 3, 4, 5};
int i = 0;
void setup()
{
for ( int i=0; i<=3; i++ )
pinMode(pins[i], OUTPUT);
}
void loop()
{
digitalWrite(pins[3], LOW);
digitalWrite(pins[2], LOW);
digitalWrite(pins[1], LOW);
digitalWrite(pins[0], LOW);
i++;
● 63
Kickstart to Arduino Nano
Till now, you have learned how to use the digital pins as outputs. It is possible to use a
digital pin as an input, though. You have to connect a pushbutton to it, as shown in Figure
2-10, where one end of the pushbutton is connected to D10, and another is connected to
the GND pin. Have a look at the following sketch.
prog09.ino
void setup()
{
pinMode(10, INPUT_PULLUP);
pinMode(LED_BUILTIN, OUTPUT);
}
void loop()
{
int sensorVal = digitalRead(10);
if (sensorVal == HIGH)
digitalWrite(LED_BUILTIN, LOW);
else
digitalWrite(LED_BUILTIN, HIGH);
}
● 64
Chapter 2 • Playing with Electronics
Every digital pin of the Arduino has a built-in pull-up resistor. When you initialize a digital
pin with the mode INPUT_PULLUP, it produces a LOW signal when pressed. When the
button is in the normal state, it is HIGH. The function digitalRead() reads the value of the
digital pin passed as the argument. This sketch makes the LED light when the pushbutton
is pressed.
The sketch (prog10.ino) uses a binary counter to show all the combinations of colors
possible by means of digital output. It shows 7 colors and an Off state (i.e., 8 combinations
using three digital output pins).
● 65
Kickstart to Arduino Nano
prog10.ino
int duration = 200;
void setup()
{
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
}
void loop()
{
digitalWrite(2, HIGH); digitalWrite(3, HIGH); digitalWrite(4, HIGH);
delay(duration);
digitalWrite(2, HIGH); digitalWrite(3, HIGH); digitalWrite(4, LOW);
delay(duration);
digitalWrite(2, HIGH); digitalWrite(3, LOW); digitalWrite(4, HIGH);
delay(duration);
digitalWrite(2, HIGH); digitalWrite(3, LOW); digitalWrite(4, LOW);
delay(duration);
digitalWrite(2, LOW); digitalWrite(3, HIGH); digitalWrite(4, HIGH);
delay(duration);
digitalWrite(2, LOW); digitalWrite(3, HIGH); digitalWrite(4, LOW);
delay(duration);
digitalWrite(2, LOW); digitalWrite(3, LOW); digitalWrite(4, HIGH);
delay(duration);
digitalWrite(2, LOW); digitalWrite(3, LOW); digitalWrite(4, LOW);
delay(duration);
}
If necessary, you can replace the common-cathode RGB LED with a common-anode RGB
LED. For that you have to adapt the circuit as shown in Figure 2-22.
● 66
Chapter 2 • Playing with Electronics
The sketch though will not need any modification to suit the common-anode RGB LED.
● 67
Kickstart to Arduino Nano
If you are planning to use Nano boards for industrial applications, then this is a good option.
It has the bare minimum requirements such as marked headers and provision to attach
wires for your control application.
In case you are looking for a more complex application with a dedicated power supply, then
the shield shown in Figure 2-24 is a good choice. It has separate sections of pins for Analog,
Digital, I2C, UART, and SPI. In addition, it has a dedicated power supply system.
● 68
Chapter 2 • Playing with Electronics
As you can see, it has a similar form factor as the Arduino Uno. Analog and digital pins have
dedicated groups for GND, VCC, and Signal. You can mount a Nano board on it as shown
in Figure 2-25.
● 69
Kickstart to Arduino Nano
Figure 2-25: Nano I/O expansion shield with a mounted Nano Every board.
Summary
In this chapter, you explored the digital input and output aspects of the Arduino Nano in
detail. You worked with various electronic components, built your first circuit, and wrote
your first Arduino sketch.
In the next chapter, you will learn how to deal with various types of Arduino-supported
buses. You will also learn how to work with analog input using the Arduino's analog pins.
● 70
Chapter 3 • Assorted Buses and the Analog Input
In the previous chapter, you learned the basics of electronic circuits and programming with
Arduino. Now, you are reasonably comfortable with building basic circuits and beginner's
level programming.
You will continue the exciting journey of Arduino programming. In this chapter, you will
learn the following topics:
After finishing this chapter, you will be at ease with various types of bus systems and the
concept of analog input.
As you can see, there is a separate bus line for every bit. This method is very fast as more
data can be carried in less time. However, this method is not particularly efficient as it re-
quires a lot of hardware, and, consequently, is expensive to implement. Most of the internal
buses in a microprocessor, such as the data bus, address bus, and control bus are parallel
buses.
A more efficient data transfer technique is Serial communication (or serial bus). Figure
3-2 represents a serial bus.
● 71
Kickstart to Arduino Nano
In serial communication systems, data bits are transferred in series, i.e., sequentially,
over a single channel. Usually, a serial communication system has a transmitter (TX) and
receiver (RX) pair for bidirectional communication. The serial data transfer is slower but
more efficient in terms of hardware and cost. There are two types of serial communication:
asynchronous and synchronous. In asynchronous serial communication, the TX and RX are
not synchronized by any clock but by the data bits. The best and the most commonly used
example of asynchronous serial communication is RS-232. Figure 3-2 shows "schematics"
of male and female connectors for a pair of RS-232 communication devices.
Figure 3-3: RS-232 male and female connectors (image by Cody.hyman under the
https://creativecommons.org/licenses/by-sa/3.0/deed.en license,
modified for publication)
The other type of serial data transfer is synchronous data transfer. Here, the endpoints
and data transfer are synchronized by clock pulses. There are many ways this can be im-
plemented. Prominent examples are the USART (universal synchronous and asynchronous
receiver-transmitter), Serial Peripheral Interface (SPI), and Inter-Integrated Circuit (I2C or
simply I2C). This chapter explores them in depth.
● 72
Chapter 3 • Assorted Buses and the Analog Input
Arduino Serial
All Arduino boards have at least one set of serial pins that are used for UART and USART.
The Arduino Nano and Arduino Nano have one set of serial pins. Digital Pins D0 and D1
serve a dual purpose: they are used for digital I/O while also configurable for Serial data
transfer. Since Arduino Nano boards have only one set of them, from here on, we will leave
pins D0 and D1 free for serial data transfer and will use other digital pins for the digital I/O.
D0 serves as RX and D1 serves as TX on both boards. We can monitor the data transfer on
these boards by using the built-in tool known as the Serial Monitor. It can be found under
the menu Tools as shown in Figure 3-4 .
● 73
Kickstart to Arduino Nano
Make sure that you check all the checkboxes at the bottom left. At the bottom right, select
Newline from the first dropdown and 9600 baud from the second dropdown as shown
in Figure 3-5. Let's play with this. Keep your eyes fixed on the Arduino board and type in
something in the textbox at the top. Then click the Send button or press the Enter key on
the keyboard. This will send the data as input to the RX pin. The LED associated with RX
will light briefly. If you send a very large string with, say, 200 characters, you will find that
the LED lights for a longer time.
Let's transmit some data over TX. All the data transmitted over TX is printed on the serial
console. Recall prog03.ino from the last chapter and modify it and save it with a new
filename under a new directory for this demo (I recommend organizing your code in chap-
ter-named directories as I am doing). Here is the modified code:
prog00.ino
void blink(int pin=LED_BUILTIN, int duration=1000)
{
digitalWrite(pin, HIGH);
Serial.println("LED On...");
delay(duration);
digitalWrite(pin, LOW);
Serial.println("LED Off..");
delay(duration);
}
void setup()
{
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(9600);
}
void loop()
{
blink();
}
The on-board LED connected to D13 (and any external one, if connected), will start blink-
ing. Also, the LED associated with the TX pin will blink momentarily every time the D13 LED
blinks. This is because you are sending data over "Serial". In the serial monitor tool, you
will see output like in Figure 3-6.
● 74
Chapter 3 • Assorted Buses and the Analog Input
You may have missed the printf() statement in C programming normally used to debug
programs. Well, Serial.println() offers the similar functionality.
You will learn to connect various devices to Arduino Nano boards that use these special
buses throughout this book.
Analog Input
In the previous chapter, you learned to work with the digital pins and pushbuttons. In this
section, you will learn to use the analog input pins of Nano boards. Nano boards have 8
different analog input pins (A0 through A7) and their resolution is 10 bits. Therefore, the
input can have 210 = 1024 different values. Those values range from 0 through 1023. Let's
build a circuit that reads input analog value of a potentiometer or a variable resistor. Figure
3-7 shows that device.
● 75
Kickstart to Arduino Nano
Potentiometers are usually operated with a knob fixed on a rotating axis. You can also use
a trimpot shown in Figure 3-8 as a variable resistor that is a bit more breadboard-friendly.
Let's use a trimpot variable-resistor with a range 0-1000 ohms for the analog input. Nearly
all trimpots acting as a variable resistance (including potentiometers) have three pins. The
middle pin (called wiper) outputs the signal. It should be connected to an analog input pin
of an Arduino board. Of the two remaining pins, one pin can be connected to the reference
voltage, and the remaining one can be connected to Ground. Note that the order is not
strict, which is why I do not mention exactly which pin in the earlier statement. Just make
sure that one pin on the extreme end is connected to 5 V, the middle pin is connected to
A0, and the last one is connected to the GND, as shown in Figure 3-9.
● 76
Chapter 3 • Assorted Buses and the Analog Input
prog01.ino
int resistor;
void setup()
{
Serial.begin(9600);
}
void loop()
{
resistor = analogRead(0);
Serial.println(resistor);
delay(100);
}
After uploading the sketch, open the serial monitor, and you will see something like in
Figure 3-10.
● 77
Kickstart to Arduino Nano
You can also see everything graphically with the serial plotter. Figure 3-11 shows how to
open the serial plotter.
Figure 3-11: Tracking the analog input values with the Serial Plotter utility.
● 78
Chapter 3 • Assorted Buses and the Analog Input
Figure 3-12: Using the Serial Plotter provides a graphical view of data values.
prog02.ino
int resistor;
float voltage;
void setup()
{
Serial.begin(9600);
}
void loop()
{
resistor = analogRead(0);
voltage = resistor * ( 5.0 / 1023.0 );
Serial.println(voltage);
delay(100);
}
The Arduino library has a built-in function map() that accepts a variable, a pair of input
ranges, and a pair of custom output ranges and then maps the input to the output fitting
the custom range. For example, you may want to convert the analog input from range 0 to
1023 to 0 to 255. It is done as follows.
● 79
Kickstart to Arduino Nano
prog03.ino
int resistor;
float mapped_range;
void setup()
{
Serial.begin(9600);
}
void loop()
{
resistor = analogRead(0);
mapped_range = map (resistor, 0, 1023, 0, 255) ;
Serial.println(mapped_range);
delay(100);
}
prog04.ino
float x, y1, y2, y3;
void setup()
{
Serial.begin(9600);
}
void loop()
{
for(x = 0; x < 360; x = x + 5)
{
y1 = x * x;
y2 = -x * x;
y3 = 100000 * cos(x * (3.1417 / 180));
Serial.print(y1);
Serial.print(" ");
Serial.print(y2);
Serial.print(" ");
Serial.println(y3);
delay(1);
}
}
This causes all the variables to be plotted in different colors. You can see the output in
Figure 3-13.
● 80
Chapter 3 • Assorted Buses and the Analog Input
Summary
In this chapter, you learned the basics of Arduino Serial and other buses. In addition, you
have learned to use the analog inputs and serial plotter.
In the next chapter, you will learn to use various displays in combination with Arduino Nano
boards.
● 81
Kickstart to Arduino Nano
Chapter 4 • P
ulse Width Modulation and Driving
Unipolar Stepper Motors with Digital I/O
In the previous chapter, you studied and practiced the Arduino serial, serial plotting, and
analog inputs. You also learned the basics of various buses and pins associated with them.
In this chapter, you will explore the amazing world of Pulse Width Modulation (abbre-
viated as PWM; alternative spelling: pulsewidth modulation). Here are the topics you will
study and demonstrate in this chapter:
Once you finish the chapter, you will be relaxed with the concept of PWM and its applica-
tions.
Figure 4-1: A digital signal carrying information. (adapted from the image provided by
El Pak under the https://creativecommons.org/licenses/by-sa/3.0/deed.en license)
So, withing the entire period, the signal is either HIGH or LOW. It is possible to modify the
digital signal in such a way that a part of the signal is HIGH and the remaining part is LOW
within a single period (or a single pulse). This is known as modulation of the width of the
pulse (PWM). Figure 4-2 shows a modulated digital signal.
Figure 4-2: A modulated digital signal. (adapted from the image by Cyril BUTTAY
under the https://creativecommons.org/licenses/by-sa/3.0/deed.en license)
● 82
Chapter 4 • Pulse Width Modulation and Driving Unipolar Stepper Motors with Digital I/O
Notice that in a single period pulse, you can see both signal levels, HIGH and LOW. Essen-
tially, you are manipulating the width of the HIGH signal. Figure 4-3 shows the anatomy of
a width-modulated digital pulse.
In a single pulse, the time for which the pulse is LOW is known as TOFF or TOFF and the time
for which it is HIGH is known as TON or TON. The following is the formula that shows the
relationship between the period, TON, and TOFF.
The duty cycle (also known as the power cycle) is the fraction of period for which the pulse
is active. It is determined in percentage with the following formula,
Figure 4-4: Duty cycle (adapted from the image by Thewrightstuff under the
https://creativecommons.org/licenses/by-sa/4.0/deed.en license)
Thus, you can cleverly use Arduino PWM for delivering the desired amount of power to an
LED or any other device of your choice.
● 83
Kickstart to Arduino Nano
You will have to use the function analogWrite() that accepts the PWM pin number and the
intensity of the PWM applied as arguments. Intensity ranges from 0 to 255. If the intensity
is 0, 63, 127, 255 it means 0%, 25%, 75%, 100% duty cycle, respectively. In addition, you
can have an intermediate percentage of values with the following formula,
Let's write and upload the sketch for the demonstration of the function analogWrite():
prog00.ino
int pwm_pin_d3 = 3;
int signal_duration = 2;
void setup()
{
pinMode(pwm_pin_d3, OUTPUT);
}
void loop()
{
for(int i=0; i<=255; i++)
● 84
Chapter 4 • Pulse Width Modulation and Driving Unipolar Stepper Motors with Digital I/O
{
analogWrite(pwm_pin_d3, i);
delay(signal_duration);
}
for(int i=255; i>=0; i--)
{
analogWrite(pwm_pin_d3, i);
delay(signal_duration);
}
}
This sketch supplies the intensity value, increasing first and then decreasing. This causes
the LED to light bright first and then fade. The change in the intensity of the LED is pre-pro-
grammed here. You can manipulate it with an analog input. You have to connect a trimpot
of any value to analog pin A0 to the same circuit, as shown in Figure 4-6.
You have to read the analog input from the analog pin A0 (which is in the range of 0 – 1023,
if you remember it from the last chapter) and then map it to the range of 0 – 255. Then
pass this new value to the function analogWrite() as the second argument, as follows:
prog01.ino
int pwm_pin_d3 = 3;
int input_signal, intensity;
void setup()
{
● 85
Kickstart to Arduino Nano
Serial.begin(9600);
pinMode(pwm_pin_d3, OUTPUT);
}
void loop()
{
input_signal = analogRead(0);
intensity = map(input_signal, 0, 1023, 0, 255);
Serial.println(intensity);
analogWrite(pwm_pin_d3, intensity);
}
Now, after uploading the sketch to the board, you can control the intensity using the trim-
pot. The variable resistor can be of any value, as the analog input will always convert it to
10-bit resolution (range of 0 through 1023). It is exactly this range that you are mapping
to the output intensity value.
You can even connect an RGB LED. Figure 4-7 shows the connections for a common-cath-
ode RGB LED.
Figure 4-7: Common-cathode RGB LED connected to PWM pins D3, D5, and D6.
● 86
Chapter 4 • Pulse Width Modulation and Driving Unipolar Stepper Motors with Digital I/O
prog02.ino
int blue_pin_d3 = 3;
int green_pin_d5 = 5;
int red_pin_d6 = 6;
void setup()
{
Serial.begin(9600);
pinMode(blue_pin_d3, OUTPUT);
pinMode(green_pin_d5, OUTPUT);
pinMode(red_pin_d6, OUTPUT);
}
void loop()
{
for ( int i = 0 ; i <= 255; i = i + 32 )
for ( int j = 0 ; j <= 255; j = j + 32 )
for ( int k = 0 ; k <= 255; k = k + 32 )
{
analogWrite(blue_pin_d3, i);
analogWrite(green_pin_d5, j);
analogWrite(red_pin_d6, k);
Serial.println(i);
Serial.println(' ');
Serial.println(j);
Serial.println(' ');
Serial.println(k);
}
}
Let's modify the RGB LED circuit and connect three trimpots to the analog pins A0, A1, and
A2 as given by the schematic in Figure 4-8.
● 87
Kickstart to Arduino Nano
The code is very simple. You just need to map the input analog values to the range of the
output as shown in the following sketch:
prog03.ino
int blue_pin_d3 = 3;
int green_pin_d5 = 5;
int red_pin_d6 = 6;
void setup()
{
Serial.begin(9600);
pinMode(blue_pin_d3, OUTPUT);
pinMode(green_pin_d5, OUTPUT);
pinMode(red_pin_d6, OUTPUT);
}
void loop()
{
analogWrite(blue_pin_d3, map(analogRead(0), 0, 1023, 0, 255));
analogWrite(green_pin_d5, map(analogRead(1), 0, 1023, 0, 255));
analogWrite(red_pin_d6, map(analogRead(2), 0, 1023, 0, 255));
}
● 88
Chapter 4 • Pulse Width Modulation and Driving Unipolar Stepper Motors with Digital I/O
Upload the sketch and feel free to play with the colors.
You can even use a common anode RGB LED. You just need to make a few minor changes
to the circuit as shown in Figure 4-9.
● 89
Kickstart to Arduino Nano
There is a built-in library for handling servomotors. Let's create the sketch for this servo
using the necessary library:
prog04.ino
#include <Servo.h>
Servo servo1;
int servo1_pin = 3, pos = 0;
void setup()
{
servo1.attach(servo1_pin);
}
void loop()
{
for (pos = 0; pos <= 180; pos = pos + 6)
{
servo1.write(pos);
delay(1000);
}
delay(5000);
}
● 90
Chapter 4 • Pulse Width Modulation and Driving Unipolar Stepper Motors with Digital I/O
This is a very simple program. You are importing something for the very first time. The first
statement imports the required library file to the sketch. It is an integral library and you
do not have to install anything. Then you are creating an object for the servo motor. The
function attach() in the setup() associated the PWM pin mentioned in the argument to
the object and initializes it. You can send the position angle for the servo using the function
write(). The argument ranges from 0 to 180. This function sets the angle of the servo to
the specified angle. This program successively increases the angle. Upload the sketch to the
Arduino Nano to see it in action.
You can improve the project by attaching a trimpot to read the values and set the angle of
the servo. Let's try that. The schematic in Figure 4-11 adds a trimpot to the analog input
pin A0.
The code for the sketch is very simple. You just have to map the analog input range (0
through 1023) to the range of angle of rotation (0 through 180 degrees).
● 91
Kickstart to Arduino Nano
prog05.ino
#include <Servo.h>
Servo servo1;
int servo1_pin = 3;
void setup()
{
servo1.attach(servo1_pin);
}
void loop()
{
servo1.write(map(analogRead(0), 0, 1023, 0, 180));
delay(100);
}
As you rotate the dial of the trimpot, you can see the angle of rotation of the servo change
in real time.
Working with the 28BYJ-48 Unipolar Stepper Motor and the ULN2003A
Motor Driver
This section is really a part of the digital I/O chapter since you will use the digital pin to
drive the Unipolar stepper motor. Nevertheless, the topic is pretty advanced for beginners.
That is why I decided to include it here, after the discussion on servo motors.
Let's learn the basics of the components we will be using in this section. The very first
component is a stepper motor. A stepper motor is also known as a step motor or a stepping
motor. It is a brushless electric motor that needs DC current to work. In other words, it uses
magnetic fields to move the motor.
In a stepper motor, a complete rotation of 360 degrees is divided into equal number of
steps. Stepper motors use four electromagnets and a cogged wheel for operation. In a
unipolar stepper motor, there is one winding per phase. You can turn on each section of a
winding to generate a magnetic field in that section. This requires a transistor, or rather an
array of transistors, for operations. A unipolar stepper motor usually has five pins. These
pins must be connected to a stepper motor controller that can activate the transistors. You
will use the 28BYJ-48 unipolar stepper motor for this demonstration. The stepper motor has
a Gear Reduction Ratio of 63.68395:1, resulting in approximately 4076 steps per complete
revolution in half-step mode.
This prompts a discussion related to the stepper motor controller. You will use a stepper
motor controller that uses an IC type ULN2003A, an array of seven NPN Darlington transis-
tors that uses common cathode diodes for implementation. You can read the data sheet of
the IC at the following URLs:
https://www.ti.com/lit/ds/symlink/uln2003a.pdf
https://www.ti.com/product/ULN2003A
● 92
Chapter 4 • Pulse Width Modulation and Driving Unipolar Stepper Motors with Digital I/O
You will not directly use the IC as you will have to build a circuit around it. So, you will use
a ready-made stepper motor driver board containing a type ULN2003A IC. This chip sends
a series of pulses to the motor. The spinning direction of the motor is decided by the se-
quence of the pulses. The speed of the motor is determined by the frequency of the pulses.
You can connect the board to a 28BYJ-48 motor as shown in Figure 4-13.
● 93
Kickstart to Arduino Nano
The pins of the motor come with a male-type adapter that fits perfectly on the female port
of the stepper motor controller board. You cannot get it wrong; these devices are truly
manufactured for each other. Let's connect this to an Arduino Nano board as shown in
Figure 4-14.
● 94
Chapter 4 • Pulse Width Modulation and Driving Unipolar Stepper Motors with Digital I/O
Note: You can download the Fritzing parts for the motor and the driver board from the
following URLs:
https://github.com/e-radionicacom/e-radionica.com-Fritzing-Library-parts-/blob/
master/28BYJ-48%20Stepper%20Motor.fzpz
https://github.com/e-radionicacom/e-radionica.com-Fritzing-Library-parts-/blob/
master/ULN2003A%20breakout%20board.fzpz
The connection between the stepper motor and the driver board is straightforward as the
motor has a male plug, and the board has a female port. Let's discuss the connections be-
tween the motor driver board and Nano board. Power the motor driver board separately as
it may generate noise and damage the Nano board if connected to it. The best option is to
use an MB 102-style breadboard power supply with it.
Near the ULN2003A IC, you will see seven pins (IN1 through IN7). The last three (IN5, IN6,
IN7) are disabled in most of the motor driver boards as the stepper motor you are using
only needs the first four pins IN1, IN2, IN3, and IN4. For counterclockwise (anticlockwise)
rotation of the motor shaft (corresponding to Figure 4-14), the following table applies.
D2 IN1
D3 IN2
D4 IN3
D5 IN4
● 95
Kickstart to Arduino Nano
D2 IN4
D3 IN3
D4 IN2
D5 IN1
prog06.ino
int A=2, B=3, C=4, D=5;
int steps_per_rotation=512;
int duration=5;
int sequence[8][4]={{1,0,0,0},
{1,1,0,0},
{0,1,0,0},
{0,1,1,0},
{0,0,1,0},
{0,0,1,1},
{0,0,0,1},
{1,0,0,1}};
void setup()
{
pinMode(A, OUTPUT);
pinMode(B, OUTPUT);
pinMode(C, OUTPUT);
pinMode(D, OUTPUT);
}
void single_step(){
for(int i=0; i<8; i++)
{
send_sequence(sequence[i][0],
sequence[i][1],
sequence[i][2],
● 96
Chapter 4 • Pulse Width Modulation and Driving Unipolar Stepper Motors with Digital I/O
sequence[i][3]);
delay(duration);
}
}
void loop()
{
int i=0;
while(i<steps_per_rotation)
{
single_step();
i++;
}
}
This is a relatively large program. Let's understand it block by block. In the first line, you
are defining the digital pins of the Nano board to be used. By reversing this line, you can
change the direction of the motor. Next, you are defining steps per full rotation (revolution)
and the delay between the microsteps. There are four coils in the motor. You are supply-
ing the positive voltage (1 or HIGH) to one or two coils in sequence from A to D. This will
make the motor shaft revolve in a particular direction (depending on your wiring). So, you
created a 2D array (or matrix) of the sequences to be applied to each coil. In the setup(),
you are initializing the pre-defined pins as the digital output pins. The customs function
send_sequence() sends the transferred values to the respective pins. You can reverse the
sequence to change the direction of rotation here too. The custom function single_step()
sends the values in the sequence matrix row-wise to the motor driver. This calls send_se-
quence() once per row in the sequence matrix. You are calling this function for every step
in the rotation in the loop() section. You can also change the direction of the rotation by
mirroring the signal sequence matrix along with the Y-axis (mirroring column-wise). This
is known as microstepping technique.
You can make the motor rotate faster by changing the sequence matrix as follows:
int sequence[4][4]={{1,1,0,0},
{0,1,1,0},
{0,0,1,1},
{1,0,0,1}};
void single_step(){
for(int i=0; i<4; i++)
{
send_sequence(sequence[i][0],
sequence[i][1],
sequence[i][2],
● 97
Kickstart to Arduino Nano
sequence[i][3]);
delay(duration);
}
}
This will increase the speed of the motor. I have added the modified program to the code
bundle in the book. You can find it in the relevant directory for this chapter. The file is
named prog07.ino.
Figure 4-17: Installing a custom library (AccelStepper) for the stepper motor.
● 98
Chapter 4 • Pulse Width Modulation and Driving Unipolar Stepper Motors with Digital I/O
prog08.ino
#include<AccelStepper.h>
const int FULLSTEP=4;
AccelStepper stepper1(FULLSTEP, 2, 4, 3, 5);
void setup()
{
stepper1.setMaxSpeed(1000.0);
stepper1.moveTo(2038);
}
void loop()
{
stepper1.setSpeed(500);
stepper1.runSpeed();
}
Let's understand the meaning of the sketch. In the very first line, you are importing the
installed third-party library. In the second line, you are deciding what step to use. There are
three types of step. The first one is the microstep, which you have already implemented by
manually sending the signal matrix row-by-row in the earlier example. The other two are
full step and half step modes. You are going to use full-step mode in this example. Then
you created the object by passing the stepping mode and the pin numbers. Please pass
the pin numbers to the constructor exactly the same way it is printed in the sketch (it is
not a typo or printing error, but the legitimate sequence of pin numbers). In the setup(),
you are setting the maximum number of steps per second (maximum speed) and moving
the stepper motor to the starting position. Finally, in the loop(), you are stating the speed
(steps per second) and then stepping the motor at the end. Upload the sketch and see the
motor in action.
You can modify the program to make the motor rotate in the other direction with half step
by modifying the following two lines.
I have included this code in a separate file in the code bundle, under this chapter's directo-
ry. The file is called prog09.ino.
prog10.ino
#include<AccelStepper.h>
const int HALFSTEP=8;
AccelStepper stepper1(HALFSTEP, 5, 3, 4, 2);
void setup()
● 99
Kickstart to Arduino Nano
{
stepper1.setMaxSpeed(1000.0);
stepper1.moveTo(2038);
}
void loop()
{
stepper1.setCurrentPosition(0);
while (stepper1.currentPosition() != 2048)
{
stepper1.setSpeed(1000);
stepper1.runSpeed();
}
delay(1000);
stepper1.setCurrentPosition(0);
while (stepper1.currentPosition() != -2048)
{
stepper1.setSpeed(-1000);
stepper1.runSpeed();
}
delay(1000);
}
There are a couple of new functions in this example. Function setCurrentPosition() sets
the position of the shaft. Function currentPosition() returns the current position of the
shaft. This example makes the shaft rotate in both directions alternatingly because you are
changing the direction of the motor by passing a positive and a negative speed to function
setSpeed().
You can rewrite the entire code with a few new functions too:
prog11.ino
#include<AccelStepper.h>
const int HALFSTEP=8;
AccelStepper stepper1(HALFSTEP, 5, 3, 4, 2);
void setup()
{
stepper1.setMaxSpeed(1000.0);
stepper1.setSpeed(100);
stepper1.setAcceleration(75.0);
stepper1.setCurrentPosition(0);
stepper1.moveTo(2038);
}
void loop()
{
if (stepper1.distanceToGo() == 0)
stepper1.moveTo(-stepper1.currentPosition());
● 100
Chapter 4 • Pulse Width Modulation and Driving Unipolar Stepper Motors with Digital I/O
stepper1.run();
}
You are using a few new functions in this example. Function setAcceleration() sets the
acceleration (change in speed over time). You can witness that the speed of the motor is
changing by observing the LEDs on the motor driver board. The rate at which they blink
will change once the speed changes. The function distanceToGo() computes the distance
from the target position.
Here, you need to use two different sets of the digital I/O pins for both stepper motor con-
trollers. Here is the code:
prog12.ino
#include<AccelStepper.h>
const int HALFSTEP=8, FULLSTEP=4;
AccelStepper stepper1(HALFSTEP, 5, 3, 4, 2);
AccelStepper stepper2(FULLSTEP, 8, 10, 9, 11);
void setup()
{
stepper1.setMaxSpeed(1000.0);
stepper1.setSpeed(100);
stepper1.setAcceleration(75.0);
● 101
Kickstart to Arduino Nano
stepper1.setCurrentPosition(0);
stepper1.moveTo(2038);
stepper2.setMaxSpeed(1000.0);
stepper2.setSpeed(150);
stepper2.setAcceleration(50.0);
stepper2.setCurrentPosition(0);
stepper2.moveTo(-2038);
}
void loop()
{
if (stepper1.distanceToGo() == 0)
stepper1.moveTo(-stepper1.currentPosition());
if (stepper2.distanceToGo() == 0)
stepper2.moveTo(-stepper2.currentPosition());
stepper1.run();
stepper2.run();
}
Since you are already familiar with all the functions, I won't explain this example. Just up-
load the code to the Nano board and see it in action.
Summary
In this chapter, you learned the fundamentals of PWM (Pulse Width Modulation). You used
it with LEDs, RGB LEDs, and SG90 servo motors. You also worked with a unipolar stepper
motor and an associated motor controller.
In the next chapter, you will explore in detail how to use various types of ready-made dis-
plays with the Arduino.
● 102
Chapter 5 • Plotting Geometric Art on an External Display
Chapter 5 • P
lotting Geometric Art on an
External Display
In the previous chapter, you learned to labor with PWM (Pulse Width Modulation). You used
PWM to fade a normal and an RGB LED. Furthermore, you used it to control an SG90 servo
motor. At this point, you should be reasonably comfortable with the concept and applica-
tions of PWM.
In this chapter, you will be introduced to an external display module based on Ilitek 9225
driver IC. You will also learn to create art — or "artwork" — with the external display.
You can purchase a 2.2-inch 166x220 TFT LCD with on-board 9225 driver as a single
package. Many times, the device comes with an embedded microSD card reader which has
separate pins. You can check online marketplaces or hobby electronics stores for this dis-
play. The datasheet for the driver IC can be found at:
https://www.displayfuture.com/Display/datasheet/controller/ILI9225.pdf
Let's see how to connect this interesting unit with the Nano board. The following table ex-
plains the display module pins mapped with the Nano board pins.
VCC +5 V
GND GND
GND No connection
NC No connection
NC No connection
NC No connection
SCK A0
SDA A1
RS A2
RST A3
CS A4
You will have to install a library for this module to make it work with your Arduino. Open the
Library Manager from the Sketch Menu and search for: 9225. Figure 5-1 is the screen-
shot of the menu opened up.
● 103
Kickstart to Arduino Nano
Install the TFT_22_ILI9225 library by Nkawu. You can read the documentation of the
library at:
https://github.com/Nkawu/TFT_22_ILI9225
https://github.com/Nkawu/TFT_22_ILI9225/wiki.
You are going to use the SPI (Serial Peripheral Interface) protocol to work with the dis-
play. You will also need to use the recently installed ILI9225 library. So, let's import both
libraries:
#include "SPI.h"
#include "TFT_22_ILI9225.h"
Let's use preprocessor directives to define a few macros for pin assignments, as follows:
● 104
Chapter 5 • Plotting Geometric Art on an External Display
#define TFT_CS A4
#define TFT_RST A3
#define TFT_RS A2
#define TFT_SDI A1
#define TFT_CLK A0
#define TFT_BRIGHTNESS 200
Note that, across the manufacturers, the pins may have different names. Let's create an
object corresponding to the TFT display:
void setup()
{
tft.begin();
tft.setBacklight(true);
tft.setDisplay(true);
tft.setBackgroundColor(COLOR_BLACK);
tft.setOrientation(0);
Serial.begin(9600);
The following code block is used to detect the orientation (we already set it):
Serial.print("Orientation: ");
switch (tft.getOrientation())
{
case 0:
Serial.print("Portrait");
● 105
Kickstart to Arduino Nano
break;
case 1:
Serial.print("Right Rotated Landscape");
break;
case 2:
Serial.print("Reverse Portrait");
break;
case 3:
Serial.print("Left Rotated Landscape");
break;
default:
Serial.print("Invalid Orientation...");
}
void loop()
{
tft.clear();
Note that this is very computationally "heavy" and it takes a few seconds to clear the dis-
play. So, if you are planning a simple animation, you cannot afford to call this every time
to clear the display as it won't be fast enough.
tft.setFont(Terminal6x8);
You can draw text by providing the coordinates, the text, and the color, like so:
● 106
Chapter 5 • Plotting Geometric Art on an External Display
You can also draw lines by providing the coordinates of the endpoints. Also, the routine
setcolor() accepts three 8-bit unsigned integer arguments R, G, and B (ranging from 0 to
255) and converts them into a single 16-bit number corresponding to an RGB color:
Here, we are creating a gradient image of red, green, and blue colors. Now, consider draw-
ing a hollow rectangle and a solid rectangle by providing the opposite vertices and the color
as arguments, like this:
tft.clear();
tft.drawText(10, 10, "Rectangle");
tft.drawRectangle(20, 20, 100, 100, COLOR_BLUE);
delay(1000);
tft.drawText(10, 10, "Rectangle (Solid)");
tft.fillRectangle(20, 20, 100, 100, COLOR_RED);
delay(1000);
Now, draw a hollow circle and a solid circle by providing the coordinates of the center, ra-
dius, and color:
tft.clear();
tft.drawText(10, 10, "Circle");
tft.drawCircle(tft.maxX()/2, tft.maxY()/2, 50, COLOR_YELLOW);
delay(1000);
tft.drawText(10, 10, "Circle (Solid)");
tft.fillCircle(tft.maxX()/2, tft.maxY()/2, 50, COLOR_GREEN);
delay(1000);
}
The routines that commence with the string draw are for drawing hollow figures, and those
commencing with the string fill are for solid figures. Putting it all together, we obtain the
following sketch:
prog00.ino
#include "SPI.h"
#include "TFT_22_ILI9225.h"
#define TFT_CS A4
#define TFT_RST A3
#define TFT_RS A2
● 107
Kickstart to Arduino Nano
#define TFT_SDI A1
#define TFT_CLK A0
#define TFT_BRIGHTNESS 200
TFT_22_ILI9225 tft = TFT_22_ILI9225(TFT_RST, TFT_RS, TFT_CS, TFT_SDI, TFT_CLK,
TFT_BRIGHTNESS);
void setup()
{
tft.begin();
tft.setBacklight(true);
tft.setDisplay(true);
tft.setBackgroundColor(COLOR_BLACK);
tft.setOrientation(0);
Serial.begin(9600);
Serial.print("Orientation: ");
switch (tft.getOrientation())
{
case 0:
Serial.print("Portrait");
break;
case 1:
Serial.print("Right Rotated Landscape");
break;
case 2:
Serial.print("Reverse Portrait");
break;
case 3:
Serial.print("Left Rotated Landscape");
break;
default:
Serial.print("Invalid Orientation...");
}
Serial.print("\nNumber of rows: ");
Serial.println(tft.maxX());
Serial.print("Number of columns: ");
Serial.println(tft.maxY());
}
void loop()
{
tft.clear();
tft.setFont(Terminal6x8);
tft.drawText(10, 10, "Gradient Demo", COLOR_WHITE);
delay(1000);
for( int i = 0; i < tft.maxY(); i++ )
{
tft.drawLine(0, i, tft.maxX()/3, i, tft.setColor(i, 0, 0));
● 108
Chapter 5 • Plotting Geometric Art on an External Display
I have adjusted the delay in the above program and all the subsequent programs. It allows
me to capture photographs of the output on the TFT LCD using my digital camera. Let's
see the output screens step by step. The string "Gradient Demo" colored white against the
black background is printed first as in Figure 5-1.
● 109
Kickstart to Arduino Nano
I have used a Lumix GH5 in manual photography mode to capture the output. Since I am
not a great photographer, the photographs may not be of the best quality. Moreover, a
consumer-grade digital camera cannot truthfully capture the output produced on a digital
display. Fortunately, its output looks much better in reality.
After the text, the system displays a gradient image created using individual lines, like in
Figure 5-3.
● 110
Chapter 5 • Plotting Geometric Art on an External Display
● 111
Kickstart to Arduino Nano
And the final image in the sequence is a solid (filled) circle or ball; see Figure 5-7.
Pay close attention to how the circle is filled with the assigned color. Since you have writ-
ten this sequence inside the loop() section, it keeps on repeating as long as the Arduino
board is powered on. We are following the similar pattern for most of the examples in the
remainder of the chapter.
● 112
Chapter 5 • Plotting Geometric Art on an External Display
Let's check out another example. You will create circles of gradients of the colors red,
green, and blue, respectively. It will be followed by dots of random color at random posi-
tions. Here is the sketch.
prog01.ino
#include "SPI.h"
#include "TFT_22_ILI9225.h"
#define TFT_CS A4
#define TFT_RST A3
#define TFT_RS A2
#define TFT_SDI A1
#define TFT_CLK A0
#define TFT_BRIGHTNESS 200
TFT_22_ILI9225 tft = TFT_22_ILI9225(TFT_RST, TFT_RS, TFT_CS, TFT_SDI, TFT_CLK,
TFT_BRIGHTNESS);
void setup()
{
tft.begin();
tft.setBacklight(true);
tft.setDisplay(true);
tft.setBackgroundColor(COLOR_BLACK);
tft.setOrientation(0);
Serial.begin(9600);
}
void loop()
{
tft.clear();
tft.setFont(Terminal6x8);
tft.drawText(10, 10, "Animation Demo!");
delay(1000);
for ( int i=0; i<(tft.maxX()/2); i++)
{
tft.drawCircle(tft.maxX()/2, tft.maxY()/2, i, random(0xffff));
delay(10);
}
tft.clear();
for ( int i=0; i<(tft.maxX()/2); i++)
{
tft.drawCircle(tft.maxX()/2, tft.maxY()/2, i, tft.setColor(i, 0, 0));
delay(10);
}
tft.clear();
for ( int i=0; i<(tft.maxX()/2); i++)
{
tft.drawCircle(tft.maxX()/2, tft.maxY()/2, i, tft.setColor(0, i, 0));
delay(10);
● 113
Kickstart to Arduino Nano
}
tft.clear();
for ( int i=0; i<(tft.maxX()/2); i++)
{
tft.drawCircle(tft.maxX()/2, tft.maxY()/2, i, tft.setColor(0, 0, i));
delay(10);
}
tft.clear();
tft.drawText(10, 10, "Random Demo!");
for (int i = 0; i < 6000; i++)
{
tft.drawPixel(random(tft.maxX()), random(tft.maxY()), random(0xffff));
delay(1);
}
delay(1000);
}
Note that you are using a routine called drawPixel() in this sketch. It accepts the coordi-
nates and the color values for a pixel and draws it on the display. The pixels of random color
and random position appear as in Figure 5-9
● 114
Chapter 5 • Plotting Geometric Art on an External Display
We know that the resolution of the screen is 176 × 220. Both numbers are divisible by 11
and 22. So, let's divide the display into a grid where individual square is of size 22 × 22 and
use it to show repetitive patterns. As a matter of fact, I got this idea of printing repetitive
geometric patterns from the floor and wall tiles of my home. Here comes the complete
sketch.
prog02.ino
#include "SPI.h"
#include "TFT_22_ILI9225.h"
#define TFT_CS A4
#define TFT_RST A3
#define TFT_RS A2
#define TFT_SDI A1
#define TFT_CLK A0
#define TFT_BRIGHTNESS 200
TFT_22_ILI9225 tft = TFT_22_ILI9225(TFT_RST, TFT_RS, TFT_CS, TFT_SDI, TFT_CLK,
TFT_BRIGHTNESS);
void setup()
{
tft.begin();
tft.setBacklight(true);
tft.setDisplay(true);
tft.setBackgroundColor(COLOR_BLACK);
tft.setOrientation(0);
● 115
Kickstart to Arduino Nano
Serial.begin(9600);
}
void loop()
{
tft.clear();
for ( int i = 0; i < 176; i = i+22 )
{
for (int j = 0; j < 220; j = j+22 )
{
tft.fillTriangle(i, j+21, i+21, j+21, i+21, j, random(0xffff));
Serial.println(i);
}
}
delay(5000);
}
You are using the routine fillTriangle() to draw a solid triangle. It accepts the coordinates
of the three vertices of the triangle and the color as arguments. The output should look like
Figure 5-10.
You can also write the sketch in such a way that the triangles are oriented in a random
fashion in the cell. The sketch is as follows.
● 116
Chapter 5 • Plotting Geometric Art on an External Display
prog03.ino
#include "SPI.h"
#include "TFT_22_ILI9225.h"
#define TFT_CS A4
#define TFT_RST A3
#define TFT_RS A2
#define TFT_SDI A1
#define TFT_CLK A0
#define TFT_BRIGHTNESS 200
TFT_22_ILI9225 tft = TFT_22_ILI9225(TFT_RST, TFT_RS, TFT_CS, TFT_SDI, TFT_CLK,
TFT_BRIGHTNESS);
void setup()
{
tft.begin();
tft.setBacklight(true);
tft.setDisplay(true);
tft.setBackgroundColor(COLOR_BLACK);
tft.setOrientation(0);
Serial.begin(9600);
}
void loop()
{
tft.clear();
for ( uint8_t i = 0; i < 176; i = i+22 )
{
for ( uint8_t j = 0; j < 220; j = j+22 )
{
uint8_t x1 = i, y1 = j;
uint8_t x2 = i+21, y2 = j;
uint8_t x3 = i, y3 = j+21;
uint8_t x4 = i+21, y4 = j+21;
uint8_t choice = random(4);
if (choice == 0)
tft.drawTriangle(x1, y1, x2, y2, x3, y3, COLOR_WHITE);
if (choice == 1)
tft.drawTriangle(x1, y1, x2, y2, x4, y4, COLOR_WHITE);
if (choice == 2)
tft.drawTriangle(x1, y1, x4, y4, x3, y3, COLOR_WHITE);
if (choice == 3)
tft.drawTriangle(x4, y4, x2, y2, x3, y3, COLOR_WHITE);
}
}
delay(5000);
}
● 117
Kickstart to Arduino Nano
Since the pattern is random, there can be many combinations. It will produce a different
output every time the sketch is executed.
You can even divide the display in cells of size 11 × 11 and draw triangles. This time let's
randomize the colors as well. Use this sketch:
prog04.ino
#include "SPI.h"
#include "TFT_22_ILI9225.h"
#define TFT_CS A4
#define TFT_RST A3
#define TFT_RS A2
#define TFT_SDI A1
#define TFT_CLK A0
#define TFT_BRIGHTNESS 200
TFT_22_ILI9225 tft = TFT_22_ILI9225(TFT_RST, TFT_RS, TFT_CS, TFT_SDI, TFT_CLK,
TFT_BRIGHTNESS);
void setup()
{
tft.begin();
tft.setBacklight(true);
tft.setDisplay(true);
tft.setBackgroundColor(COLOR_BLACK);
tft.setOrientation(0);
● 118
Chapter 5 • Plotting Geometric Art on an External Display
Serial.begin(9600);
}
void loop()
{
tft.clear();
for ( uint8_t I = 0; i < 176; i = i+11 )
{
for ( uint8_t j = 0; j < 220; j = j+11 )
{
uint8_t x1 = i, y1 = j;
uint8_t x2 = i+10, y2 = j;
uint8_t x3 = i, y3 = j+10;
uint8_t x4 = i+10, y4 = j+10;
uint8_t choice = random(4);
if (choice == 0)
tft.drawTriangle(x1, y1, x2, y2, x3, y3, random(0xffff));
if (choice == 1)
tft.drawTriangle(x1, y1, x2, y2, x4, y4, random(0xffff));
if (choice == 2)
tft.drawTriangle(x1, y1, x4, y4, x3, y3, random(0xffff));
if (choice == 3)
tft.drawTriangle(x4, y4, x2, y2, x3, y3, random(0xffff));
}
}
delay(5000);
}
● 119
Kickstart to Arduino Nano
prog05.ino
#include""SPI.""
#include""TFT_22_ILI9225.""
#define TFT_CS A4
#define TFT_RST A3
#define TFT_RS A2
#define TFT_SDI A1
#define TFT_CLK A0
#define TFT_BRIGHTNESS 200
TFT_22_ILI9225 tft = TFT_22_ILI9225(TFT_RST, TFT_RS, TFT_CS, TFT_SDI, TFT_CLK,
TFT_BRIGHTNESS);
void setup()
{
tft.begin();
tft.setBacklight(true);
tft.setDisplay(true);
tft.setBackgroundColor(COLOR_BLACK);
tft.setOrientation(0);
Serial.begin(9600);
}
void loop()
{
● 120
Chapter 5 • Plotting Geometric Art on an External Display
tft.clear();
for ( uint8_t i = 0; i < 176; i = i+11 )
{
for ( uint8_t j = 0; j < 220; j = j+11 )
{
uint8_t x1 = i, y1 = j;
uint8_t x2 = i+10, y2 = j;
uint8_t x3 = i, y3 = j+10;
uint8_t x4 = i+10, y4 = j+10;
tft.drawRectangle(x1, y1, x4, y4, random(0xffff));
}
}
delay(5000);
}
You can use fillRectangle() to draw random solid squares. You can find that in prog06.
ino of the code bundle of this chapter (5). That sketch produces output as shown in Figure
5-14:
● 121
Kickstart to Arduino Nano
You can even draw a pair of random-colored lines joining the opposite vertices of every cell
to create a nice pattern. Check the following sketch:
prog07.ino
#include""SPI.""
#include""TFT_22_ILI9225.""
#define TFT_CS A4
#define TFT_RST A3
#define TFT_RS A2
#define TFT_SDI A1
#define TFT_CLK A0
#define TFT_BRIGHTNESS 200
TFT_22_ILI9225 tft = TFT_22_ILI9225(TFT_RST, TFT_RS, TFT_CS, TFT_SDI, TFT_CLK,
TFT_BRIGHTNESS);
void setup()
{
tft.begin();
tft.setBacklight(true);
tft.setDisplay(true);
tft.setBackgroundColor(COLOR_BLACK);
tft.setOrientation(0);
Serial.begin(9600);
}
void loop()
● 122
Chapter 5 • Plotting Geometric Art on an External Display
{
tft.clear();
for ( uint8_t i = 0; i < 176; i = i+11 )
{
for ( uint8_t j = 0; j < 220; j = j+11 )
{
uint8_t x1 = i, y1 = j;
uint8_t x2 = i+10, y2 = j;
uint8_t x3 = i, y3 = j+10;
uint8_t x4 = i+10, y4 = j+10;
tft.drawLine(x1, y1, x4, y4, random(0xffff));
tft.drawLine(x2, y2, x3, y3, random(0xffff));
}
}
delay(5000);
}
You can also connect all the vertices of a cell and create pattern, as shown in the following
sketch:
● 123
Kickstart to Arduino Nano
prog08.ino
#include "SPI.h"
#include "TFT_22_ILI9225.h"
#define TFT_CS A4
#define TFT_RST A3
#define TFT_RS A2
#define TFT_SDI A1
#define TFT_CLK A0
#define TFT_BRIGHTNESS 200
TFT_22_ILI9225 tft = TFT_22_ILI9225(TFT_RST, TFT_RS, TFT_CS, TFT_SDI, TFT_CLK,
TFT_BRIGHTNESS);
void setup()
{
tft.begin();
tft.setBacklight(true);
tft.setDisplay(true);
tft.setBackgroundColor(COLOR_BLACK);
tft.setOrientation(0);
Serial.begin(9600);
}
void loop()
{
tft.clear();
for ( uint8_t i = 0; i < 176; i = i+11 )
{
for ( uint8_t j = 0; j < 220; j = j+11 )
{
uint8_t x1 = i, y1 = j;
uint8_t x2 = i+10, y2 = j;
uint8_t x3 = i, y3 = j+10;
uint8_t x4 = i+10, y4 = j+10;
tft.drawLine(x1, y1, x2, y2, random(0xffff));
tft.drawLine(x1, y1, x3, y3, random(0xffff));
tft.drawLine(x1, y1, x4, y4, random(0xffff));
tft.drawLine(x2, y2, x3, y3, random(0xffff));
tft.drawLine(x2, y2, x4, y4, random(0xffff));
tft.drawLine(x3, y3, x4, y4, random(0xffff));
}
}
delay(5000);
}
● 124
Chapter 5 • Plotting Geometric Art on an External Display
prog09.ino
#include "SPI.h"
#include "TFT_22_ILI9225.h"
#define TFT_CS A4
#define TFT_RST A3
#define TFT_RS A2
#define TFT_SDI A1
#define TFT_CLK A0
#define TFT_BRIGHTNESS 200
TFT_22_ILI9225 tft = TFT_22_ILI9225(TFT_RST, TFT_RS, TFT_CS, TFT_SDI, TFT_CLK,
TFT_BRIGHTNESS);
void setup()
{
tft.begin();
tft.setBacklight(true);
tft.setDisplay(true);
tft.setBackgroundColor(COLOR_BLACK);
tft.setOrientation(0);
Serial.begin(9600);
}
void loop()
{
● 125
Kickstart to Arduino Nano
tft.clear();
for ( uint8_t i = 0; i < 176; i = i+11 )
{
for ( uint8_t j = 0; j < 220; j = j+11 )
{
uint8_t x1 = i, y1 = j;
uint8_t x2 = i+10, y2 = j;
uint8_t x3 = i, y3 = j+10;
uint8_t x4 = i+10, y4 = j+10;
tft.drawCircle(i+5, j+5, 5, random(0xffff));
}
}
delay(5000);
}
Proceed by using the routine fillCircle() to draw solid-colored circles. You can find the code
in the sketch called prog10.ino in the code bundle. The output is as follows (Figure 5-18):
● 126
Chapter 5 • Plotting Geometric Art on an External Display
Calling a routine within itself is known as recursion and you can use it to draw various ge-
ometric figures. There are two types of recursion: direct recursion and indirect. In direct
recursion, the routine calls itself. In indirect recursion, there are multiple routines calling
each other and thus creating a chain of function calls. You will use direct recursion to create
a couple of geometric patterns.
In any recursive program, the function calls itself with slightly altered arguments. The re-
cursive function has two parts: termination condition and recursive call. The termination
condition decides when the recursive call should be made. In the absence of this, the re-
cursion will run forever. The recursive call is part of the recursive function that calls itself
with altered arguments.
If you are curious, you can read more about the Sierpinski triangle. Given the vertices of
any triangle, you can divide that triangle in four triangles by connecting the midpoints of
the sides. Go ahead and write a routine for it and pass the coordinates of the endpoints
of the sides of the smaller triangles in each pass. This will create an interesting geometric
pattern. The sketch is as follows:
prog11.ino
#include "SPI.h"
#include "TFT_22_ILI9225.h"
#define TFT_CS A4
#define TFT_RST A3
#define TFT_RS A2
● 127
Kickstart to Arduino Nano
#define TFT_SDI A1
#define TFT_CLK A0
#define TFT_BRIGHTNESS 200
TFT_22_ILI9225 tft = TFT_22_ILI9225(TFT_RST, TFT_RS, TFT_CS, TFT_SDI, TFT_CLK,
TFT_BRIGHTNESS);
void setup()
{
tft.begin();
tft.setBacklight(true);
tft.setDisplay(true);
tft.setBackgroundColor(COLOR_BLACK);
tft.setOrientation(0);
Serial.begin(9600);
}
void drawFractal(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint8_t x3,
uint8_t y3, uint8_t i)
{
if ( i != 0 )
{
drawFractal(x1, y1, (x1 + x2)/2 , (y1 + y2)/2 , (x1 + x3)/2 , (y1 + y3)/2,
i-1);
drawFractal(x2, y2, (x1 + x2)/2 , (y1 + y2)/2 , (x2 + x3)/2 , (y2 + y3)/2,
i-1);
drawFractal(x3, y3, (x3 + x2)/2 , (y3 + y2)/2 , (x1 + x3)/2 , (y1 + y3)/2,
i-1);
tft.drawLine(x1, y1, x2, y2, random(0xffff));
tft.drawLine(x1, y1, x3, y3, random(0xffff));
tft.drawLine(x3, y3, x2, y2, random(0xffff));
}
}
void loop()
{
tft.clear();
drawFractal(0, 0, 0, tft.maxY(), tft.maxX(), tft.maxY()/2, 8);
delay(5000);
}
You are defining the routine drawFractal() that accepts the coordinates of the endpoints
of the sides of triangles and the depth of the recursion. At every level, we are reducing the
depth. The line with the if condition has the termination criteria. You are calling the function
in the loop section. The image in Figure 5-19 shows the output.
● 128
Chapter 5 • Plotting Geometric Art on an External Display
You can even draw a square shape using this technique. Here is the relevant sketch:
prog12.ino
#include "SPI.h"
#include "TFT_22_ILI9225.h"
#define TFT_CS A4
#define TFT_RST A3
#define TFT_RS A2
#define TFT_SDI A1
#define TFT_CLK A0
#define TFT_BRIGHTNESS 200
TFT_22_ILI9225 tft = TFT_22_ILI9225(TFT_RST, TFT_RS, TFT_CS, TFT_SDI, TFT_CLK,
TFT_BRIGHTNESS);
void setup()
{
tft.begin();
tft.setBacklight(true);
tft.setDisplay(true);
tft.setBackgroundColor(COLOR_BLACK);
tft.setOrientation(0);
Serial.begin(9600);
}
void drawFractal(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint8_t i)
{
● 129
Kickstart to Arduino Nano
if ( i != 0 )
{
drawFractal(x1, y1, (x1 + x2)/2-1, (y1 + y2)/2-1, i-1);
drawFractal(x2, y2, (x1 + x2)/2, (y1 + y2)/2, i-1);
drawFractal(x1, y2, (x1 + x2)/2-1, (y1 + y2)/2, i-1);
drawFractal(x2, y1, (x1 + x2)/2, (y1 + y2)/2-1, i-1);
if (i == 1)
{
uint8_t color = random(200, 256);
switch(random(0, 7))
{
case 0:
tft.drawRectangle(x1, y1, (x1 + x2)/2-1, (y1 + y2)/2-1, tft.setColor(0,
0, color));
tft.drawRectangle(x2, y2, (x1 + x2)/2, (y1 + y2)/2, tft.setColor(0, 0,
color-30));
tft.drawRectangle(x1, y2, (x1 + x2)/2-1, (y1 + y2)/2, tft.setColor(0, 0,
color-60));
tft.drawRectangle(x2, y1, (x1 + x2)/2, (y1 + y2)/2-1, tft.setColor(0, 0,
color-90));
break;
case 1:
tft.drawRectangle(x1, y1, (x1 + x2)/2-1, (y1 + y2)/2-1, tft.setColor(0,
color, 0));
tft.drawRectangle(x2, y2, (x1 + x2)/2, (y1 + y2)/2, tft.setColor(0,
color-30, 0));
tft.drawRectangle(x1, y2, (x1 + x2)/2-1, (y1 + y2)/2, tft.setColor(0,
color-60, 0));
tft.drawRectangle(x2, y1, (x1 + x2)/2, (y1 + y2)/2-1, tft.setColor(0,
color-90, 0));
break;
case 2:
tft.drawRectangle(x1, y1, (x1 + x2)/2-1, (y1 + y2)/2-1, tft.
setColor(color, 0, 0));
tft.drawRectangle(x2, y2, (x1 + x2)/2, (y1 + y2)/2, tft.setColor(color-30,
0, 0));
tft.drawRectangle(x1, y2, (x1 + x2)/2-1, (y1 + y2)/2, tft.
setColor(color-60, 0, 0));
tft.drawRectangle(x2, y1, (x1 + x2)/2, (y1 + y2)/2-1, tft.
setColor(color-90, 0, 0));
break;
case 3:
tft.drawRectangle(x1, y1, (x1 + x2)/2-1, (y1 + y2)/2-1, tft.
setColor(color, color, 0));
tft.drawRectangle(x2, y2, (x1 + x2)/2, (y1 + y2)/2, tft.setColor(color-30,
color-30, 0));
● 130
Chapter 5 • Plotting Geometric Art on an External Display
● 131
Kickstart to Arduino Nano
The geometric shapes created using recursion sometimes fall under the category of frac-
tal. Both examples you programmed are fractals. You can even apply geometric transfor-
mations on shapes. Let's see how to create the rotation effect on a triangle. I have referred
the examples posted at:
https://create.arduino.cc/projecthub/Arnov_Sharma_makes/getting-started-
with-ili9255-tft-lcd-378331
Let's study that code block by block. First, we initialize the display:
#include "SPI.h"
#include "TFT_22_ILI9225.h"
#define TFT_CS A4
#define TFT_RST A3
#define TFT_RS A2
#define TFT_SDI A1
#define TFT_CLK A0
#define TFT_BRIGHTNESS 200
TFT_22_ILI9225 tft = TFT_22_ILI9225(TFT_RST, TFT_RS, TFT_CS, TFT_SDI, TFT_CLK,
TFT_BRIGHTNESS);
● 132
Chapter 5 • Plotting Geometric Art on an External Display
struct Point
{
uint8_t x;
uint8_t y;
};
These are the vertices and the centroid of the triangle. Let's define a routine to rotate a
point P with respect to another point C with a given angle as follows:
Carry on by writing a custom routine to rotate all the three points of a triangle:
void rotateTriangle( Point &a, Point &b, Point &c, Point r, int16_t deg )
{
float angle = (float)deg * 1000 / 57296;
a = rotatePoint( r, angle, a);
b = rotatePoint( r, angle, b);
c = rotatePoint( r, angle, c);
}
● 133
Kickstart to Arduino Nano
void setup()
{
tft.begin();
tft.setBacklight(true);
tft.setDisplay(true);
tft.setBackgroundColor(COLOR_BLACK);
tft.setOrientation(0);
Serial.begin(9600);
}
Finally, we are computing the number of steps in the rotation and running the loop to rotate
the triangle:
void loop()
{
tft.clear();
int16_t steps = (int16_t)(360 / ROTATE_ANGLE);
for (int8_t i = 0; i < steps; i++)
{
tft.drawTriangle(c1.x, c1.y, c2.x, c2.y, c3.x, c3.y, COLOR_RED);
rotateTriangle(c1, c2, c3, cc, ROTATE_ANGLE);
delay(50);
}
delay(3000);
}
● 134
Chapter 5 • Plotting Geometric Art on an External Display
This is the output after the triangle completes a full cycle of rotation. Be creative and create
a zigzag pattern as follows:
prog13.ino
#include "SPI.h"
#include "TFT_22_ILI9225.h"
#define TFT_CS A4
#define TFT_RST A3
#define TFT_RS A2
#define TFT_SDI A1
#define TFT_CLK A0
#define TFT_BRIGHTNESS 200
TFT_22_ILI9225 tft = TFT_22_ILI9225(TFT_RST, TFT_RS, TFT_CS, TFT_SDI, TFT_CLK,
TFT_BRIGHTNESS);
void setup()
{
tft.begin();
tft.setBacklight(true);
tft.setDisplay(true);
tft.setBackgroundColor(COLOR_BLACK);
tft.setOrientation(0);
Serial.begin(9600);
}
● 135
Kickstart to Arduino Nano
void loop()
{
tft.clear();
for ( uint8_t i = 0; i < 176; i = i+11 )
{
for ( uint8_t j = 0; j < 220; j = j+11 )
{
uint8_t x1 = i, y1 = j;
uint8_t x2 = i+10, y2 = j;
uint8_t x3 = i, y3 = j+10;
uint8_t x4 = i+10, y4 = j+10;
if ( j%2 )
tft.drawLine(x1, y1, x4, y4, random(0xffff));
else
tft.drawLine(x2, y2, x3, y3, random(0xffff));
delay(5);
}
}
delay(5000);
}
● 136
Chapter 5 • Plotting Geometric Art on an External Display
We can change the axis of the pattern by changing the condition to if ( i%2 ). You can
find the program as prog14_1.ino in the code bundle for this chapter. The output is as in
Figure 5-23.
Moreover, you can change the condition to if(random(2)). You can find the code in
prog14_2.ino. The output will look like Figure 5-24.
● 137
Kickstart to Arduino Nano
Consider creating a more intricate maze structure with the following sketch:
prog15.ino
#include "SPI.h"
#include "TFT_22_ILI9225.h"
#define TFT_CS A4
#define TFT_RST A3
#define TFT_RS A2
#define TFT_SDI A1
#define TFT_CLK A0
#define TFT_BRIGHTNESS 200
TFT_22_ILI9225 tft = TFT_22_ILI9225(TFT_RST, TFT_RS, TFT_CS, TFT_SDI, TFT_CLK,
TFT_BRIGHTNESS);
void setup()
{
tft.begin();
tft.setBacklight(true);
tft.setDisplay(true);
tft.setBackgroundColor(COLOR_BLACK);
tft.setOrientation(0);
Serial.begin(9600);
}
void loop()
{
● 138
Chapter 5 • Plotting Geometric Art on an External Display
tft.clear();
for ( uint8_t i = 0; i < 176; i = i+11 )
{
for ( uint8_t j = 0; j < 220; j = j+11 )
{
uint8_t x1 = i, y1 = j;
uint8_t x2 = i+10, y2 = j;
uint8_t x3 = i, y3 = j+10;
uint8_t x4 = i+10, y4 = j+10;
if(random(2))
tft.drawLine(x1, y1, x4, y4, random(0xffff));
else
tft.drawLine(x2, y2, x3, y3, random(0xffff));
if(random(2))
tft.drawLine(x1, y1, x4, y4, random(0xffff));
else
tft.drawLine(x2, y2, x3, y3, random(0xffff));
delay(5);
}
}
delay(5000);
}
● 139
Kickstart to Arduino Nano
prog16.ino
#include "SPI.h"
#include "TFT_22_ILI9225.h"
#define TFT_CS A4
#define TFT_RST A3
#define TFT_RS A2
#define TFT_SDI A1
#define TFT_CLK A0
#define TFT_BRIGHTNESS 200
TFT_22_ILI9225 tft = TFT_22_ILI9225(TFT_RST, TFT_RS, TFT_CS, TFT_SDI, TFT_CLK,
TFT_BRIGHTNESS);
void setup()
{
tft.begin();
tft.setBacklight(true);
tft.setDisplay(true);
tft.setBackgroundColor(COLOR_BLACK);
tft.setOrientation(0);
Serial.begin(9600);
}
void loop()
{
tft.clear();
for ( uint8_t i = 0; i < 176; i = i+11 )
{
for ( uint8_t j = 0; j < 220; j = j+11 )
{
uint8_t x1 = i, y1 = j;
uint8_t x2 = i+10, y2 = j;
uint8_t x3 = i, y3 = j+10;
uint8_t x4 = i+10, y4 = j+10;
switch(random(6))
{
case 0:
tft.drawLine(x1, y1, x4, y4, random(0xffff));
break;
case 1:
tft.drawLine(x2, y2, x3, y3, random(0xffff));
break;
case 2:
tft.drawLine(x1, y1, x2, y2, random(0xffff));
break;
case 3:
tft.drawLine(x3, y3, x4, y4, random(0xffff));
● 140
Chapter 5 • Plotting Geometric Art on an External Display
break;
case 4:
tft.drawLine(x1, y1, x3, y3, random(0xffff));
break;
case 5:
tft.drawLine(x2, y2, x4, y4, random(0xffff));
break;
}
delay(5);
}
}
delay(5000);
}
Let's create random more patterns with random squares, circles, and lines, as follows:
prog17.ino
#include "SPI.h"
#include "TFT_22_ILI9225.h"
#define TFT_CS A4
#define TFT_RST A3
#define TFT_RS A2
● 141
Kickstart to Arduino Nano
#define TFT_SDI A1
#define TFT_CLK A0
#define TFT_BRIGHTNESS 200
TFT_22_ILI9225 tft = TFT_22_ILI9225(TFT_RST, TFT_RS, TFT_CS, TFT_SDI, TFT_CLK,
TFT_BRIGHTNESS);
void setup()
{
tft.begin();
tft.setBacklight(true);
tft.setDisplay(true);
tft.setBackgroundColor(COLOR_BLACK);
tft.setOrientation(0);
Serial.begin(9600);
}
void loop()
{
tft.clear();
for ( uint8_t i = 0; i < 176; i = i+11 )
{
for ( uint8_t j = 0; j < 220; j = j+11 )
{
uint8_t x1 = i, y1 = j;
uint8_t x2 = i+10, y2 = j;
uint8_t x3 = i, y3 = j+10;
uint8_t x4 = i+10, y4 = j+10;
switch(random(7))
{
case 0:
tft.drawLine(x1, y1, x4, y4, random(0xffff));
break;
case 1:
tft.drawLine(x2, y2, x3, y3, random(0xffff));
break;
case 2:
tft.drawRectangle(x1, y1, x4, y4, random(0xffff));
break;
case 3:
tft.drawRectangle(x1, y1, (x1+x4)/2, (y1+y4)/2, random(0xffff));
tft.drawRectangle(x4, y4, (x1+x4)/2+1, (y1+y4)/2+1, random(0xffff));
break;
case 4:
tft.drawCircle((x1+x4)/2, (y1+y4)/2, 5, random(0xffff));
break;
case 5:
tft.drawRectangle(x1, y1, x4, y4, random(0xffff));
tft.drawRectangle(x1+3, y1+3, x4-3, y4-3, random(0xffff));
● 142
Chapter 5 • Plotting Geometric Art on an External Display
break;
case 6:
word color = random(0xffff);
tft.drawCircle((x1+x4)/2, (y1+y4)/2, 5, color);
tft.drawCircle((x1+x4)/2, (y1+y4)/2, 4, color);
tft.drawCircle((x1+x4)/2, (y1+y4)/2, 3, color);
break;
}
delay(5);
}
}
delay(5000);
}
This closes off our discussion on creating patterns with the ILI9225 library. At this point,
you can start writing a program for a simple game of Snake using this display and a few
buttons.
Summary
In this chapter, you learned how to work with ILI9225 display and create animations. In the
next chapter, you will learn how to work with various sensors and output devices including
a temperature sensor, a piezo buzzer, and a joystick.
● 143
Kickstart to Arduino Nano
In the previous chapter, you learned how to work with various displays with Arduino Nano
family boards. You are now comfy using various types of displays with Arduino.
In this short chapter, you will learn how to work with a few sensors and buzzer. These are
the topics you will learn in this chapter:
After absorbing this chapter, you will be comfortable with interfacing your Arduino Nano
with peripheral devices like a buzzer, a temperature sensor, and a joystick.
● 144
Chapter 6 • Working with a Buzzer and a Sensor
The buzzer's positive pin (red wire) is connected to the digital I/O pin on the Nano, and the
negative pin (black wire) is connected to GND. You will use this circuit for the next couple
of sketches. For this, we will use a built-in routine tone(). It generates a square wave of a
specified frequency with 50% duty cycle. You can generate only one tone at a time on a pin
and board. In other words, if you are using a specific pin to emit a tone, when you call this
function again with some other pin, it will not work. If you are already emitting a tone on a
pin and you call this routine again with the changed frequency, it will change the frequency
of the tone. The routine has three arguments. The first and the second ones are mandatory,
and they are defined as the output pin and the frequency. The third argument is optional:
it is the duration in milliseconds for which the tone is played on the buzzer. If the third
argument is not mentioned, the buzzer keeps emitting the specified tone unless another
routine noTone() is called. The following sketch shows the usage of the routine tone().
prog00.ino
const int piezzo_pin = 2;
void setup()
{
Serial.begin(9600);
pinMode(piezzo_pin, OUTPUT);
}
void loop()
{
for (long i = 0; i <= 65535; i=i+500)
{
tone(piezzo_pin, i, 2000);
Serial.println(i);
}
}
On the Arduino Nano family of boards, you can generate a square wave of frequency rang-
ing from 31 Hz up to 65535 Hz. Since the data type int cannot handle this range, you have
to use long type for storing the frequencies. We can write the similar code using the routine
noTone() as follows:
prog01.ino
const int piezzo_pin = 2;
void setup()
{
Serial.begin(9600);
pinMode(piezzo_pin, OUTPUT);
}
void loop()
{
for (long i = 31; i <= 20000; i=i+500)
● 145
Kickstart to Arduino Nano
{
tone(piezzo_pin, i);
Serial.println(i);
delay(2000);
noTone(piezzo_pin);
delay(500);
}
}
Upload and run both sketches. You can read more about the tone() in the Arduino Refer-
ence docs at: https://www.arduino.cc/reference/en/language/functions/advanced-io/tone/
You can also use this for more complex projects. Attach an analog input device like a trim-
pot to pin A0, as shown in Figure 6-2.
I am a great fan of Star Wars. Using this circuit, you can emit the Darth Vader theme. The
speed of the theme play can be adjusted with the trimpot knob. I borrowed the code from
an online GitHub project (https://gist.github.com/nicksort) and made appropriate changes
to the code and circuit. This is the code:
● 146
Chapter 6 • Working with a Buzzer and a Sensor
prog02.ino
const int c = 261;
const int d = 294;
const int e = 329;
const int f = 349;
const int g = 391;
const int gS = 415;
const int a = 440;
const int aS = 455;
const int b = 466;
const int cH = 523;
const int cSH = 554;
const int dH = 587;
const int dSH = 622;
const int eH = 659;
const int fH = 698;
const int fSH = 740;
const int gH = 784;
const int gSH = 830;
const int aH = 880;
void firstSection()
{
beep(a, 500);
beep(a, 500);
beep(a, 500);
beep(f, 350);
beep(cH, 150);
beep(a, 500);
beep(f, 350);
beep(cH, 150);
beep(a, 650);
● 147
Kickstart to Arduino Nano
delay(500);
beep(eH, 500);
beep(eH, 500);
beep(eH, 500);
beep(fH, 350);
beep(cH, 150);
beep(gS, 500);
beep(f, 350);
beep(cH, 150);
beep(a, 650);
delay(500);
}
void secondSection()
{
beep(aH, 500);
beep(a, 300);
beep(a, 150);
beep(aH, 500);
beep(gSH, 325);
beep(gH, 175);
beep(fSH, 125);
beep(fH, 125);
beep(fSH, 250);
delay(325);
beep(aS, 250);
beep(dSH, 500);
beep(dH, 325);
beep(cSH, 175);
beep(cH, 125);
beep(b, 125);
beep(cH, 250);
delay(350);
}
void setup()
{
Serial.begin(9600);
pinMode(buzzerPin, OUTPUT);
}
● 148
Chapter 6 • Working with a Buzzer and a Sensor
void loop()
{
firstSection();
secondSection();
beep(f, 250);
beep(gS, 500);
beep(f, 350);
beep(a, 125);
beep(cH, 500);
beep(a, 375);
beep(cH, 125);
beep(eH, 650);
delay(500);
secondSection();
beep(f, 250);
beep(gS, 500);
beep(f, 375);
beep(cH, 125);
beep(a, 500);
beep(f, 375);
beep(cH, 125);
beep(a, 650);
delay(650);
}
Since I have already explained the functions used in this code earlier, I will discuss only the
logic. First, you are defining the frequencies of the tone used for creating the music. Sec-
ond, you are defining a custom routine beep() that emits a tone of a particular frequency
for a specified time. The delay between the individual tones is detected by the position of
the trimpot. Since a few tone sequences are repetitive, there is a need for the routines
firstSection() and secondSection(). In the loop() section, you are calling them, along
with other tones, to create the Darth Vader theme music. Upload the sketch and enjoy the
music.
● 149
Kickstart to Arduino Nano
Each manufacturer will have its own naming scheme for the pins. However, the most com-
mon joysticks have 5 pins. Connect the X position pin to A1, the Y position pin to A0, and
connect the pin for the switch to digital I/O pin 2. In addition, you have to connect the VCC
and GND terminals to the +5 V and GND pins of the board, respectively. Now, it is time to
write the code. The code is pretty simple and I have already covered all functions used.
prog03.ino
int hor = A1;
int ver = A0;
int button = 2;
int x = 0;
int y = 0;
int button_state = 0;
const int range = 64;
void setup() {
Serial.begin(9600);
pinMode(hor, INPUT);
pinMode(ver, INPUT);
pinMode(button, INPUT_PULLUP);
}
void loop() {
x = analogRead(hor);
y = analogRead(ver);
button_state = digitalRead(button);
● 150
Chapter 6 • Working with a Buzzer and a Sensor
Serial.print("X: ");
Serial.print(map(x, 0, 1023, -range, range-1));
Serial.print(" | Y: ");
Serial.print(map(y, 0, 1023, -range, range-1));
Serial.print(" | Button: ");
Serial.println(button_state);
delay(100);
}
We are mapping the X and Y positions to a custom range (–64 to 63) and displaying the
status of all the inputs using a serial monitor. Figure 6-4 shows the joystick in action.
This is how you can work with a joystick. In the previous chapter, I suggested you create a
snake game with Nokia 5110 display. You can add this joystick to control the snake.
● 151
Kickstart to Arduino Nano
This sensor requires OneWire protocol and a special library. Open the library manager and
search for the term "DS18B20". It will show multiple libraries in the result. Install the Dal-
lasTemperature library. While installing, it will prompt you for installing another library,
OneWire. Install that library too. Once done, upload the following sketch:
prog04.ino
#include <OneWire.h>
#include <DallasTemperature.h>
const int sensor_pin = 2;
OneWire oneWire(sensor_pin);
DallasTemperature sensors(&oneWire);
void setup()
{
Serial.begin(9600);
sensors.begin();
}
void loop()
{
sensors.requestTemperatures();
● 152
Chapter 6 • Working with a Buzzer and a Sensor
The code uses all the library functions of OneWire and DallasTemperature library. The out-
put is as shown in Figure 6-6.
Summary
In this chapter, you learned how to work with diverse input and output devices such as a
buzzer, a joystick, and a temperature sensor.
In the next chapter, you will learn how to create IoT projects.
● 153
Kickstart to Arduino Nano
In the last chapter, you studied how to connect the temperature sensor, piezo buzzer, and
joystick to Arduino Nano. In this chapter, you will learn to use another member of the Ar-
duino Nano family, Arduino Nano 33 IoT. This is the list of topics you will learn about and
demonstrate in this chapter:
After completing this chapter, you will be more than comfortable with the Arduino Nano 33
IoT board.
Let's discuss the hardware specifications of the Nano 33 IoT. The Nano 33 IoT comes in
two versions: with and without pinheaders. Due to the shortage of semiconductors and
electronic components, I found it difficult to procure them in my region while authoring
this book (May 2022). I hope you can procure it without problems once the semiconductor
shortage is resolved. I am using the version of this board with pinheaders. However, in case
you are only able to procure the one without headers, soldering the headers is an easy job.
The Arduino Nano 33 IoT comes with a Microchip SAMD21 Cortex®-M0+ 32bit low
power ARM MCU as the main chip and its datasheet is at:
https://content.arduino.cc/assets/mkr-microchip_samd21_family_full_datasheet-
ds40001882d.pdf.
The Wi-Fi and Bluetooth connectivity are provided by u-blox NINA-W102 module, whose
datasheet is at:
● 154
Chapter 7 • Working with the Arduino Nano 33 IoT
https://content.arduino.cc/assets/Arduino_NINA-W10_
DataSheet_%28UBX-17065507%29.pdf.
The Nano 33 IoT also has a Microchip ATECC608A chip for secure communication. You
can check the datasheet at:
https://content.arduino.cc/assets/microchip_atecc608a_cryptoauthentication_
device_summary_datasheet-DS40001977B.pdf.
Furthermore, there is also an Inertial Measurement Unit chip type IMU LSM6DS3 and you
can check its datasheet at:
https://content.arduino.cc/assets/st_imu_lsm6ds3_datasheet.pdf.
SRAM 32 KB
EEPROM none
UART 1
SPI 1
I2C 1
LEDs, on-board 13
Length 45 mm
Width 18 mm
https://content.arduino.cc/assets/Arduino%20Nano%2033%20IOT.fzpz.
● 155
Kickstart to Arduino Nano
● 156
Chapter 7 • Working with the Arduino Nano 33 IoT
Getting Started
By default, the Arduino IDE does not support the Arduino Nano 33 IoT board, so you have
to install the support for this board. Open the Boards Manager from the Tools in the
menu and type in the search bar the string: samd. It will return the search results depicted
in Figure 7-4.
● 157
Kickstart to Arduino Nano
Install the option that reads Arduino SAMD Boards (32-bits ARM Cortex-M0+). It will
take some time as it is a big package. Once the installation is done, you can choose the
board by navigating as shown in Figure 7-5.
● 158
Chapter 7 • Working with the Arduino Nano 33 IoT
Connect the board to the computer and then choose the port as pictured in Figure 7-6.
Now try to upload a simple program to blink the built-in LED and to check if everything is
working fine. In principle, you can achieve all the functionality of the Arduino Nano and the
Arduino Nano Every with the Nano 33 IoT.
Before proceeding any further, I recommend updating the firmware for Wi-Fi with the built-
in tool. Open the firmware updater tool as shown in Figure 7-8.
● 159
Kickstart to Arduino Nano
For Arduino IDE 1.8, this pops up a window like in Figure 7-9.
Select the port and the firmware version and then click on the button Update Firmware.
In IDE 2.0 RC5, you will find the utility window like in Figure 7-10.
● 160
Chapter 7 • Working with the Arduino Nano 33 IoT
Click on the button Check Updates. The window will expand as shown in Figure 7-11.
Figure 7-11: Expanded WiFiNINA Firmware Updater running in Arduino IDE 2.0 RC5.
Select the firmware version and click the button Install. This will update the firmware.
Note: For many sketches, I am referring to the examples provided on the library's home-
page at https://github.com/arduino-libraries/WiFiNINA/ with modifications.
After all this installation stuff, now let's write a simple program to check all the available
connections. Let's import the libraries first:
#include <SPI.h>
#include <WiFiNINA.h>
Lets' check if the Wi-Fi module is working properly in the setup() section as follows:
void setup()
{
Serial.begin(9600);
if (WiFi.status() == WL_NO_MODULE)
{
● 161
Kickstart to Arduino Nano
In the loop() section, let's scan for the available Wi-Fi networks, like so:
void loop()
{
Serial.println("\nScanning for available Networks....");
int num = WiFi.scanNetworks();
If no network is found, it returns –1, else it returns the number of networks. Let's handle
both possibilities:
if (num == -1)
{
Serial.println("Couldn't find a WiFi network");
while (true);
}
Serial.print("Number of available networks: ");
Serial.println(num);
Finally, let's print the details of the available networks,
for (int i = 0; i < num; i++)
{
Serial.print(i);
Serial.print(") WiFi Network Name: ");
Serial.print(WiFi.SSID(i));
Serial.print("\nSignal Strength: ");
Serial.print(WiFi.RSSI(i));
Serial.print(" dBm");
Serial.print("\nMethod of Encryption: ");
switch (WiFi.encryptionType(i))
{
case ENC_TYPE_WEP:
Serial.println("WEP");
break;
case ENC_TYPE_TKIP:
Serial.println("WPA");
break;
case ENC_TYPE_CCMP:
Serial.println("WPA2");
break;
case ENC_TYPE_NONE:
Serial.println("None");
break;
● 162
Chapter 7 • Working with the Arduino Nano 33 IoT
case ENC_TYPE_AUTO:
Serial.println("Auto");
break;
case ENC_TYPE_UNKNOWN:
default:
Serial.println("Unknown");
break;
}
}
delay(10000);
}
prog00.ino
#include <SPI.h>
#include <WiFiNINA.h>
void setup()
{
Serial.begin(9600);
if (WiFi.status() == WL_NO_MODULE)
{
Serial.println("Communication with WiFi module failed!");
while (true);
}
}
void loop()
{
Serial.println("\nScanning for available Networks....");
int num = WiFi.scanNetworks();
if (num == -1)
{
Serial.println("Couldn't find a WiFi network");
while (true);
}
Serial.print("Number of available networks: ");
Serial.println(num);
for (int i = 0; i < num; i++)
{
Serial.print(i);
Serial.print(") WiFi Network Name: ");
Serial.print(WiFi.SSID(i));
Serial.print("\nSignal Strength: ");
Serial.print(WiFi.RSSI(i));
Serial.print(" dBm");
Serial.print("\nMethod of Encryption: ");
● 163
Kickstart to Arduino Nano
switch (WiFi.encryptionType(i))
{
case ENC_TYPE_WEP:
Serial.println("WEP");
break;
case ENC_TYPE_TKIP:
Serial.println("WPA");
break;
case ENC_TYPE_CCMP:
Serial.println("WPA2");
break;
case ENC_TYPE_NONE:
Serial.println("None");
break;
case ENC_TYPE_AUTO:
Serial.println("Auto");
break;
case ENC_TYPE_UNKNOWN:
default:
Serial.println("Unknown");
break;
}
}
delay(10000);
}
Let's write another program to create a simple web server on the Nano 33 IoT step-by-step.
First, import the libraries:
● 164
Chapter 7 • Working with the Arduino Nano 33 IoT
#include <SPI.h>
#include <WiFiNINA.h>
Change the value of these variables with the credentials of your own Wi-Fi network. Let's
define variables for status, server, and client.
In the setup() section, initialize the serial and built-in LED pin to the output mode,
void setup()
{
Serial.begin(9600);
pinMode(LED_BUILTIN, OUTPUT);
if (WiFi.status() == WL_NO_MODULE)
{
Serial.println("Communication with WiFi module failed!");
while (true);
}
Now, initialize the server and print the details of the connection:
server.begin();
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
IPAddress ip = WiFi.localIP();
● 165
Kickstart to Arduino Nano
Proceed by writing the loop() section. Here you need to check if a client is connected to
the server. The following code creates a simple webpage with two clickable links, which,
when clicked, send either H or L to the server. Based on these values, you are turning the
on-board LED off or on.
void loop()
{
client = server.available();
delay(1000);
if (client)
{
Serial.println("A new client has connected to the server...");
String currentLine = "";
while (client.connected())
{
if (client.available())
{
char c = client.read();
Serial.write(c);
if (c == '\n')
{
if (currentLine.length() == 0)
{
client.println("HTTP/1.1 200 OK");
client.println("Content-type:text/html");
client.println();
client.print("Click <a href=\"/H\">here</a> turn the Built-in LED on
pin 13 on<br>");
client.print("Click <a href=\"/L\">here</a> turn the Built-in LED on
pin 13 off<br>");
client.println();
break;
}
else
{
● 166
Chapter 7 • Working with the Arduino Nano 33 IoT
currentLine = "";
}
}
else if (c != '\r')
{
currentLine += c;
}
if (currentLine.endsWith("GET /H")) {
digitalWrite(LED_BUILTIN, HIGH);
}
if (currentLine.endsWith("GET /L")) {
digitalWrite(LED_BUILTIN, LOW);
}
}
}
client.stop();
Serial.println("The client disconnected...");
}
}
Now, put all these sections together and save that file as prog01.ino. You will find this file
in the code bundle released for this publication. Upload the sketch and the Console shows
the following output:
SSID: TP-Link_710E
IP Address: 192.168.0.105
As you can see, the Wi-Fi network automatically and dynamically assigns an IP address
to the Nano using the DHCP protocol. You can check for this IP address in the active client
table of your Wi-Fi router or using the nmap command (https://nmap.org/). Figure 7-12
shows the output in the Zenmap utility.
● 167
Kickstart to Arduino Nano
Open a browser window and use the given IP address. You should see the webpage data
as in Figure 7-13.
Once you connect using a browser, the Serial Console of Arduino shows the following details
of the connections:
Connection: keep-alive
DNT: 1
Accept: image/avif,image/webp,image/apng,image/
svg+xml,image/*,*/*;q=0.8
Referer: http://192.168.0.105/
Accept-Language: en-US,en;q=0.9
● 168
Chapter 7 • Working with the Arduino Nano 33 IoT
If you click on the hyperlinks, you can send appropriate data to the web server and change
the state of the on-board LED. It takes a few seconds for the changes to take effect. In
case you are closely observing, you can spot the changed URL in the browser's address bar.
You can connect a relay to Digital I/O pin 13 in order to control a fluorescent tube or a fan.
Be careful while working with AC powerline voltages — an electric shock is fatal in most
cases.
You can extend this application with a common-cathode RGB LED. Have a look at the circuit
depicted in Figure 7-14.
You can enable its operation over the local network with the following program:
prog02.ino
#include <SPI.h>
#include <WiFiNINA.h>
char ssid[] = "TP-Link_710E";
char pass[] = "internet1";
int status = WL_IDLE_STATUS;
WiFiServer server(80);
WiFiClient client;
● 169
Kickstart to Arduino Nano
● 170
Chapter 7 • Working with the Arduino Nano 33 IoT
if (c == '\n') {
if (currentLine.length() == 0)
{
client.println("HTTP/1.1 200 OK");
client.println("Content-type:text/html");
client.println();
client.print("Click <a href=\"/HR\">here</a> turn the Red LED on pin
2 on<br>");
client.print("Click <a href=\"/LR\">here</a> turn the Red LED on pin
2 off<br>");
client.print("Click <a href=\"/HG\">here</a> turn the Green LED on
pin 3 on<br>");
client.print("Click <a href=\"/LG\">here</a> turn the Green LED on
pin 3 off<br>");
client.print("Click <a href=\"/HB\">here</a> turn the Blue LED on pin
4 on<br>");
client.print("Click <a href=\"/LB\">here</a> turn the Blue LED on pin
4 off<br>");
client.println();
break;
}
else
{
currentLine = "";
}
} else if (c != '\r') {
currentLine += c;
}
if (currentLine.endsWith("GET /HR"))
{
digitalWrite(RED, HIGH);
}
if (currentLine.endsWith("GET /LR"))
{
digitalWrite(RED, LOW);
}
if (currentLine.endsWith("GET /HG"))
{
digitalWrite(GREEN, HIGH);
}
if (currentLine.endsWith("GET /LG"))
{
digitalWrite(GREEN, LOW);
}
if (currentLine.endsWith("GET /HB"))
{
● 171
Kickstart to Arduino Nano
digitalWrite(BLUE, HIGH);
}
if (currentLine.endsWith("GET /LB"))
{
digitalWrite(BLUE, LOW);
}
}
}
client.stop();
Serial.println("The client disconnected...");
}
}
Run the program and control the RGB LED using a browser. Now, you can extend this by
connecting a relay board with multiple relays and control your home appliances over the
web.
prog03.ino
#include <SPI.h>
#include <WiFiNINA.h>
char ssid[] = "TP-Link_710E";
char pass[] = "internet1";
int status = WL_IDLE_STATUS;
WiFiServer server(23);
boolean alreadyConnected = false;
WiFiClient client;
void setup()
{
Serial.begin(9600);
if (WiFi.status() == WL_NO_MODULE)
{
Serial.println("Communication with WiFi module failed!");
while (true);
}
while (status != WL_CONNECTED)
{
Serial.print("Attempting to connect to Network named: ");
Serial.println(ssid);
status = WiFi.begin(ssid, pass);
delay(10000);
}
server.begin();
● 172
Chapter 7 • Working with the Arduino Nano 33 IoT
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
long rssi = WiFi.RSSI();
Serial.print("Signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
Serial.print("Open this address in a browser http://");
Serial.println(ip);
}
void loop()
{
client = server.available();
if (client)
{
if (!alreadyConnected)
{
client.flush();
Serial.println("We have a new client");
client.println("Hello, client!");
alreadyConnected = true;
}
if (client.available() > 0)
{
char thisChar = client.read();
server.write(thisChar);
Serial.write(thisChar);
}
}
}
Upload this sketch. This program listens for incoming connections and broadcasts mes-
sages to all clients. Once the sketch is uploaded, you can see the IP address of the Nano
in your Serial Console. From the command prompt of Linux and macOS, run the following
command:
telnet 192.168.0.105 23
Trying 192.168.0.105...
Connected to 192.168.0.105.
● 173
Kickstart to Arduino Nano
test
Hello, client!
test
test1
abc
Ctrl + ]
You have to enable Telnet in Windows. Here's a good guide for that:
https://www.lifewire.com/what-is-telnet-2626026
prog04.ino
#include <SPI.h>
#include <WiFiNINA.h>
char ssid[] = "TP-Link_710E";
char pass[] = "internet1";
int status = WL_IDLE_STATUS;
const String hostName = "www.google.com";
int pingResult;
void setup()
{
Serial.begin(9600);
if (WiFi.status() == WL_NO_MODULE)
{
Serial.println("Communication with WiFi module failed!");
while (true);
}
while (status != WL_CONNECTED)
{
Serial.print("Attempting to connect to Network named: ");
Serial.println(ssid);
status = WiFi.begin(ssid, pass);
● 174
Chapter 7 • Working with the Arduino Nano 33 IoT
delay(10000);
}
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
long rssi = WiFi.RSSI();
Serial.print("Signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
Serial.println(ip);
}
void loop()
{
Serial.print("Pinging ");
Serial.print(hostName);
Serial.print(": ");
pingResult = WiFi.ping(hostName);
if (pingResult >= 0)
{
Serial.print("SUCCESS! RTT = ");
Serial.print(pingResult);
Serial.println(" ms");
}
else
{
Serial.print("FAILED! Error code: ");
Serial.println(pingResult);
}
delay(5000);
}
IP Address: 192.168.0.105
192.168.0.105
● 175
Kickstart to Arduino Nano
prog05.ino
#include <SPI.h>
#include <WiFiNINA.h>
char ssid[] = "TP-Link_710E";
char pass[] = "internet1";
int status = WL_IDLE_STATUS;
char server[] = "www.google.com";
WiFiClient client;
void setup()
{
Serial.begin(9600);
if (WiFi.status() == WL_NO_MODULE)
{
Serial.println("Communication with WiFi module failed!");
while (true);
}
while (status != WL_CONNECTED)
{
Serial.print("Attempting to connect to Network named: ");
Serial.println(ssid);
status = WiFi.begin(ssid, pass);
delay(10000);
}
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
long rssi = WiFi.RSSI();
Serial.print("Signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
Serial.println(ip);
Serial.println("\nStarting connection to server...");
if (client.connect(server, 80))
{
Serial.println("connected to server");
client.println("GET /search?q=elektor HTTP/1.1");
client.println("Host: www.google.com");
client.println("Connection: close");
client.println();
● 176
Chapter 7 • Working with the Arduino Nano 33 IoT
}
}
void loop()
{
while (client.available())
{
char c = client.read();
Serial.write(c);
}
if (!client.connected())
{
Serial.println();
Serial.println("Disconnecting from server.");
client.stop();
while (true);
}
}
Using the Serial Console, all the results returned by the remote server will get printed.
#include "SPI.h"
#include <WiFiNINA.h>
#include <WiFiUdp.h>
#include <RTCZero.h>
● 177
Kickstart to Arduino Nano
Serial.begin(9600);
if (WiFi.status() == WL_NO_MODULE)
{
Serial.println("Communication with WiFi module failed!");
while (true);
}
while (status != WL_CONNECTED)
{
Serial.print("Attempting to connect to Network named: ");
Serial.println(ssid);
status = WiFi.begin(ssid, pass);
delay(10000);
}
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
long rssi = WiFi.RSSI();
Serial.print("Signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
Serial.println(ip);
Let's initialize the real-time clock,
rtc.begin();
Let's fetch the epoch (i.e., the time since 1 January 1970) from an NTP server:
do
{
epoch = WiFi.getTime();
attempts = attempts + 1;
}
while ((epoch == 0) && (attempts < maxAttempts));
If the NTP Server cannot be connected, you get an error. Else, set the current time:
if (attempts == maxAttempts)
{
Serial.print("NTP is unreachable!");
while (1);
}
else
{
Serial.print("Epoch received: ");
Serial.println(epoch);
● 178
Chapter 7 • Working with the Arduino Nano 33 IoT
rtc.setEpoch(epoch);
Serial.println();
}
}
Finally, in the loop() section, you are displaying the current date and time every second.
void loop()
{
Serial.print(rtc.getDay());
Serial.print("/");
Serial.print(rtc.getMonth());
Serial.print("/");
Serial.print(rtc.getYear());
Serial.print(" ");
Serial.print(rtc.getHours());
Serial.print(":");
Serial.print(rtc.getMinutes());
Serial.print(":");
Serial.print(rtc.getSeconds());
Serial.println();
delay(1000);
}
Upload the sketch and observe the output on the Serial Console.
● 179
Kickstart to Arduino Nano
Figure 7-15: DS18B20 temperature sensor connected to the Arduino Nano 33 IoT.
You can mix the code of the RTC with the code of the temperature sensor to get a temper-
ature reading with a timestamp, as follows:
prog07.ino
#include "SPI.h"
#include <WiFiNINA.h>
#include <WiFiUdp.h>
#include <RTCZero.h>
#include <OneWire.h>
#include <DallasTemperature.h>
const int sensor_pin = 2;
OneWire oneWire(sensor_pin);
DallasTemperature sensors(&oneWire);
char ssid[] = "TP-Link_710E";
char pass[] = "internet1";
int status = WL_IDLE_STATUS;
char msg[100];
RTCZero rtc;
unsigned long epoch;
● 180
Chapter 7 • Working with the Arduino Nano 33 IoT
uint8_t attempts = 0;
const uint8_t maxAttempts = 7;
void setup()
{
Serial.begin(9600);
sensors.begin();
if (WiFi.status() == WL_NO_MODULE)
{
Serial.println("Communication with WiFi module failed!");
while (true);
}
while (status != WL_CONNECTED)
{
Serial.print("Attempting to connect to Network named: ");
Serial.println(ssid);
status = WiFi.begin(ssid, pass);
delay(10000);
}
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
long rssi = WiFi.RSSI();
Serial.print("Signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
Serial.println(ip);
rtc.begin();
do
{
epoch = WiFi.getTime();
attempts = attempts + 1;
}
while ((epoch == 0) && (attempts < maxAttempts));
if (attempts == maxAttempts)
{
Serial.print("NTP is unreachable!");
while (1);
}
else
{
Serial.print("Epoch received: ");
Serial.println(epoch);
rtc.setEpoch(epoch);
Serial.println();
● 181
Kickstart to Arduino Nano
}
}
void loop()
{
sensors.requestTemperatures();
float temp = sensors.getTempCByIndex(0);
sprintf(msg, "%d/%d/%d %d:%d:%d ",
rtc.getDay(), rtc.getMonth(),
rtc.getYear(), rtc.getHours(),
rtc.getMinutes(), rtc.getSeconds());
Serial.print(msg);
Serial.print(temp);
Serial.println();
delay(1000);
}
This will print the temperature with the current timestamp in the Serial Console at seconds
intervals. You can even display the results on a webpage. Check the following sketch:
prog08.ino
#include "SPI.h"
#include <WiFiNINA.h>
#include <WiFiUdp.h>
#include <RTCZero.h>
#include <OneWire.h>
#include <DallasTemperature.h>
const int sensor_pin = 2;
OneWire oneWire(sensor_pin);
DallasTemperature sensors(&oneWire);
char ssid[] = "TP-Link_710E";
char pass[] = "internet1";
int status = WL_IDLE_STATUS;
char msg[100];
RTCZero rtc;
unsigned long epoch;
uint8_t attempts = 0;
const uint8_t maxAttempts = 7;
WiFiServer server(80);
WiFiClient client;
void setup()
{
Serial.begin(9600);
sensors.begin();
if (WiFi.status() == WL_NO_MODULE)
{
● 182
Chapter 7 • Working with the Arduino Nano 33 IoT
● 183
Kickstart to Arduino Nano
rtc.getDay(), rtc.getMonth(),
rtc.getYear(), rtc.getHours(),
rtc.getMinutes(), rtc.getSeconds(),
String(temp, 3).c_str());
client = server.available();
delay(1000);
if (client)
{
Serial.println("A new client has connected to the server...");
String currentLine = "";
while (client.connected())
{
if (client.available())
{
char c = client.read();
Serial.write(c);
if (c == '\n') {
if (currentLine.length() == 0)
{
client.println("HTTP/1.1 200 OK");
client.println("Content-type:text/html");
client.println("Connection: close");
client.println();
client.println("<!DOCTYPE html>");
client.println("<html>");
client.println("<head>");
client.println("<title>Arduino Webserver</title>");
client.println("<meta http-equiv=\"refresh\" content=\"1\">");
client.println("</head>");
client.println("<body>");
client.println(msg);
client.println("</body>");
client.println("</html>");
client.println();
break;
}
else
{
currentLine = "";
}
} else if (c != '\r') {
currentLine += c;
}
}
}
// close the connection:
● 184
Chapter 7 • Working with the Arduino Nano 33 IoT
client.stop();
Serial.println("The client disconnected...");
}
delay(1000);
}
Just copy the IP address from the Serial Console and paste it into the browser to see the
temperature.
Once you click this option, you will be taken to a new page. There, click on the green button
New Channel — check Figure 7-17.
Once you click the button, a form will open as pictured in Figure 7-18.
● 185
Kickstart to Arduino Nano
Assign a suitable name to your channel. Since you just need to show the graph for temper-
ature, check only one field and assign a suitable name to it. Complete the description and
metadata fields. Finally, click on the Save Channel button at the bottom of the page. Once
done, your channels list will appear like the one shown in Figure 7-19.
● 186
Chapter 7 • Working with the Arduino Nano 33 IoT
Now, you have to change the settings. Go to the Sharing section and share the channel
with everyone, as shown in Figure 7-20.
Afterward, navigate to the tab API Keys, and note down the Write API Key for your
channel.
● 187
Kickstart to Arduino Nano
Now, install the ThingSpeak library from the Library Manager. Upload the following
sketch to the Nano 33 IoT:
prog09.ino
#include "SPI.h"
#include <WiFiNINA.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include "ThingSpeak.h"
unsigned long mychannelnumber = 1111111;
const char * myAPIkey = "A1A1A1A1A1A1A1A1";
const int sensor_pin = 2;
OneWire oneWire(sensor_pin);
DallasTemperature sensors(&oneWire);
char ssid[] = "TP-Link_710E";
char pass[] = "internet1";
int status = WL_IDLE_STATUS;
WiFiClient client;
void setup()
{
● 188
Chapter 7 • Working with the Arduino Nano 33 IoT
Serial.begin(9600);
ThingSpeak.begin(client);
sensors.begin();
if (WiFi.status() == WL_NO_MODULE)
{
Serial.println("Communication with WiFi module failed!");
while (true);
}
while (status != WL_CONNECTED)
{
Serial.print("Attempting to connect to Network named: ");
Serial.println(ssid);
status = WiFi.begin(ssid, pass);
delay(10000);
}
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
long rssi = WiFi.RSSI();
Serial.print("Signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
Serial.println(ip);
}
void loop()
{
sensors.requestTemperatures();
float temp = sensors.getTempCByIndex(0);
ThingSpeak.writeField(mychannelnumber, 1, temp, myAPIkey);
delay(16000);
}
You are already familiar with most of the code. Let's understand the new lines of code. The
new file included is as follows,
#include "ThingSpeak.h"
You need to get the channel number and API Write Key from your ThingSpeak account. I
have entered dummy data to mask the details of my own account,
● 189
Kickstart to Arduino Nano
The argument 1 refers to the field numbers, and temp is the variable for numerical value
to be visualized. Upload the sketch and go to your channel using a browser. If the number
of your channel is 11111111, then the URL of your channel is https://thingspeak.com/
channels/11111111. Everything working properly so far, you can see the graph of all tem-
perature data.
#include <Arduino_LSM6DS3.h>
In the setup() section, you are initializing the IMU and printing the sample rates for the
accelerometer and the gyroscope in Hz in the Serial Console.
void setup()
{
Serial.begin(9600);
if (!IMU.begin())
{
Serial.println("Failed to initialize IMU!");
while (1);
}
Serial.print("Accelerometer sample rate = ");
Serial.print(IMU.accelerationSampleRate());
Serial.println(" Hz");
Serial.println();
Serial.print("Gyroscope sample rate = ");
Serial.print(IMU.gyroscopeSampleRate());
Serial.println(" Hz");
Serial.println();
}
In the loop() section, we are printing the acceleration and orientation values on all three
axes, one after another, every second.
● 190
Chapter 7 • Working with the Arduino Nano 33 IoT
void loop()
{
float x, y, z;
if (IMU.accelerationAvailable())
{
Serial.println("Acceleration X, Y, Z");
IMU.readAcceleration(x, y, z);
Serial.print(x);
Serial.print(", ");
Serial.print(y);
Serial.print(", ");
Serial.print(z);
Serial.print(", \n");
}
if (IMU.gyroscopeAvailable())
{
Serial.println("Gyroscope X, Y, Z");
IMU.readGyroscope(x, y, z);
Serial.print(x);
Serial.print(", ");
Serial.print(y);
Serial.print(", ");
Serial.print(z);
Serial.print(", \n");
}
delay(1000);
}
You can exploit this interesting feature of the Nano 33 IoT board creatively for interactive
projects.
Summary
In this chapter, you learned to work with the Wi-Fi module aiming to create simple IoT
applications. You have also learned to work with the IMU included on the board. You can
extend this knowledge to build more creative and interactive projects in the future.
Conclusion
The journey that you started to explore the Arduino Ecosystem is far from over. There are
plenty more Arduino boards, sensors, I/O devices, and projects to explore. You can start
exploring the documentation section at https://www.arduino.cc/ and the project hub at
https://create.arduino.cc/projecthub. Happy exploring!
● 191
Kickstart to Arduino Nano
Index
C J
CH340 39 Joystick 149
CIPO 19, 75 Jumper cables 50
common-anode 65
common-cathode 65 L
COPI 19, 75 LED 43
Counterfeits 14 LED blink 42
LEDs 51
D Light Emitting Diodes 51
Derivatives 14 local variables 45
Device Manager 36 loop() 42
Digital I/O 82 LSM6DS3 190
● 192
Contents
N T
Nano Family 13 Telnet 154, 172
Newline 74 temperature sensor 144
nmap 167 TFT LCD 103
ThingSpeak 185
O TOFF 83
OneWire 152 TON 83
Tools 73
P trimpot 76
parallel 71 Two Wire Interface 75
Ping 174
port 37 U
portable power supply 50 UART 19
potentiometer 75 ULN2003A 82, 92
power supplies 46 Unipolar Stepper Motors 82
Pulse Width Modulation 82 Update Firmware 160
pushbutton 63 Upload 39
Pushbuttons 53
PWM 19, 82 V
Visualizing 185
R
Raspberry Pi OS 30 W
Real-Time Clock 177 web client 154
Remote Server 174 Web Client 176
Resistors 52 WiFiNINA 154, 159
RGB 65 Wire 75
RGB LEDs 42
RTCZero 177
S
samd 157
SAMD 158
Send 74
Sensor 144
serial 71
Serial Monitor 73
● 193