Microcontroller Programming With Arduino and Python
Microcontroller Programming With Arduino and Python
FOSSEE Project
Indian Institute of Technology Bombay
June 2021
The soft-copy/electronic-version of this book is released under Creative Commons
Attribution-NonCommercial-NoDerivatives (CC BY-NC-ND) license. Those who
want to use this book for commercial purposes may contact Prof. Kannan Moudgalya.
Contents
Preface vii
List of Figures ix
List of Tables xi
1 Introduction 1
2 Hardware Environment 3
2.1 Microcontroller . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.1.1 Organization of a Microcontroller . . . . . . . . . . . . . . . . 3
2.1.2 Microcontroller Peripherals . . . . . . . . . . . . . . . . . . . 5
2.2 Open Source Hardware (OSHW) . . . . . . . . . . . . . . . . . . . . 7
2.3 Arduino . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.3.1 Brief History . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.3.2 Arduino Uno Board . . . . . . . . . . . . . . . . . . . . . . . 9
2.3.3 Popular Arduino Projects . . . . . . . . . . . . . . . . . . . . 9
2.4 Shield . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.5 Experimental Test Bed . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.6 Doing the Experiments with a Breadboard . . . . . . . . . . . . . . . 13
5 Interfacing a Pushbutton 49
5.1 Preliminaries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
5.2 Connecting a pushbutton with Arduino Uno using a breadboard . . . 49
5.3 Reading the pushbutton status from the Arduino IDE . . . . . . . . 52
5.3.1 Reading the pushbutton status . . . . . . . . . . . . . . . . . 52
5.3.2 Arduino Code . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
5.4 Reading the pushbutton status from Python . . . . . . . . . . . . . . 54
5.4.1 Reading the pushbutton status . . . . . . . . . . . . . . . . . 54
5.4.2 Python Code . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
7 Interfacing a Potentiometer 69
7.1 Preliminaries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
7.2 Connecting a potentiometer with Arduino Uno using a breadboard . 70
7.3 Reading the potentiometer from the Arduino IDE . . . . . . . . . . . 71
7.3.1 Reading the potentiometer . . . . . . . . . . . . . . . . . . . . 71
7.3.2 Arduino Code . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
7.4 Reading the potentiometer from Python . . . . . . . . . . . . . . . . 73
7.4.1 Reading the potentiometer . . . . . . . . . . . . . . . . . . . . 73
7.4.2 Python Code . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
8 Interfacing a Thermistor 77
8.1 Preliminaries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
8.2 Connecting a thermistor with Arduino Uno using a breadboard . . . 79
8.3 Interfacing the thermistor from the Arduino IDE . . . . . . . . . . . 80
8.3.1 Interfacing the thermistor . . . . . . . . . . . . . . . . . . . . 80
8.3.2 Arduino Code . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
8.4 Interfacing the thermistor from Python . . . . . . . . . . . . . . . . . 84
8.4.1 Interfacing the thermistor . . . . . . . . . . . . . . . . . . . . 84
8.4.2 Python Code . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
9 Interfacing a Servomotor 89
9.1 Preliminaries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
9.2 Connecting a servomotor with Arduino Uno using a breadboard . . . 90
9.3 Controlling the servomotor through the Arduino IDE . . . . . . . . . 91
9.3.1 Controlling the servomotor . . . . . . . . . . . . . . . . . . . 91
9.3.2 Arduino Code . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
9.4 Controlling the servomotor through Python . . . . . . . . . . . . . . 96
9.4.1 Controlling the servomotor . . . . . . . . . . . . . . . . . . . 96
9.4.2 Python Code . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
References 133
Preface
Microcontrollers are extensively used in the industry, automobiles and home ap-
pliances, to list a few. Arduino is a popular open source microcontroller available
today. Arduino comes with its own software, Arduino IDE, short for Integrated De-
velopment Environment. Using Arduino IDE, one can program Arduino for different
purposes. Some times, one may want to program Arduino using high level program-
ming languages. We have explained Arduino programming with the following high
level languages through separate books.
1 Scilab and Xcos: Microcontroller programming with Arduino, Scilab,
and Xcos
2 Python: Microcontroller programming with Arduino and
Python
3 OpenModelica: Microcontroller programming with Arduino and Open-
Modelica
4 Julia: Microcontroller programming with Arduino and Julia
Each of these four books concentrates on one topic. Such a compact book may
be of interest to those who are interested in only one programming language. We
are bringing out a fifth book that combines all of these languages for the benefit of
readers who may be interested in two or more languages.
All code explained in the book are made freely downloadable and their URL are
provided at appropriate places. The user will need the Arduino Uno board and a
Shield to carry out the experiments explained in this book. It is easy to procure
Arduino UNO, which is available through many vendors. The location of the Gerber
file and details of the components required to assemble the Shield are provided in
the book. Alternatively, one can buy the Shield directly from vendors, details of
whom are also provided in the book.
This work is supported by the FOSSEE (Free/Libre and Open Source Software
for Education) project (https://fossee.in) at IIT Bombay. This project is
funded by the National Mission on Education through ICT, Ministry of Education,
Govt. of India. FOSSEE promotes software, such as Scilab, Python, eSim, Open-
vii
viii Contents
Kannan Moudgalya
IIT Bombay
2 October 2022
List of Figures
ix
x List of Figures
xi
xii List of Tables
List of Arduino Code
5.1 Read the status of the pushbutton and display it on the Serial Monitor 53
5.2 Turning the LED on or off depending on the pushbutton . . . . . . 53
11.1 First 10 lines of the firmware for Modbus Energy Meter experiment 127
xiii
xiv List of Arduino Code
List of Python Code
5.1 Read the status of the pushbutton and display it on the Command
Prompt or the Terminal . . . . . . . . . . . . . . . . . . . . . . . . 55
5.2 Turning the LED on or off depending on the pushbutton . . . . . . 56
xv
xvi List of Python Code
xvii
xviii List of Acronyms
Introduction
there has not been much literature that teaches how to use them to program the
versatile Arduino Uno. To address this gap, we have written this series of books.
We have provided code written in all of these open-source software. The reader is
recommended to go through the book that covers a particular software.
The only way we can become versatile in hardware is through hands-on training.
To this end, we make use of the easily available low-cost Arduino Uno board to
introduce the reader to computer interfacing. We also make available the details
of a shield that makes the Arduino Uno use extremely easy and intuitive. We tell
the user how to install the firmware to make the Arduino Uno board communicate
with the computer. We explain how to control the peripherals on the Arduino Uno
board with user-developed software.
The Scilab-Arduino toolbox is already available for Windows [2]. We have
suitably modified it so that it works on Linux also. We give the required programs
to experiment with the sensors and actuators that come with the shield, a DC motor,
and a servomotor. These programs are available for all of the following environments:
Arduino IDE, Scilab, Xcos, Python, Julia, and OpenModelica. In addition to these
toolboxes, we provide the firmware for each software and a program to check its
working.
This book teaches how to access the following sensors and actuators: LED, push-
button, LDR, Potentiometer, Thermistor, Servo motor, and DC motor. A set of two
to five programs are given for each. These are given for all the software mentioned
above. The reader has to see the book devoted to the appropriate software. We also
explain where to find these programs and how to execute them for each experiment.
This book is written for self-learners and hobbyists. It has been field-tested by
250 people who attended a hands-on workshop conducted at IIT Bombay in July
2015. It has also been field-tested by 25 people who participated in a TEQIP course
held in Amravati in November 2015.
All the code described in this book is available at https://floss-arduino.
fossee.in/downloads. On downloading and unzipping it, it will open a folder
Origin in the current directory. All the files mentioned in this book are with
reference to this folder2 .
2
This naming convention will be used throughout this book. Users are expected to download
this file and use it while reading this book.
Chapter 2
Hardware Environment
In this book, we shall use an Arduino Uno board and associated circuitry to perform
several experiments on data acquisition and control. This chapter will briefly take
you through the hardware environment needed to perform these experiments. We will
start with the introduction to a microcontroller followed by a brief on Open Source
Hardware. Then, we shall go through the history and hardware specifications of the
Arduino Uno board and the schema and uses of the shield provided in the kit.
2.1 Microcontroller
A microcontroller is a “smart” and complex programmable digital circuit that con-
tains a processor, memory and input/output peripherals on a single integrated cir-
cuit. Effectively, it can function as a small computer that can perform a variety of
applications. A few of these day-to-day applications include:
• Automotive: Braking, driver assist, fault diagnosis, power steering
• Household appliances: CD/DVD players, washing machines, microwave ovens,
energy meters
• Telecommunication: Mobile phones, switches, routers, ethernet controllers
• Medical: Implantable devices, MRI, ultrasound, dental imaging
• General: Automation, safety systems, electronic measurement instruments
Clock: A complex digital circuit, such as the one that is present in a microcontroller,
requires a clock pulse to synchronize different parts of it. The clock is generated
through internal or external crystal oscillator. A typical microcontroller can
execute one instruction per clock cycle (time between two consecutive clock
pulses).
Interrupts: An interrupt to the CPU suspends the running program and executes
a code block corresponding to it. After serving/attending interrupts, the CPU
resumes the previous program and continues. An interrupt could be originated
by the software or the hardware. A hardware interrupt normally has a higher
priority.
Analog to Digital Converter (ADC): Most of the signals around us are continuous.
Digital circuits cannot process them. An ADC converts them into digital
signals. The resolution of the ADC determines the efficiency of conversion. For
example, a 10-bit resolution of the ADC relates to 1024 values per sample. This
is shown pictorially in Fig. 2.2. Higher resolution relates to better translation
of an analog signal.
Digital to Analog Converter (DAC): Digital output of the CPU is converted to ana-
log signals using the pulse width modulation (PWM) technique. The output
of a DAC is used to drive analog devices and actuators.
2. Beagle board, Panda board, OLinuXino are ARM based development boards.
8 2. Hardware Environment
7. “OpenMoko” project set the foundation for open-source mobile phones. “Neo
1973” was the first smartphone released in 2007 with Linux based operating
system, it had 128MB RAM and 64MB ROM.
2.3 Arduino
Arduino is an open-source microcontroller board and a software development en-
vironment. Arduino language is a C like programming language which is easy to
learn and understand. Arduino has two components, open source hardware and open
source software. We will cover the basics of the Arduino hardware in this section.
Parameter Value
Microcontroller ATmega328P
Operating Voltage 5V
Input Voltage (recommended) 7-12V
Input Voltage (limits) 6-20V
Digital I/O Pins 14 (of which 6 provide PWM output)
Analog Input Pins 6
DC Current per I/O Pin 20 mA
DC Current for 3.3V Pin 50 mA
Flash Memory 32 KB (ATmega328), 0.5 KB used by bootloader
SRAM 2 KB (ATmega328)
EEPROM 1 KB (ATmega328)
Clock Speed 16 MHz
Length 68.6 mm
Width 53.4 mm
Weight 25 g
Arduino phone: An Arduino connected with a graphic LCD and a GSM shield.
This low-tech phone, shown in Fig. 2.7 can be built in a few hours [8].
2.4. Shield 11
Candy sorting machine: As the name suggests, this machine can sort candy
based on its color to separate jars [9].
2.4 Shield
The shield that we use in this book is a modified version of the Diyode Codeshield
board [11], which makes it easy to perform experiments on the Arduino Uno board.
12 2. Hardware Environment
The shield is a printed circuit board (PCB) with a large number of sensors, already
wired and hence, ready to use. It obviates the need for a breadboard as an intermedi-
ate tool for electronics circuit prototyping, which is quite cumbersome for beginners.
The shield provides the user a faster way of circuit prototyping without worrying
much about troubleshooting.
The numbering on the shield is identical to that on the Arduino Uno board.
The shield fits snugly on to the Arduino Uno board, obviating the need to do the
wiring in many experiments. One can even say that shields have made the hardware
experiments involving Arduino boards as easy as writing software.
All the experiments in this book have been verified with the use of a modified ver-
sion of Diyode Codeshield, as mentioned above. We make available all the required
information to make a shield, thus making this an OSHW, see Sec. 2.2.
We now explain where the required files to make our shield are given. The
gerber file to make the shield is given in Origin/tools/shield/gerber-V1.2,
see Footnote 2 on page 2. The image of the PCB file is given in Fig. 2.9. The PCB
project files are available in a folder at Origin/tools/shield/kicad-import,
see Footnote 2 on page 2. The pictorial representation of the schematic for the shield
is given in Fig. 2.10. A photograph of the PCB after fabrication is given in Fig. 2.11.
The values of the various components used in the shield are given in Table 2.2.
Table 2.3 provides information about various sensors, components on shield and its
corresponding pin on Arduino Uno board [11]. A picture of the completed shield is
in Fig. 2.12. The information on purchasing this shield is given in Appendix A.
2. Shield containing
2.6. Doing the Experiments with a Breadboard 13
(a) LED
(b) LDR
(c) Push Button
(d) Thermistor
4. Servomotor
The Arduino Uno board is easily available in the market. The shield is designed
by us. Details of most of these units are provided in the previous sections. Infor-
mation on all of these is available in the file, mentioned in Footnote 2, and in the
Appendix.
To carry out all the experiments using a breadboard, as explained in the subsequent
chapters, one needs the components listed in Table 2.4.
2.6. Doing the Experiments with a Breadboard 15
Components Quantity
Arduino Uno with USB cable 1
Half breadboard 1
Male to Male jumper wires 10
100Ω Resistor 5
10KΩ Resistor 2
RGB LED 1
Pushbutton 1
Photoresistor (LDR) 1
Potentiometer 1
Thermistor 1
Buzzer 1
Servomotor 1
L293D motor driver board 1
DC motor 1
18 2. Hardware Environment
Chapter 3
In this chapter, we shall briefly walk through the software environment that needs to
be set up before we could start with the Arduino Uno board-based experiments. We
shall start with the Arduino Uno compatible Integrated Development Environment
(IDE), termed as Arduino IDE, that would be used to load the FLOSS firmware on
to the microcontroller. The FLOSS firmware to be loaded could be developed to
serve different purposes as per the requirement. For example,
• To run Arduino Uno stand-alone, without waiting for any commands from
other software or hardware, for the specified time or until power off
• To decode the commands sent by other software, such as Scilab, Python, Julia,
OpenModelica, etc., through a serial port, and execute the given instructions
Next, we shall discuss other open-source software tools and a related toolbox that
can communicate with Arduino Uno over a serial port using RS232 protocol.
1. To begin, we need an Arduino Uno board with a USB cable (A plug to B plug)
as shown in Fig. 2.4.
20 3. Communication between Software and Arduino
2. Connect it to a computer and power it up. The moment you connect Arduino
Uno to the computer, an on-board power LED will turn ON.
4. Extract the downloaded ZIP file to Desktop. Do not alter any file or directory
structure.
5. Click on the Windows Start Menu, and open up the “Control Panel”.
6. While in the Control Panel, navigate to “System and Security”, click on “Sys-
tem” and then choose the “Device Manager”.
7. Look for “Other devices” in the “Device Manager” list, expand and locate “Un-
known device”. This may be similar to what is shown in Fig. 3.1. In case, you
don’t see “Unknown device,” look for “Ports (COM & LPT)” and expand it to
locate “USB Serial Device (COM2)”. This may be similar to what is shown in
Fig. 3.2.
8. Right-click on the “Unknown device” (or “USB Serial Device (COM2)” as shown
in the previous step) and select the “Update Driver Software” (or “Update
driver”) option as shown in Fig. 3.3.
10. Navigate to the newly extracted Arduino folder on the Desktop and select
“drivers” folder.
11. Windows will now finish the driver installation. The Arduino IDE is ready for
use.
To launch Arduino IDE, browse to extracted Arduino folder on the Desktop and
double click on “arduino.exe”.
3.1. Arduino IDE 21
3. First, update your system. Open the terminal emulator, type, sudo apt-get
update and press Enter.
4. Find out your operating system support for 64-bit instructions. Open the
terminal emulator and type, uname -m
5. If it returns “x86_64”, then your computer has 64-bit operating system. There
is no visible performance difference in 32 and 64-bit Arduino versions.
22 3. Communication between Software and Arduino
7. At the time of writing this book, we worked with version 1.8.13. Assuming
that you have downloaded the tar file in the Downloads directory, execute the
following commands on the terminal:
cd ~/Downloads
tar -xvf arduino-1.8.13-linux64.tar.xz
sudo mv arduino-1.8.13 /opt
8. In the same terminal session, install the required Java Runtime Environment
with a command like, sudo apt-get -y install openjdk-8-jre
9. Execute the following command on the terminal to list the serial port number.
ls /dev/ttyACM*
3.1. Arduino IDE 23
the text editor. Sketches are saved with the file extension “.ino”. The frequently used
icons shown in the toolbar, below the menu bar, are explained next. The names of
these icons can be viewed by hovering the mouse pointer over each of them.
2. Upload: Compiles your code and uploads it to the Arduino I/O board
4. Open: Presents a menu of all the sketches in your sketchbook - clicking one
will open it within the current window
6. Serial Monitor: Opens the serial port window - the location of this is shown in
the top right-hand corner of Fig. 3.5
Note that these appear from left to right in the editor window. Next, we shall go
through the additional useful options under the menu.
1. File
2. Sketch
3. Tools
(a) Auto Format: Indents code so that opening and closing curly braces line
up
(b) Archive Sketch: Archives a copy of the current sketch in .zip format. The
archive is placed in the same directory as the sketch.
(c) Board: Selects the board that you’re using
(d) Port: This menu contains all the serial devices (real or virtual) on your
machine. It should automatically refresh every time you open the top-
level tools menu.
26 3. Communication between Software and Arduino
1. Open the Arduino IDE by clicking the shortcut “arduino” from Desktop in
Ubuntu. In MS Windows browse to extracted Arduino folder on Desktop and
double click on “arduino.exe”.
2. In the Arduino IDE, to know the path of your sketch files, navigate to File,
then Preferences and then locate the “Sketchbook location” text box at the
top. You may change the path of your storage location. In this book, we will
keep it unchanged. The path will be different for Windows and Ubuntu.
3. To load a sample program, navigate and click on sketch “File”, then Examples,
then 01.Basics, and then Blink.
4. A new IDE instance will open with Blink LED code. You may close the
previous IDE window now.
5. Click “verify” to compile. The “status bar” below the text editor shall show
“Done compiling” on success.
6. Connect Arduino UNO board to PC. You may connect the board before writing
the sketch too.
7. Now, navigate to “Tools”, then Port, and select the available port. If the port
option is greyed out (or disabled) then reinsert the USB cable to the PC.
8. Now select the upload button to compile and send the firmware to the Arduino
Uno board.
3.2. Python 27
9. If the upload is successful, you will notice the onboard orange LED next to the
Arduino logo will start blinking.
3.2 Python
Python is a general-purpose, high-level, remarkably powerful dynamic programming
language that is used in a wide variety of application domains. Its high-level built-
in data structures, combined with dynamic typing and dynamic binding, make it
28 3. Communication between Software and Arduino
very attractive for Rapid Application Development, as well as for use as a scripting
or glue language to connect existing components together. Python’s simple, easy
to learn syntax emphasizes readability and therefore reduces the cost of program
maintenance. Python supports modules and packages, which encourages program
modularity and code reuse. The Python interpreter and the extensive standard
library are available in source or binary form without charge for all major platforms,
and can be freely distributed [12].
Once the installation is finished, Python 3.9 App can be launched from the Start
menu. In this book, we will use the Command Prompt to execute the Python scripts.
Please note that a Python script has .py as its extension. Carry out the steps given
below to execute a Python script from the Command Prompt:
1. Launch the Command Prompt. Press the Windows key+R together. A win-
dow, as shown in Fig. 3.7 appears. In the text box adjacent to Open, type
cmd, and press Enter. The Command Prompt, as shown in Fig. 3.8 appears.
By default, it points to the home directory.
2. Now, we will check whether Python 3.9 was installed successfully or not. In
the Command Prompt, type py --version and press Enter. If this step
displays Python 3.9.4 in the following line, the installation was successful.
3.2. Python 29
3. Using the cd command, navigate to the directory where your Python script is
located. Assuming that your Command Prompt points to the home directory,
and you want to navigate to the folder Origin on Desktop, execute the following
command: cd Desktop\Origin
It may be noted that a backslash (\) has been used between Desktop and
Origin.
4. To view the contents of this folder, type dir and press Enter.
5. Suppose you have a Python script named FILENAME.py in this folder. To ex-
ecute this script, type python FILENAME.py and press Enter. The required
output will be displayed in the Command Prompt itself. We don’t expect the
readers to run the command python FILENAME.py at this instant. This
command will be helpful while running the Python scripts in the upcoming
sections and chapters.
Apart from Python, we need to install Python Serial Port Extension, also known
as pyserial [13]. To do so, carry out the steps given below:
2. First, we need to make sure we have pip available. In the Command Prompt,
execute the following command: py -m pip --version
This step should display an output with the version of pip installed.
3. Now, install pyserial. In the Command Prompt, execute the following com-
mand: py -m pip install pyserial
4. We will verify whether the pyserial package was installed successfully or not. In
the Command Prompt, execute the following command: pip show pyserial
It should show the name, version, etc., of the package.
4. Now, we will check whether Python was installed successfully or not. In the
terminal, type python3 --version or type python3 -V and press Enter.
If this step displays Python 3.8.4 in the following line, the installation was
successful.
Once the installation is finished, Python 3 can be launched from the terminal.
In this book, we will use the Linux terminal to execute the Python scripts. Please
note that a Python script has .py as its extension. Carry out the steps given below
to execute a Python script from the terminal:
2. Using cd command, navigate to the directory where the Python script is lo-
cated.
Apart from Python, we need to install Python Serial Port Extension, also known
as pyserial [13]. To do so, carry out the steps given below:
2. First, we need to install pip. In the terminal, execute the following command:
sudo apt-get install python3-pip
4. We will verify whether the pyserial package was installed successfully or not.
In the terminal, execute the following command: pip3 show pyserial
It should show the name, version, etc., of the package.
Linux. The Python scripts (or codes) for various experiments mentioned through-
out this book can be found in Origin/user-code directory. The user-code
directory will have many sub-directories as per the experiments.
In this book, we have created a package named "Arduino" in Python 3. This
package is available at Origin/tools/python. This package makes use of the
functions available in pyserial [13] to establish serial communication with Arduino.
In this package, we have added functions required to run various experiments on
Arduino Uno. Using this basic set of functions, the user can define other functions
to operate upon the Arduino. Please note that the "Arduino" package and the
FLOSS firmware given in Arduino Code 3.1 are required to run the experiments.
Now, we will see how to import (or load) the "Arduino" package inside a Python
script to run various experiments provided in this book. In a Python script, add
from Arduino.Arduino import Arduino at the top of the script. When we
add from Arduino.Arduino import Arduino in a script, the function "from"
searches for "Arduino" only in that directory where our script is saved. That’s why all
the scripts in Python must be saved in a folder that contains the "Arduino" package.
In this book, "Arduino" package has been saved in the folder where the Python
scripts for each chapter are available. For the sake of convenience, we have added
from Arduino.Arduino import Arduino in all the Python scripts provided
in this book. To run a particular experiment, one can follow the steps as given in
Sec. 3.2.1 or Sec. 3.2.2.
3.2.4 Firmware
We have provided a Python code to check whether the firmware has been properly
installed. That code is listed below. Please ensure that you have uploaded the
FLOSS firmware given in Arduino Code 3.1 on the Arduino Uno board.
Python Code 3.1 A Python script to check whether the firmware is properly in-
stalled or not. Available at Origin/tools/python/test_firmware.py, see
Footnote 2 on page 2. Execute this script by following the steps given in Sec. 3.2.1
or Sec. 3.2.2. If the execution is successful, you should expect three "ok" messages.
1 import o s
2 import s y s
3 cwd = o s . getcwd ( )
4 ( s e t p a t h , Examples ) = o s . path . s p l i t ( cwd )
5 s y s . path . append ( s e t p a t h )
6
7 from Arduino . Arduino import Arduino
8 from time import s l e e p
9
10 c l a s s TEST_FIRMWARE:
3.2. Python 33
11 d e f __init__ ( s e l f , b a u d r a t e ) :
12 s e l f . baudrate = baudrate
13 s e l f . setup ()
14 s e l f . run ( )
15 s e l f . exit ()
16
17 def setup ( s e l f ) :
18 s e l f . obj_arduino = Arduino ( )
19 s e l f . p o r t = s e l f . obj_arduino . l o c a t e p o r t ( )
20 s e l f . obj_arduino . o p e n _ s e r i a l ( 1 , s e l f . port , s e l f . b a u d r a t e )
21
22 d e f run ( s e l f ) :
23 s e l f . obj_arduino . c h e c k f i r m w a r e ( )
24
25 def exit ( s e l f ) :
26 s e l f . obj_arduino . c l o s e _ s e r i a l ( )
27
28 d e f main ( ) :
29 o bj _l ed = TEST_FIRMWARE( 1 1 5 2 0 0 )
30
31 i f __name__== ’__main__ ’ :
32 main ( )
34 3. Communication between Software and Arduino
Chapter 4
In this chapter, we will learn how to control the LEDs on the shield and on the
Arduino Uno board. We will do this through the Arduino IDE and other open-
source software tools. These are beginner level experiments, and often referred to
as the hello world task of Arduino. Although simple, controlling LED is a very
important task in all kinds of electronic boards.
4.1 Preliminaries
A light emitting diode (LED) is a special type of semiconductor diode, which emits
light when voltage is applied across its terminals. A typical LED has 2 leads: Anode,
the positive terminal and Cathode, the negative terminal. When sufficient voltage
is applied, electrons combine with the holes, thereby releasing energy in the form of
photons. These photons emit light and this phenomenon is known as electrolumi-
nescence. The symbolic representation of an LED is shown in Fig. 4.1. Generally,
LEDs are capable of emitting different colours. Changing the composition of alloys
that are present in LED helps produce different colours. A popular LED is an RGB
LED that actually has three LEDs: red, green and blue.
An RGB LED is present on the shield provided in the kit. In this section, we
will see how to light each of the LEDs present in the RGB LED. As a matter of fact,
Figure 4.2: Internal connection diagram for the RGB LED on the shield
shown in Fig. 4.3. All the experiments in this chapter assume that the shield is
connected to the Arduino Uno board. It is also possible to do some of the experiments
without the shield, which is pointed out in the next section.
anode pins of red, green, and blue are connected to digital pins 11, 10, and 9 of
Arduino Uno, respectively. Common cathode is connected to the ground (GND)
terminal of Arduino Uno.
Before that, we need to define pin 9 as the output pin. This is achieved by the
command,
1 pinMode ( 9 , OUTPUT) ;
2. Next, we will modify the code slightly so that the blue light remains on for
two seconds and then turns off. Arduino Code 4.2 helps achieve this. In this,
we introduce a new command delay as below:
1 delay (2000) ;
This delay command halts the code for the time passed as in input argument.
In our case, it is 2,000 milliseconds, or 2 seconds. The next command,
1 d i g i t a l W r i t e ( 9 , LOW) ;
// d e l a y ( 2 0 0 0 ) ;
If you observe carefully, you will see that the LED turns blue momentarily and
then turns off.
3. We mentioned earlier that it was possible to light more than one LED simul-
taneously. We will now describe this with another experiment. In this, we will
turn on both blue and red LEDs. We will keep both of them on for 5 seconds
and then turn blue off, leaving only red on. After 3 seconds, we will turn red
also off. This code is given in Arduino Code 4.3. Remember that before writ-
ing either HIGH or LOW on to any pin, its mode has to be declared as OUTPUT,
as given in the code. All the commands in this code are self explanatory.
4. Finally, we will give a hint of how to use the programming capabilities of the
Arduino IDE. For this, we will use Arduino Code 4.4. It makes the LED blink
5 times. Recall from the previous section that a HIGH on pin 10 turns on the
green LED. This cycle is executed for a total of five times. In each iteration,
it will turn the green LED on for a second by giving the HIGH signal and then
turn it off for a second by giving the LOW signal. This cycle is carried out for
a total of 5 times, because of the for loop.
Note: All the above four experiments have been done with the shield affixed to
the Arduino Uno board. One may run these experiments without the shield as well.
But in this case, pin number 13 has to be used in all experiments, as pin 13 lights
up the LED that is on the Arduino Uno board. For example, in Arduino Code 4.1,
one has to replace both occurrences of number 9 with 13. In this case, one will get
the LED of Arduino Uno board light up, as shown in Fig. 4.5.
Note: It should also be pointed out that only one colour is available in Arduino
Uno board. As a result, it is not possible to conduct the experiments that produce
different colours if the shield is not used.
Exercise 4.1 Carry out the following exercise:
1. In Arduino Code 4.2, remove the delay, as discussed above, and check what
happens.
2. Light up all three colours simultaneously, by modifying Arduino Code 4.3.
Change the combination of colours to get different colours.
3. Incorporate some of the features of earlier experiments into Arduino Code 4.4
and come up with different ways of blinking with different colour combina-
tions.
40 4. Interfacing a Light Emitting Diode
Figure 4.5: LED experiments directly on Arduino Uno board, without the shield
Arduino Code 4.2 Turning on the blue LED and turning it off after two seconds.
Available at Origin/user-code/led/arduino/led-blue-delay/led-blu
e-delay.ino, see Footnote 2 on page 2.
1 void s e t u p ( ) {
2 pinMode ( 9 , OUTPUT) ;
4.3. Lighting the LED from the Arduino IDE 41
3 S e r i a l . begin (115200) ;
4 d i g i t a l W r i t e ( 9 , HIGH) ;
5 delay (2000) ;
6 d i g i t a l W r i t e ( 9 , LOW) ;
7 }
8 void l o o p ( ) {
9 }
Arduino Code 4.3 Turning on blue and red LEDs for 5 seconds and then turning
them off one by one. Available at Origin/user-code/led/arduino/led-bl
ue-red/led-blue-red.ino, see Footnote 2 on page 2.
1 void s e t u p ( ) {
2 pinMode ( 9 , OUTPUT) ;
3 pinMode ( 1 1 , OUTPUT) ;
4 S e r i a l . begin (115200) ;
5 d i g i t a l W r i t e ( 9 , HIGH) ;
6 d i g i t a l W r i t e ( 1 1 , HIGH) ;
7 delay (5000) ;
8 d i g i t a l W r i t e ( 9 , LOW) ;
9 delay (3000) ;
10 d i g i t a l W r i t e ( 1 1 , LOW) ;
11 }
12 void l o o p ( ) {
13 }
1. In the first experiment, we will light up the blue LED on the shield. The
code for this is given in Python Code 4.1. It begins with importing necessary
modules, as given below:
1 import o s
2 import s y s
Here, os module provides functions for interacting with the operating system.
On the other hand, the sys module provides access to some variables used
or maintained by the interpreter and functions that interact strongly with
the interpreter. Next, the following lines of code are used to get the current
directory followed by splitting it and appending the path to PYTHONPATH
environment:
1 cwd = o s . getcwd ( )
2 ( s e t p a t h , Examples ) = o s . path . s p l i t ( cwd )
3 s y s . path . append ( s e t p a t h )
After importing the necessary modules, following line imports the Arduino
module from the Python-Arduino toolbox, as explained in Sec. 3.2.3:
1 from Arduino . Arduino import Arduino
Next, we will import sleep module, which is a function available in the pack-
age pyserial [13]. For the sake of simplicity, we have configured each experiment
as a class. In Python Code 4.1, we have defined the experiment as class
LED_ON. The following lines of code initilize the parameters and functions
available in this class.
1 c l a s s LED_ON:
2 d e f __init__ ( s e l f , b a u d r a t e ) :
3 s e l f . baudrate = baudrate
4 s e l f . setup ()
5 s e l f . run ( )
6 s e l f . exit ()
4.4. Lighting the LED from Python 43
The function setup creates an object of the Arduino class through which we
can call all the methods available in the base class. Along with this, it locates
the port to which Arduino Uno is connected and opens the port for serial
communication. Thus, we require port number and BAUD RATE for opening
the serial port.
The function run is used to define the functionality of the experiment. In
this experiment, we have to switch on the blue LED. For this, we define the
pin number (which is 9 in this case) and send the required signal to this pin.
Following lines are used to implement this functionality:
1 d e f run ( s e l f ) :
2 s e l f . blue = 9
3 s e l f . obj_arduino . cmd_digital_out ( 1 , s e l f . blue , 1 )
2. Python Code 4.2 does the same thing as what Arduino Code 4.2 does. It does
two more things than what Python Code 4.1 does: It makes the blue LED
light up for two seconds. This is achieved by the command
1 sleep (2)
The second thing this code does is to turn the blue LED off. This is achieved
by the command
1 s e l f . obj_arduino . cmd_digital_out ( 1 , s e l f . blue , 0 )
Python Code 4.2 Turning on the blue LED and turning it off after two sec-
onds. Available at Origin/user-code/led/python/led-blue-delay.p
y, see Footnote 2 on page 2.
1 import o s
2 import s y s
3 cwd = o s . getcwd ( )
4 ( s e t p a t h , Examples ) = o s . path . s p l i t ( cwd )
5 s y s . path . append ( s e t p a t h )
6
4.4. Lighting the LED from Python 45
Python Code 4.3 Turning on blue and red LEDs for 5 seconds and then turning
them off one by one. Available at Origin/user-code/led/python/led-blu
e-red.py, see Footnote 2 on page 2.
1 import o s
2 import s y s
3 cwd = o s . getcwd ( )
4 ( s e t p a t h , Examples ) = o s . path . s p l i t ( cwd )
5 s y s . path . append ( s e t p a t h )
6
7 from Arduino . Arduino import Arduino
8 from time import s l e e p
9
10 c l a s s LED_ON_OFF_MULTICOLOR:
11
12 d e f __init__ ( s e l f , b a u d r a t e ) :
13 s e l f . baudrate = baudrate
14 s e l f . setup ()
15 s e l f . run ( )
46 4. Interfacing a Light Emitting Diode
16 s e l f . exit ()
17
18 def setup ( s e l f ) :
19 s e l f . obj_arduino = Arduino ( )
20 s e l f . p o r t = s e l f . obj_arduino . l o c a t e p o r t ( )
21 s e l f . obj_arduino . o p e n _ s e r i a l ( 1 , s e l f . port , s e l f . b a u d r a t e )
22
23 d e f run ( s e l f ) :
24 s e l f . blue = 9
25 s e l f . g r e e n = 10
26 s e l f . r e d = 11
27 s e l f . obj_arduino . cmd_digital_out ( 1 , s e l f . blue , s e l f . b a u d r a t e )
28 s e l f . obj_arduino . cmd_digital_out ( 1 , s e l f . red , s e l f . b a u d r a t e )
29 sleep (5)
30 s e l f . obj_arduino . cmd_digital_out ( 1 , s e l f . blue , 0 )
31 sleep (3)
32 s e l f . obj_arduino . cmd_digital_out ( 1 , s e l f . red , 0 )
33
34 def exit ( s e l f ) :
35 s e l f . obj_arduino . c l o s e _ s e r i a l ( )
36
37 d e f main ( ) :
38 o bj _l ed = LED_ON_OFF_MULTICOLOR( 1 1 5 2 0 0 )
39
40 i f __name__==’__main__ ’ :
41 main ( )
20 s e l f . p o r t = s e l f . obj_arduino . l o c a t e p o r t ( )
21 s e l f . obj_arduino . o p e n _ s e r i a l ( 1 , s e l f . port , s e l f . b a u d r a t e )
22
23 d e f run ( s e l f ) :
24 s e l f . blue = 9
25 s e l f . g r e e n = 10
26 s e l f . r e d = 11
27 for i in range ( 5 ) :
28 s e l f . obj_arduino . cmd_digital_out ( 1 , s e l f . green , 1 )
29 sleep (1)
30 s e l f . obj_arduino . cmd_digital_out ( 1 , s e l f . green , 0 )
31 sleep (1)
32
33 def exit ( s e l f ) :
34 s e l f . obj_arduino . c l o s e _ s e r i a l ( )
35
36 d e f main ( ) :
37 o bj _l ed = LED_ON_OFF_LOOP( 1 1 5 2 0 0 )
38
39 i f __name__==’__main__ ’ :
40 main ( )
41
48 4. Interfacing a Light Emitting Diode
Chapter 5
Interfacing a Pushbutton
5.1 Preliminaries
A pushbutton mounted on the shield is connected to the digital pin 12 of the Arduino
Uno board. The connection diagram for the pushbutton is shown in Fig. 5.1. It has
2 pairs of terminals. Each pair is electrically connected. When the pushbutton is
pressed all the terminals short to complete the circuit, thereby allowing the flow of
current through the switch. As you might expect, there is a limit to the maximum
current that could flow through a pushbutton. This maximum current is also called
the rated current and is usually provided by the manufacturer in the datasheet.
Figure 5.1: Internal connection diagram for the pushbutton on the shield
Figure 5.2: A pushbutton to read its status with Arduino Uno using a breadboard
Figure 5.3: A pushbutton to control an LED with Arduino Uno using a breadboard
is connected to the rightmost leg of the RGB LED. Rest of the connections are same
as that in Fig. 5.2.
1. In the first experiment, we shall simply read the status of the pushbutton.
Recall that it is a normally open type of switch. So, in an unpressed state,
the logic read will be “0”, corresponding to 0V. And, when the user presses the
pushbutton, the reading would be “1”, corresponding to 5V. The code for this
experiment is given in Arduino Code 5.1. In the initialization part of the code,
we assign the sensor pin to be read, 12 in this case, to a variable for ease. Next,
we initialize the port for serial port communication at data rate of 115200 bits
per second and declare the digital pin 12 as an input pin using the command
pinMode. After initialization, we start reading the status of the pushbutton
using the following command:
1 s e n s o r V a l u e = d i g i t a l R e a d ( s e n s o r P i n ) ; / / r e a d push −b u t t o n
value
Note that the input argument to this command is the digital pin 12 corre-
sponding to the pin to which the pushbutton is connected. After acquiring the
values, we print them using,
1 S e r i a l . p r i n t l n ( sensorValue ) ; // p r i n t i t a t t h e S e r i a l
Monitor
We repeat this read and print process 50 times by putting the commands in a
for loop. While running this experiment, the readers must press and release
the pushbutton and observe the values being printed on the Serial Monitor
of Arduino IDE.
Arduino Code 5.2. This experiment can be taken as a step further to the
previous one. We declare the LED pin to be controlled as an output pin by,
1 pinMode ( s e n s o r P i n , INPUT) ;
Next, we read the pusbhutton value from digital pin 12. If the value is “1”, we
turn on the LED at pin 9 else we turn it off. The condition check is performed
using if else statements. We run these commands for 50 iterations. While
running this experiment, the readers must press and release the pushbutton.
Accordingly, they can observe whether the LED glows when the pushbutton is
pressed.
Arduino Code 5.2 Turning the LED on or off depending on the pushbutton. Avail-
able at Origin/user-code/push/arduino/led-push-button/led-push
-button.ino, see Footnote 2 on page 2.
1 const i n t s e n s o r P i n = 1 2 ;
2 const i n t l e d P i n = 9 ;
3 int sensorValue = 0 ;
4 int i ;
5 void s e t u p ( ) {
6 S e r i a l . begin (115200) ;
7 pinMode ( s e n s o r P i n , INPUT) ;
8 pinMode ( l e d P i n , OUTPUT) ;
9 f o r ( i = 0 ; i < 5 0 ; i ++) {
10 sensorValue = digitalRead ( sensorPin ) ;
11 S e r i a l . p r i n t l n ( sensorValue ) ; // p r i n t i t a t t h e S e r i a l Monitor
54 5. Interfacing a Pushbutton
12 i f ( s e n s o r V a l u e == 0 ) {
13 d i g i t a l W r i t e ( l e d P i n , LOW) ;
14 delay (200) ;
15 }
16 else {
17 d i g i t a l W r i t e ( l e d P i n , HIGH) ;
18 delay (200) ;
19 }
20 }
21 }
22 void l o o p ( ) {
23 }
1. In the first experiment, we will read the pushbutton status. The code for this
experiment is given in Python Code 5.1. As explained earlier in Sec. 4.4.1,
we begin with importing necessary modules followed by setting up the serial
port. Then, we read the input coming from digital pin 12 using the following
command:
1 v a l = s e l f . obj_arduino . cmd_digital_in ( 1 , s e l f . pushbutton )
Note that the one leg of the pushbutton on the shield is connected to digital
pin 12 of Arduino Uno as given in Fig. 5.1. The read value is displayed (or
printed) by the following lines:
1 for i in range (20) :
2 v a l = s e l f . obj_arduino . cmd_digital_in ( 1 , s e l f . pushbutton )
3 print ( val )
4 sleep (0.5)
where val contains the pushbutton value acquired by the previous command.
When the pushbutton is not pressed, val will be “0”. On the other hand,
when the pushbutton is pressed, val will be “1”. To encourage the user to
have a good hands-on, we run these commands in a for loop for 20 iterations.
5.4. Reading the pushbutton status from Python 55
The readers are encouraged to change the number of iterations as per their
requirements. While running this experiment, the readers must press and
release the pushbutton and observe the values being printed on the Command
Prompt (on Windows) or Terminal (on Linux), as the case maybe.
control the LED state based on the status of the pushbutton. While running
this experiment, the readers must press and release the pushbutton. Accord-
ingly, they can observe whether the LED glows when the pushbutton is pressed.
20 s e l f . p o r t = s e l f . obj_arduino . l o c a t e p o r t ( )
21 s e l f . obj_arduino . o p e n _ s e r i a l ( 1 , s e l f . port , s e l f . b a u d r a t e )
22
23 d e f run ( s e l f ) :
24 s e l f . pushbutton = 12
25 for i in range (20) :
26 v a l = s e l f . obj_arduino . cmd_digital_in ( 1 , s e l f . pushbutton )
27 print ( val )
28 sleep (0.5)
29
30 def exit ( s e l f ) :
31 s e l f . obj_arduino . c l o s e _ s e r i a l ( )
32
33 d e f main ( ) :
34 obj_pushbutton = PUSHBUTTON( 1 1 5 2 0 0 )
35
36 i f __name__==’__main__ ’ :
37 main ( )
Python Code 5.2 Turning the LED on or off depending on the pushbutton. Avail-
able at Origin/user-code/push/python/led-push-button.py, see Foot-
note 2 on page 2.
1 import o s
2 import s y s
3 cwd = o s . getcwd ( )
4 ( s e t p a t h , Examples ) = o s . path . s p l i t ( cwd )
5 s y s . path . append ( s e t p a t h )
6
7 from Arduino . Arduino import Arduino
8 from time import s l e e p
9
10 c l a s s PUSHBUTTON_LED:
11
12 d e f __init__ ( s e l f , b a u d r a t e ) :
13 s e l f . baudrate = baudrate
14 s e l f . setup ()
15 s e l f . run ( )
16 s e l f . exit ()
17
18 def setup ( s e l f ) :
19 s e l f . obj_arduino = Arduino ( )
20 s e l f . p o r t = s e l f . obj_arduino . l o c a t e p o r t ( )
21 s e l f . obj_arduino . o p e n _ s e r i a l ( 1 , s e l f . port , s e l f . b a u d r a t e )
22
23 d e f run ( s e l f ) :
24 s e l f . blue = 9
25 s e l f . g r e e n = 10
26 s e l f . r e d = 11
5.4. Reading the pushbutton status from Python 57
27 s e l f . pushbutton = 12
28 for i in range (20) :
29 v a l = s e l f . obj_arduino . cmd_digital_in ( 1 , s e l f . pushbutton )
30 print ( val )
31 s e l f . obj_arduino . cmd_digital_out ( 1 , s e l f . blue , v a l )
32 sleep (0.5)
33
34 def exit ( s e l f ) :
35 s e l f . obj_arduino . c l o s e _ s e r i a l ( )
36
37 d e f main ( ) :
38 obj_pushbutton = PUSHBUTTON_LED( 1 1 5 2 0 0 )
39
40 i f __name__==’__main__ ’ :
41 main ( )
58 5. Interfacing a Pushbutton
Chapter 6
6.1 Preliminaries
A typical LDR and its symbolic representation are shown in Fig. 6.1a and Fig. 6.1b
respectively. The shield provided with the kit has an LDR mounted on it. The
LDR mounted on the shield looks exactly like the picture in Fig. 6.1a, although, the
picture looks a lot larger. This LDR is connected to the analog pin 5 of the Arduino
Uno board. The connections for this experiment are shown in Fig. 6.2. However,
the user doesn’t need to connect any wire or component explicitly.
The LDR mounted on the shield is an analog sensor. Hence, the analog voltage,
corresponding to the changing resistance, across its terminals needs to be digitized
before being sent to the computer. This is taken care of by an onboard Analog to
Digital Converter (ADC) of ATmega328 microcontroller on the Arduino Uno board.
ATmega328 has a 6-channel, 0 through 5, 10 bit ADC. Analog pin 5 of the Arduino
Uno board, to which the LDR is connected, corresponds to channel 5 of the ADC.
60 6. Interfacing a Light Dependent Resistor
Figure 6.2: Internal connection diagram for the LDR on the shield
As there are 10 bits, 0-5V readings from LDR are mapped to the ADC values from
0 to 1023.
LDR is a commonly available sensor in the market. It costs about Rs. 100.
There are multiple manufacturers which provide commercial LDRs. Some exam-
ples are VT90N1 and VT935G from EXCELITAS TECH, and N5AC501A085 and
NSL19M51 from ADVANCED PHOTONIX.
6.2. Connecting an LDR with Arduino Uno using a breadboard 61
Figure 6.3: An LDR to read its values with Arduino Uno using a breadboard
Figure 6.4: An LDR to control an LED with Arduino Uno using a breadboard
on the voltage values from the LDR. As shown in Fig. 6.4, digital pin 11 on Arduino
Uno is connected to the leftmost leg of the RGB LED. Rest of the connections are
same as that in Fig. 6.3.
1. A simple code to read the LDR values is given in Arduino Code 6.1. As
discussed earlier, the 0-5V LDR readings are mapped to 0-1023 through an
ADC. The Arduino IDE based command for the analog read functionality is
given by,
1 v a l = analogRead (A5) ; // v a l u e o f LDR
6.3. Interfacing the LDR through the Arduino IDE 63
where A5 represents the analog pin 5 to be read and the read LDR values are
stored in the variable val. The read values are then displayed using,
1 S e r i a l . println ( val ) ; // for display
is added so that the readings do not scroll away very fast. The entire reading
and display operation is carried out 50 times.
To observe the values, one has to open the Serial Monitor of the Arduino
IDE. The numbers displayed are in the range 0 to 1023 and depend on the light
falling on the LDR. If one does the experiment in a completely dark room, the
reading will be 0. If on the other hand, a bright light, say for instance the torch
light from mobile, is shined, the value displayed is close to 1023. One will get
intermediate values by keeping one’s finger on the LDR. While running this
experiment, the readers must keep their fingertips on the LDR and observe the
change in values being printed on the Serial Monitor of Arduino IDE.
1. Carry out the experiment in a dark room and check what values get displayed
on the Serial Monitor.
2. Carry out the experiment with the torch light from the mobile phone shining
on the LDR.
64 6. Interfacing a Light Dependent Resistor
Arduino Code 6.2 Turning the red LED on and off. Available at Origin/user
-code/ldr/arduino/ldr-led/ldr-led.ino, see Footnote 2 on page 2.
1 int val ;
2 int i = 1 ;
3 void s e t u p ( ) {
4 pinMode ( 1 1 , OUTPUT) ; / / LED P i n
5 S e r i a l . begin (115200) ;
6 f o r ( i = 1 ; i <= 5 0 ; i ++){
7 v a l = analogRead (A5) ; / / V a l u e o f LDR
8 S e r i a l . println ( val ) ;
9 i f ( val < 300) { // T h r e s h o l d
10 d i g i t a l W r i t e ( 1 1 , HIGH) ;
11 }
12 else
13 {
14 d i g i t a l W r i t e ( 1 1 , LOW) ;
15 }
16 delay (500) ;
17 }
18 }
19 void l o o p ( ) {
20 }
has to be attached to the Arduino Uno board before doing these experiments and
the Arduino Uno needs to be connected to the computer with a USB cable, as shown
in Fig. 2.4. The reader should go through the instructions given in Sec. 3.2 before
getting started.
1. In the first experiment, we will read the LDR values. The code for this exper-
iment is given in Python Code 6.1. As explained earlier in Sec. 4.4.1, we begin
with importing necessary modules followed by setting up the serial port. Then,
we read the input coming from analog pin 5 using the following command:
1 v a l = s e l f . obj_arduino . cmd_analog_in ( 1 , s e l f . l d r )
Note that the one leg of the LDR on the shield is connected to analog pin 5 of
Arduino Uno as given in Fig. 6.2. The read value is displayed by the following
command:
1 print ( val )
where val contains the LDR values ranging from 0 to 1023. If one does the
experiment in a completely dark room, the reading will be 0. If on the other
hand, a bright light, say for instance the torch light from mobile, is shined, the
value displayed is close to 1023. One will get intermediate values by keeping
one’s finger on the LDR. To encourage the user to have a good hands-on,
we run these commands in a for loop for 50 iterations. While running this
experiment, the readers must keep their fingertips on the LDR and observe the
change in values being printed on on the Command Prompt (on Windows) or
Terminal (on Linux), as the case maybe.
2. This experiment is an extension of the previous experiment. Here, depending
the resistance of the LDR, we will turn the red LED on. The program for
this is available at Python Code 6.2. The value of LDR is read and stored
in val. In case it is below some threshold (like 300 in Python Code 6.2), it
puts a high in pin number 11. From Sec. 4.1, one can note that this pin is for
the red LED. If the LDR value is below 300, the red LED will be on, else, it
will be turned off. While running this experiment, the readers must keep their
fingertips on the LDR so that the threshold is achieved. Accordingly, they can
observe whether the red LED is turned on.
Exercise 6.2 Carry out the exercise below:
1. Carry out the exercise in the previous section.
2. Calculate the difference in LDR readings in indoor room before lighting the
lamp and after lighting the lamp. You can also record changes in the room
lighting at different times of the day.
66 6. Interfacing a Light Dependent Resistor
Python Code 6.2 Turning the red LED on and off. Available at Origin/user-
code/ldr/python/ldr-led.py, see Footnote 2 on page 2.
6.4. Interfacing the LDR through Python 67
1 import o s
2 import s y s
3 cwd = o s . getcwd ( )
4 ( s e t p a t h , Examples ) = o s . path . s p l i t ( cwd )
5 s y s . path . append ( s e t p a t h )
6
7 from Arduino . Arduino import Arduino
8 from time import s l e e p
9
10 c l a s s LDR:
11 d e f __init__ ( s e l f , b a u d r a t e ) :
12 s e l f . baudrate = baudrate
13 s e l f . setup ()
14 s e l f . run ( )
15 s e l f . exit ()
16
17 def setup ( s e l f ) :
18 s e l f . obj_arduino = Arduino ( )
19 s e l f . p o r t = s e l f . obj_arduino . l o c a t e p o r t ( )
20 s e l f . obj_arduino . o p e n _ s e r i a l ( 1 , s e l f . port , s e l f . b a u d r a t e )
21
22 d e f run ( s e l f ) :
23 s e l f . ldr = 5
24 s e l f . blue = 9
25 s e l f . g r e e n = 10
26 s e l f . r e d = 11
27 for i in range (50) :
28 v a l = s e l f . obj_arduino . cmd_analog_in ( 1 , s e l f . l d r )
29 print ( val )
30 i f int ( val ) < 300:
31 s e l f . obj_arduino . cmd_digital_out ( 1 , s e l f . red , 1 )
32 else :
33 s e l f . obj_arduino . cmd_digital_out ( 1 , s e l f . red , 0 )
34 sleep (0.5)
35
36 def exit ( s e l f ) :
37 s e l f . obj_arduino . c l o s e _ s e r i a l ( )
38
39 d e f main ( ) :
40 o b j _ l d r = LDR( 1 1 5 2 0 0 )
41
42 i f __name__== ’__main__ ’ :
43 main ( )
68 6. Interfacing a Light Dependent Resistor
Chapter 7
Interfacing a Potentiometer
7.1 Preliminaries
The shield provided with the kit has a 1K potentiometer mounted on it. The me-
chanical contact at the middle terminal is rotated to vary the resistance across the
middle terminal and the two ends of the potentiometer. With the fixed voltage
across the two terminals of the potentiometer, the position of the wiper determines
the potential across the middle terminal and either of the two end terminals. Nowa-
days, digital potentiometer integrated circuits, which vary resistance across two pins
on the basis of the set value, are also available.
The potentiometer used in the kit can be seen on the shield in Fig. 4.3 on page 36.
It is mounted on the shield. The two end terminals of the potentiometer are con-
nected to 5V supply and ground. The middle terminal is connected to analog pin 2
of the Arduino Uno board. The resistance between the middle terminal and either of
the two ends can be varied by rotating the middle terminal by hand. The connection
diagram for the potentiometer is shown in Fig. 7.1.
70 7. Interfacing a Potentiometer
(a) Pictorial representation of a potentiometer (b) Internal connection diagram for the poten-
tiometer on the shield
Figure 7.2: A potentiometer to control an LED with Arduino Uno using a breadboard
the fifth and sixth tutorials, i.e., First Arduino Program and Arduino with
Tricolor LED and Push button.
In case you have a potentiometer, and you want to connect it with Arduino Uno
on a breadboard, please refer to Fig. 7.2. The connections given in this figure can
be used to control an RGB LED depending upon the values from the potentiometer.
As shown in Fig. 7.2, the three legs of the potentiometer are connected to 5V, analog
pin 2, and GND on Arduino Uno. Depending upon how much the potentiometer’s
shaft is rotated, one can get a value on analog pin 2. On the other hand, there is an
RGB LED, and its four legs are connected to three different digital pins and GND
on Arduino Uno as discussed in Chapter 4.
a USB cable, as shown in Fig. 2.4. The reader should go through the instructions
given in Sec. 3.1 before getting started.
The Arduino code for this experiment is given in Arduino Code 7.1. In this code,
lines 1 through 4 are used to assign relevant PINs to the potentiometer and RGB
LED. The purpose of these lines is to avoid confusion, with the PINs, for beginners.
Next, we start serial port communication, as on line 9, with the baud rate of 115200.
To take the potentiometer input, we need to initialize the pins by giving the following
commands:
1 pinMode (POT, INPUT) ;
2 pinMode (RGB_RED, OUTPUT) ;
3 pinMode (RGB_GREEN, OUTPUT) ;
4 pinMode (RGB_BLUE, OUTPUT) ;
4 const i n t RGB_BLUE = 9 ;
5 int val = 0 ;
6 int i = 0 ;
7 void s e t u p ( ) {
8 S e r i a l . begin (115200) ;
9 pinMode (POT, INPUT) ;
10 pinMode (RGB_RED, OUTPUT) ;
11 pinMode (RGB_GREEN, OUTPUT) ;
12 pinMode (RGB_BLUE, OUTPUT) ;
13 f o r ( i = 0 ; i < 2 0 ; i ++){
14 v a l = analogRead (POT) ;
15 S e r i a l . println ( val ) ;
16 i f ( v a l >= 0 & v a l < 3 2 0 ) { // t h r e s h o l d 1
17 d i g i t a l W r i t e (RGB_RED, HIGH) ;
18 delay (1000) ;
19 d i g i t a l W r i t e (RGB_RED, LOW) ;
20 } e l s e i f ( v a l >= 320 & v a l < 9 0 0 ) { // t h r e s h o l d 2
21 d i g i t a l W r i t e (RGB_GREEN, HIGH) ;
22 delay (1000) ;
23 d i g i t a l W r i t e (RGB_GREEN, LOW) ;
24 } e l s e i f ( v a l >= 900 & v a l <= 1 0 2 3 ) { // t h r e s h o l d 3
25 d i g i t a l W r i t e (RGB_BLUE, HIGH) ;
26 delay (1000) ;
27 d i g i t a l W r i t e (RGB_BLUE, LOW) ;
28 }
29 }
30 }
31 void l o o p ( ) {
32 }
by setting up the serial port. Then, we read the analog input at pin 2 using,
1 v a l = s e l f . obj_arduino . cmd_analog_in ( 1 , s e l f . pot )
where the first argument is for the kit number and the second argument corresponds
to the analog pin to be read. Next, we compare the read values with the set range,
and then turn on and off the corresponding LED. For example,
1 i f ( i n t ( v a l ) >= 0 and i n t ( v a l ) < 3 2 0 ) :
2 s e l f . obj_arduino . cmd_digital_out ( 1 , s e l f . red , 1 )
3 sleep (1)
4 s e l f . obj_arduino . cmd_digital_out ( 1 , s e l f . red , 0 )
where cmd_digital_out is used to set the pin 11 high (1) or low (0). We used
sleep(1) to retain the LED in the on state for one second. A similar check is done
the other two bands. While running this experiment, the readers must rotate the
knob of the potentiometer and observe the change in the color of the RGB LED.
26 s e l f . r e d = 11
27 for i in range (20) :
28 v a l = s e l f . obj_arduino . cmd_analog_in ( 1 , s e l f . pot )
29 print ( val )
30
31 i f ( i n t ( v a l ) >= 0 and i n t ( v a l ) < 3 2 0 ) :
32 s e l f . obj_arduino . cmd_digital_out ( 1 , s e l f . red , 1 )
33 sleep (1)
34 s e l f . obj_arduino . cmd_digital_out ( 1 , s e l f . red , 0 )
35 e l i f ( i n t ( v a l ) >= 320 and i n t ( v a l ) < 9 0 0 ) :
36 s e l f . obj_arduino . cmd_digital_out ( 1 , s e l f . green , 1 )
37 sleep (1)
38 s e l f . obj_arduino . cmd_digital_out ( 1 , s e l f . green , 0 )
39 e l i f ( i n t ( v a l ) >= 900 and i n t ( v a l ) <= 1 0 2 3 ) :
40 s e l f . obj_arduino . cmd_digital_out ( 1 , s e l f . blue , 1 )
41 sleep (1)
42 s e l f . obj_arduino . cmd_digital_out ( 1 , s e l f . blue , 0 )
43
44 def exit ( s e l f ) :
45 s e l f . obj_arduino . c l o s e _ s e r i a l ( )
46
47 d e f main ( ) :
48 obj_pot = POT( 1 1 5 2 0 0 )
49
50 i f __name__==’__main__ ’ :
51 main ( )
76 7. Interfacing a Potentiometer
Chapter 8
Interfacing a Thermistor
8.1 Preliminaries
A typical thermistor and its symbolic representation are shown in 8.1a and 8.1b
respectively. The thermistor is available on the shield provided with the kit. It is
a bead type thermistor having a resistance of 10k at room temperature. A voltage
divider network is formed using thermistor and another fixed 10k resistor. A voltage
of 5 volts is applied across the series combination of the thermistor and the fixed 10k
resistor. Voltage across the fixed resistor is sensed and is given to the ADC via pin
4. Hence at room temperature, both the resistors offer 10k resistance resulting in
dividing the 5V equally. A buzzer is also connected on pin 3 which is a digital output
pin. Connections for this experiment are shown in 8.2a and 8.2b. Nevertheless, the
user doesn’t need to connect any wire or component explicitly.
78 8. Interfacing a Thermistor
Figure 8.2: Internal connection diagrams for thermistor and buzzer on the shield
8.2. Connecting a thermistor with Arduino Uno using a breadboard 79
Figure 8.3: A thermistor to read its values with Arduino Uno using a breadboard
Figure 8.4: A thermistor to control a buzzer with Arduino Uno using a breadboard
Finally, this voltage is used by the analog pin 4 of Arduino Uno in its logic.
The connections shown in Fig. 8.4 can be used to control a buzzer, depending
on the values from the thermistor. As shown in Fig. 8.4, digital pin 3 on Arduino
Uno is connected to the one of the legs of the buzzer. Another leg of the buzzer is
connected to GND of Arduino Uno.
1. A simple code to read the values from thermistor is given in Arduino Code 8.1.
The Arduino IDE based command for the analog read functionality is given
by.
1 v a l = analogRead (A4) ; / / r e a d v a l u e f r o m t h e r m i s t o r
8.3. Interfacing the thermistor from the Arduino IDE 81
where A4 represents the analog pin 4 to be read. The read value is stored in
variable val and is displayed using
1 S e r i a l . p r i n t l n ( v a l ) ; // d i s p l a y
is used to put a delay of 500 milliseconds. This is to avoid very fast display
of the read values. The entire reading and display operation is carried out 40
times.
The values can be observed over the Serial Monitor of Arduino IDE. The
numbers displayed range from 0 to 1023. At room temperature you may get the
output of ADC around 500. If a heating or cooling source is available, one can
observe the increase or decrease in the ADC output. Although the thermistor
is of NTC type, the ADC output increases with increase in temperature. This
is because the voltage across the fixed resistor is sensed.
While running this experiment, the readers should try holding (or rubbing)
the thermistor with their fingertips. Doing so will transfer heat from the per-
son holding the thermistor, thereby raising the temperature of the thermistor.
Accordingly, they should observe the change in the thermistor values on the
Serial Monitor.
A delay of half a second is introduced before the next value is read. While
running this experiment, the readers should try holding (or rubbing) the ther-
mistor with their fingertips. Doing so will transfer heat from the person holding
the thermistor, thereby raising the temperature of the thermistor. Accordingly,
they should observe whether the threshold of 550 is achieved and the buzzer
is enabled.
Note: Once the thermistor value reaches 550 (the threshold), the value will
remain the same (unless it is cooled). Therefore, the buzzer will continu-
ously produce the sound, which might be a bit annoying. To get rid of this,
the readers are advised to execute some other code on Arduino Uno like Ar-
duino Code 8.1.
1. Put the thermistor in the vicinity of an Ice bowl. Take care not to wet the
shield while doing so. Note down the ADC output value for 0◦ Celsius.
9 v a l = analogRead (A4) ; / / r e a d v a l u e f r o m t h e r m i s t o r
10 S e r i a l . p r i n t l n ( v a l ) ; // d i s p l a y
11 delay (500) ;
12 }
13
14 }
15
16 void l o o p ( )
17 {
18 }
Arduino Code 8.2 Turning the buzzer on using the thermistor values read by
ADC. Available at Origin/user-code/thermistor/arduino/therm-buzz
er/therm-buzzer.ino, see Footnote 2 on page 2.
1 int val ;
2 int i ;
3
4 void s e t u p ( )
5 {
6 pinMode ( 3 , OUTPUT) ;
7 S e r i a l . begin (115200) ;
8
9 f o r ( i = 1 ; i <= 2 0 ; i ++)
10 {
11 v a l = analogRead (A4) ; / / r e a d v a l u e f r o m t h e r m i s t o r
12 S e r i a l . p r i n t l n ( v a l ) ; // d i s p l a y
13
14 i f ( val > 550)
15 {
16 d i g i t a l W r i t e ( 3 , HIGH) ; / / Turn ON b u z z e r
17 }
18 else
19 {
20 d i g i t a l W r i t e ( 3 , LOW) ; / / Turn OFF b u z z e r
21 }
22 delay (500) ;
23 }
24 d i g i t a l W r i t e ( 3 , LOW) ; / / Turn OFF b u z z e r
25 }
26
27 void l o o p ( )
28 {
29 }
84 8. Interfacing a Thermistor
1. In the first experiment, we will read the thermistor values. The code for this
experiment is given in Python Code 8.1. As explained earlier in Sec. 4.4.1,
we begin with importing necessary modules followed by setting up the serial
port. Then, we read the input coming from analog pin 4 using the following
command:
1 v a l = s e l f . obj_arduino . cmd_analog_in ( 1 , s e l f . therm )
Note that the one leg of the thermistor on the shield is connected to analog
pin 4 of Arduino Uno as given in Fig. 8.2a. The read value is displayed by the
following command:
1 print ( val )
where val contains the thermistor values ranging from 0 to 1023. To encourage
the user to have a good hands-on, we run these commands in a for loop for
20 iterations.
While running this experiment, the readers should try holding (or rubbing)
the thermistor with their fingertips. Doing so will transfer heat from the per-
son holding the thermistor, thereby raising the temperature of the thermistor.
Accordingly, they should observe the change in values being printed on on the
Command Prompt (on Windows) or Terminal (on Linux), as the case maybe.
in this experiment. One may note that this threshold would vary according to
the location and time of performing this experiment. Accordingly, the readers
are advised to change this threshold in Python Code 8.2. For testing purposes,
one may note the normal thermistor readings generated from the execution of
Python Code 8.1 and set a threshold that is approximately 10 more than these
readings.
In this experiment we compare the ADC output value with 550 and as soon
as the value exceeds 550 the buzzer is turned on. The following lines of code
perform this comparison and sending a HIGH signal to digital pin 3 on Arduino
Uno:
1 i f ( int ( val ) > 550) :
2 s e l f . obj_arduino . cmd_digital_out ( 1 , s e l f . buzzer , 1 )
3 else :
4 s e l f . obj_arduino . cmd_digital_out ( 1 , s e l f . buzzer , 0 )
5 sleep (0.5)
A delay of half a second is introduced before the next value is read. While
running this experiment, the readers should try holding (or rubbing) the ther-
mistor with their fingertips. Doing so will transfer heat from the person holding
the thermistor, thereby raising the temperature of the thermistor. Accordingly,
they should observe whether the threshold of 550 is achieved and the buzzer
is enabled.
Note: Once the thermistor value reaches 550 (the threshold), the value will
remain the same (unless it is cooled). Therefore, the buzzer will contin-
uously produce the sound, which might be a bit annoying. To get rid of
this, the readers are advised to execute some other code on Arduino Uno like
Python Code 8.1.
1 import o s
2 import s y s
3 cwd = o s . getcwd ( )
4 ( s e t p a t h , Examples ) = o s . path . s p l i t ( cwd )
5 s y s . path . append ( s e t p a t h )
6
7 from Arduino . Arduino import Arduino
86 8. Interfacing a Thermistor
Python Code 8.2 Turning the buzzer on using the thermistor values read by ADC.
Available at Origin/user-code/thermistor/python/therm-buzzer.py,
see Footnote 2 on page 2.
1 import o s
2 import s y s
3 cwd = o s . getcwd ( )
4 ( s e t p a t h , Examples ) = o s . path . s p l i t ( cwd )
5 s y s . path . append ( s e t p a t h )
6
7 from Arduino . Arduino import Arduino
8 from time import s l e e p
9
10 c l a s s THERM_BUZZER:
11 d e f __init__ ( s e l f , b a u d r a t e ) :
12 s e l f . baudrate = baudrate
13 s e l f . setup ()
14 s e l f . run ( )
8.4. Interfacing the thermistor from Python 87
15 s e l f . exit ()
16
17 def setup ( s e l f ) :
18 s e l f . obj_arduino = Arduino ( )
19 s e l f . p o r t = s e l f . obj_arduino . l o c a t e p o r t ( )
20 s e l f . obj_arduino . o p e n _ s e r i a l ( 1 , s e l f . port , s e l f . b a u d r a t e )
21
22 d e f run ( s e l f ) :
23 s e l f . therm = 4
24 s e l f . buzzer = 3
25
26 for i in range (20) :
27 v a l = s e l f . obj_arduino . cmd_analog_in ( 1 , s e l f . therm )
28 print ( val )
29
30 i f ( int ( val ) > 550) :
31 s e l f . obj_arduino . cmd_digital_out ( 1 , s e l f . buzzer , 1 )
32 else :
33 s e l f . obj_arduino . cmd_digital_out ( 1 , s e l f . buzzer , 0 )
34 sleep (0.5)
35 s e l f . obj_arduino . cmd_digital_out ( 1 , s e l f . buzzer , 0 )
36
37
38 def exit ( s e l f ) :
39 s e l f . obj_arduino . c l o s e _ s e r i a l ( )
40
41 d e f main ( ) :
42 obj_pot = THERM_BUZZER( 1 1 5 2 0 0 )
43
44 i f __name__== ’__main__ ’ :
45 main ( )
88 8. Interfacing a Thermistor
Chapter 9
Interfacing a Servomotor
9.1 Preliminaries
A servomotor is a rotary control mechanism. It can be commanded to rotate to a
specified angle. It can rotate in positive or negative direction. Using servomotors,
one can control angular position, velocity and acceleration. Servomotors are useful
in many applications. Some examples are robotics, industrial motors and printers.
Typical servomotors have a maximum range of 180◦ , although some have different
ranges3 . Servomotors typically have a position sensor, using which, rotate to the
commanded angle. The minimum angle to which a servomotor can be rotated is its
least count, which varies from one model to another. Low cost servomotors have a
large least count, say, of the order of 10◦ .
A servomotor typically comes with three terminals for the following three signals:
position signal, Vcc and ground. Position signal means that this terminal should be
connected to one of the PWM (Pulse Width Modulation) pins [15] on Arduino Uno.
This book uses PWM pin 5 for this purpose. Rest two terminals (Vcc and ground)
need to be connected to 5V and GND on Arduino Uno. Table 9.1 summarizes these
connections.
3
All the angles in a servomotor are absolute angles, with respect to a fixed reference point, which
can be taken as 0◦ .
90 9. Interfacing a Servomotor
Figure 9.3: A servomotor and a potentiometer with Arduino Uno using a breadboard
should go through the instructions given in Sec. 3.1 before getting started.
1. In the first experiment, we will move the servomotor by 30◦ . Arduino Code 9.1
has the required code for this. This code makes use of a library named Servo
[16]. Thus, we include its header file at the top of Arduino Code 9.1:
1 #include <Servo . h>
Most Arduino boards allow the creation of 12 servo objects. Next, we initial-
ize the port for serial communication at data rate of 115200 bits per second.
Following to this, we mention the pin to which the servo is attached, as shown
below:
1 myservo . a t t a c h ( 5 ) ; / / a t t a c h t h e s e r v o o b j e c t on t o p i n 5
With this, we issue the command to rotate the servomotor by 30◦ followed by
a delay of 1000 milliseconds:
1 myservo . w r i t e ( 3 0 ) ; / / t e l l servo to r o t a t e by 3 0 d e g r e e s
2 delay (1000) ;
9.3. Controlling the servomotor through the Arduino IDE 93
2. In the second experiment, we move the motor by 90◦ in the forward direction
and 45◦ in the reverse direction. This code is given in Arduino Code 9.2. In
this code, we have added a delay of 1000 milliseconds between the two instances
of rotating the servomotor:
1 myservo . w r i t e ( 9 0 ) ; / / t e l l servo to r o t a t e by 9 0 d e g r e e s
2 delay (1000) ;
3 myservo . w r i t e ( 4 5 ) ;
What is the reason behind this delay? If the delay were not there, the motor
will move only by the net angle of 90 − 45 = 45 degrees. The reader should
verify this by commenting on the delay command.
4. Finally, in the last experiment, we read the potentiometer value from the shield
and use it to drive the servomotor, see Arduino Code 9.4. The resistance of
the potentiometer is represented in 10 bits. As a result, the resistance value
could be any one of 1024 values, from 0 to 1023. This entire range is mapped
to 180◦ , as shown below:
1 v a l = analogRead ( p o t p i n ) ; / / r e a d s a v a l u e i n ( 0 , 1 0 2 3 ) t h r o u g h
pot
2 v a l = map( v a l , 0 , 1 0 2 3 , 0 , 1 8 0 ) ; / / maps i t i n t h e r a n g e ( 0 , 1 8 0 )
degrees
3 myservo . w r i t e ( v a l ) ; / / m o v e s t h e m o t o r t o t h e mapped
degree
By rotating the potentiometer, one can make the motor move by different
amounts.
As mentioned in Chapter 7, the potentiometer on the shield is connected to
analog pin 2 on Arduino Uno. Through this pin, the resistance of the poten-
tiometer, in the range of 0 to 1023, depending on its position, is read. Thus,
by rotating the potentiometer, we make different values appear on pin 2. This
94 9. Interfacing a Servomotor
value is used to move the servo. For example, if the resistance is half of the
total, the servomotor will go to 90◦ and so on. The servomotor stops for 500
milliseconds after every move. The loop is executed for 50 iterations. During
this period, the servomotor keeps moving as dictated by the resistance of the
potentiometer. While running this experiment, the readers must rotate the
knob of the potentiometer and observe the change in the position (or angle) of
the servomotor.
1. In Arduino Code 9.3, the loop parameter i starts from 1. From what angle
will the motor start? If one wants the motor to start from 0◦ , what should
one do?
2. How does one find the least count of the servomotor? If the variable angle
is chosen to be less than this least count in Arduino Code 9.3, what happens?
3. What happens if 180 in Line 10 of Arduino Code 9.4 is changed to 90?
What does the change 180 to 90 mean?
Arduino Code 9.2 Rotating the servomotor to a specified degree and reversing.
Available at Origin/user-code/servo/arduino/servo-reverse/servo-
reverse.ino, see Footnote 2 on page 2.
9.3. Controlling the servomotor through the Arduino IDE 95
Arduino Code 9.4 Rotating the servomotor through the potentiometer. Available
at Origin/user-code/servo/arduino/servo-pot/servo-pot.ino, see
Footnote 2 on page 2.
1 #include <Servo . h>
2 Servo myservo ; / / c r e a t e s e r v o o b j e c t t o c o n t r o l a s e r v o
3 int potpin = 2 ; // a n a l o g p i n u s ed t o c o n n e c t t h e p o t e n t i o m e t e r
4 int val ; // v a r i a b l e t o r e a d t h e v a l u e from t h e a n a l o g p i n
5 int i ;
6 void s e t u p ( ) {
7 S e r i a l . begin (115200) ;
8 myservo . a t t a c h ( 5 ) ; / / a t t a c h t h e s e r v o o b j e c t on t o p i n 5
9 f o r ( i = 0 ; i < 5 0 ; ++i ) {
10 v a l = analogRead ( p o t p i n ) ; / / r e a d s a v a l u e i n ( 0 , 1 0 2 3 ) t h r o u g h p o t
96 9. Interfacing a Servomotor
11 v a l = map( v a l , 0 , 1 0 2 3 , 0 , 1 8 0 ) ; / / maps i t i n t h e r a n g e ( 0 , 1 8 0 )
degrees
12 myservo . w r i t e ( v a l ) ; / / m o v e s t h e m o t o r t o t h e mapped d e g r e e
13 delay (500) ; // w a i t s f o r a s e c o n d f o r s e r v o t o r e a c h
14 }
15 myservo . d e t a c h ( ) ;
16 }
17 void l o o p ( ) {
18 }
1. The first experiment makes the servomotor move by 30◦ . The code for this
experiment is given in Python Code 9.1. As explained earlier in Sec. 4.4.1, we
begin with importing necessary modules followed by setting up the serial port.
Next, we attach the servomotor by issuing the command given below:
1 s e l f . obj_arduino . cmd_servo_attach ( 1 , 1 )
2. In the second experiment, we move the servomotor by 90◦ in the forward direc-
tion and 45◦ in the reverse direction. This code is given in Python Code 9.2.
In this code, we have added a delay of 1 second between the two instances of
moving the servomotor:
1 s e l f . obj_arduino . cmd_servo_move ( 1 , 1 , 9 0 )
2 sleep (1)
3 s e l f . obj_arduino . cmd_servo_move ( 1 , 1 , 4 5 )
What is the reason behind this delay? If the delay were not there, the motor
will move only by the net angle of 90 − 45 = 45 degrees. The reader should
verify this by commenting on the delay command.
3. In the third experiment, we move the motor in increments of 20◦ . This is
achieved by the for loop, as in Python Code 9.3. The code helps the motor
move in steps of 20◦ all the way to 180◦ .
4. Finally, in the last experiment, we read the potentiometer value from the shield
and use it to drive the servomotor, see Python Code 9.4. The resistance of
the potentiometer is represented in 10 bits. As a result, the resistance value
could be any one of 1024 values, from 0 to 1023. This entire range is mapped
to 180◦ , as shown below:
1 v a l = s e l f . obj_arduino . cmd_analog_in ( 1 , s e l f . pot )
2 val = int ( val ∗180/1023)
3 s e l f . obj_arduino . cmd_servo_move ( 1 , 1 , v a l )
By rotating the potentiometer, one can make the motor move by different
amounts.
As mentioned in Chapter 7, the potentiometer on the shield is connected to
analog pin 2 on Arduino Uno. Through this pin, the resistance of the poten-
tiometer, in the range of 0 to 1023, depending on its position, is read. Thus,
by rotating the potentiometer, we make different values appear on pin 2. This
value is used to move the servo. For example, if the resistance is half of the
total, the servomotor will go to 90◦ and so on. The servomotor stops for 500
milliseconds after every move. The loop is executed for 50 iterations. During
this period, the servomotor keeps moving as dictated by the resistance of the
potentiometer. While running this experiment, the readers must rotate the
knob of the potentiometer by a fixed amount and observe the change in the
position (or angle) of the servomotor.
1 import o s
2 import s y s
3 cwd = o s . getcwd ( )
4 ( s e t p a t h , Examples ) = o s . path . s p l i t ( cwd )
5 s y s . path . append ( s e t p a t h )
6
7 from Arduino . Arduino import Arduino
8 from time import s l e e p
9
10 c l a s s SERVO_INIT :
11 d e f __init__ ( s e l f , b a u d r a t e ) :
12 s e l f . baudrate = baudrate
13 s e l f . setup ()
14 s e l f . run ( )
15 s e l f . exit ()
16
17 def setup ( s e l f ) :
18 s e l f . obj_arduino = Arduino ( )
19 s e l f . p o r t = s e l f . obj_arduino . l o c a t e p o r t ( )
20 s e l f . obj_arduino . o p e n _ s e r i a l ( 1 , s e l f . port , s e l f . b a u d r a t e )
21
22 d e f run ( s e l f ) :
23 s e l f . pin1 = 5
24 s e l f . obj_arduino . cmd_servo_attach ( 1 , 1 )
25 s e l f . obj_arduino . cmd_servo_move ( 1 , 1 , 3 0 )
26 sleep (1)
27 s e l f . obj_arduino . cmd_servo_detach ( 1 , 1 )
28 sleep (1)
29
30
31 def exit ( s e l f ) :
32 s e l f . obj_arduino . c l o s e _ s e r i a l ( )
33
34 d e f main ( ) :
35 o b j _ s e r v o = SERVO_INIT( 1 1 5 2 0 0 )
36
37 i f __name__== ’__main__ ’ :
38 main ( )
Python Code 9.2 Rotating the servomotor to a specified degree and reversing.
Available at Origin/user-code/servo/python/servo-reverse.py, see
Footnote 2 on page 2.
1 import o s
2 import s y s
3 cwd = o s . getcwd ( )
9.4. Controlling the servomotor through Python 99
Python Code 9.3 Rotating the servomotor in steps of 20◦ . Available at Origin
/user-code/servo/python/servo-loop.py, see Footnote 2 on page 2.
1 import o s
2 import s y s
3 cwd = o s . getcwd ( )
4 ( s e t p a t h , Examples )=o s . path . s p l i t ( cwd )
5 s y s . path . append ( s e t p a t h )
6
7 from Arduino . Arduino import Arduino
8 from time import s l e e p
9
100 9. Interfacing a Servomotor
10 c l a s s SERVO_INCR:
11 d e f __init__ ( s e l f , b a u d r a t e ) :
12 s e l f . baudrate = baudrate
13 s e l f . setup ()
14 s e l f . run ( )
15 s e l f . exit ()
16
17 def setup ( s e l f ) :
18 s e l f . obj_arduino = Arduino ( )
19 s e l f . p o r t = s e l f . obj_arduino . l o c a t e p o r t ( )
20 s e l f . obj_arduino . o p e n _ s e r i a l ( 1 , s e l f . port , s e l f . b a u d r a t e )
21
22 d e f run ( s e l f ) :
23 s e l f . pin1 = 5
24 s e l f . obj_arduino . cmd_servo_attach ( 1 , 1 )
25 sleep (1)
26 s e l f . a n g l e = 20
27 for i in range (10) :
28 s e l f . obj_arduino . cmd_servo_move ( 1 , 1 , s e l f . a n g l e ∗ i )
29 sleep (1)
30 s e l f . obj_arduino . cmd_servo_detach ( 1 , 1 )
31
32 def exit ( s e l f ) :
33 s e l f . obj_arduino . c l o s e _ s e r i a l ( )
34
35 d e f main ( ) :
36 o b j _ s e r v o=SERVO_INCR( 1 1 5 2 0 0 )
37
38 i f __name__==’__main__ ’ :
39 main ( )
Python Code 9.4 Rotating the servomotor to a degree specified by the poten-
tiometer. Available at Origin/user-code/servo/python/servo-pot.py,
see Footnote 2 on page 2.
1 import o s
2 import s y s
3 cwd = o s . getcwd ( )
4 ( s e t p a t h , Examples ) = o s . path . s p l i t ( cwd )
5 s y s . path . append ( s e t p a t h )
6
7 from Arduino . Arduino import Arduino
8 from time import s l e e p
9
10 c l a s s SERVO_POT:
11 d e f __init__ ( s e l f , b a u d r a t e ) :
12 s e l f . baudrate = baudrate
13 s e l f . setup ()
14 s e l f . run ( )
9.4. Controlling the servomotor through Python 101
15 s e l f . exit ()
16
17 def setup ( s e l f ) :
18 s e l f . obj_arduino = Arduino ( )
19 s e l f . p o r t = s e l f . obj_arduino . l o c a t e p o r t ( )
20 s e l f . obj_arduino . o p e n _ s e r i a l ( 1 , s e l f . port , s e l f . b a u d r a t e )
21
22 d e f run ( s e l f ) :
23 s e l f . pin1 = 5
24 s e l f . pot = 2
25 s e l f . obj_arduino . cmd_servo_attach ( 1 , 1 )
26 for i in range (50) :
27 v a l = s e l f . obj_arduino . cmd_analog_in ( 1 , s e l f . pot )
28 val = int ( val ∗180/1023)
29 s e l f . obj_arduino . cmd_servo_move ( 1 , 1 , v a l )
30 sleep (0.5)
31 s e l f . obj_arduino . cmd_servo_detach ( 1 , 1 )
32
33 def exit ( s e l f ) :
34 s e l f . obj_arduino . c l o s e _ s e r i a l ( )
35
36 d e f main ( ) :
37 o b j _ s e r v o = SERVO_POT( 1 1 5 2 0 0 )
38
39 i f __name__==’__main__ ’ :
40 main ( )
102 9. Interfacing a Servomotor
Chapter 10
Interfacing a DC Motor
10.1 Preliminaries
In order to change its direction, the sign of the voltage applied to the DC motor is
changed. For that, one needs to use external hardware called H-Bridge circuit DC
motor with Arduino Uno. H-Bridge allows direction of the current passing through
the DC motor to be changed. It avoids the sudden short that may happen while
changing the direction of current passing through the motor. It is one of the essential
circuits for the smooth operation of a DC motor. There are many manufacturers
of H-bridge circuit viz. L293D, L298, etc. Often they provide small PCB breakout
boards. These modules also provide an extra supply that is needed to drive the
DC motor. Fig. 10.1 shows the diagram of a typical breakout board containing IC
L293D, which will be used in this book. One may note that the toolboxes presented
in this book supports three types of H-Bridge circuit. Table 10.1 provides the values
to be passed for different H-Bridge circuits.
Input from Arduino Uno to H-bridge IC is in pulse width modulation (PWM)
form. PWM is a technique to generate analog voltages using digital pins. We know
104 10. Interfacing a DC Motor
that Arduino Uno has digital input-output pins. When these pins are configured
as an output, they provide High (5V) or Low (0V) voltage. With PWM technique,
these pins are switched on and off iteratively and fast enough so that the voltage is
averaged out to some analog value in between 0-5V. This analog value depends on
”switch-on” time and ”switch-off” time. For example, if both ”switch-on” time and
”switch-off” time are equal, average voltage on PWM pin will be 2.5V. To enable fast
switching of digital pin, a special hardware is provided in microcontrollers. PWM
is considered as an important resource of the microcontroller system. Arduino Uno
board has 6 PWM pins (3, 5, 6, 9, 10, 11) [15]. On an original Arduino Uno board,
these pins are marked with a tilde sign next to the pin number, as shown in Fig. 10.2.
For each of these pins, the input can come from 8 bits. Thus we can generate 28 = 256
different analog values (from 0 to 255) in between 0-5V with these pins.
10.2. Controlling the DC motor from Arduino 105
Figure 10.4: How to connect the DC motor to the Arduino Uno board
Note: The readers are advised to affix a small (very lightweight) piece of paper at
the tip of the shaft of the DC motor. That will help them observe the direction of
rotation of the DC motor while running the experiments.
10.2. Controlling the DC motor from Arduino 107
1. We now demonstrate how to drive the DC motor from the Arduino IDE. Ar-
duino Code 10.1 has the required code for this. It starts the serial port at a
baud rate of 115200. Pins 9 and 10 are declared as output pins and hence
values can be written on to them. The following lines are used to declare these
two pins as output pins:
1 pinMode ( 9 , OUTPUT) ; / / u s e p i n s 9 and 1 0 f o r m o t o r o u t p u t
2 pinMode ( 1 0 , OUTPUT) ;
Next, we write PWM 100 on pin 9 and PWM 0 on pin 10, as shown below:
1 a n a l o g W r i t e ( 9 , 1 0 0 ) ; / / PWM 1 0 0 on p i n 9 ma k es t h e m o t o r r o t a t e
2 analogWrite (10 , 0) ;
Recall from Fig. 10.4 that pins 9 and 10 are connected to the input of the
breakout board, which in turn makes the DC motor run at an intermediate
speed. Some of the breakout boards may not have enough current driving
capability and hence tend to heat up. To avoid these difficulties, the DC motor
is run at an intermediate value of PWM 100. Remember, we can increase this
value upto 255.
The line containing delay makes the previous command execute for 3 seconds.
As a result, the DC motor continues to rotate for 3 seconds. After this, we put
a 0 in both pins 9 and 10, as shown below:
1 analogWrite (9 , 0) ; / / 0 on p i n 9 s t o p s t h e motor
2 analogWrite (10 , 0) ;
Next, we release the motor by writing 0 in both pins 9 and 10, as shown below:
1 analogWrite (9 , 0) ; // Motor is stopped
2 analogWrite (10 , 0) ; //
3. Next, we make the DC motor run in forward and reverse directions, in a loop.
This is done through Arduino Code 10.3. We first write PWM 100 in pin 9 for
3 seconds. After that, make the motor stop for 2 seconds. Finally, make the
motor rotate in the reverse direction by writing PWM 100 in pin 10 for two
seconds. Finally, we make the motor stop for one second. The entire thing is
put in a for loop which runs for 5 iterations.
1. Try out some of the suggestions given above, i.e., removing certain numbers
from the code
2. See if the DC motor runs if you put 1 instead of 100 as the PWM value.
Explain why it does not run. Find out the smallest value at which it will
start running.
Arduino Code 10.2 Rotating the DC motor in both directions. Available at Ori
gin/user-code/dcmotor/arduino/dcmotor-both/dcmotor-both.ino,
see Footnote 2 on page 2.
1 void s e t u p ( ) {
2 S e r i a l . begin (115200) ; // s e t t h e b a u d r a t e
10.3. Controlling the DC motor from Python 109
Arduino Code 10.3 Rotating the DC motor in both directions in a loop. Available
at Origin/user-code/dcmotor/arduino/dcmotor-loop/dcmotor-loop
.ino, see Footnote 2 on page 2.
1 int i ;
2 void s e t u p ( ) {
3 S e r i a l . begin (115200) ; // s e t t h e b a u d r a t e
4 pinMode ( 9 ,OUTPUT) ; / / u s e p i n s 9 and 1 0 for motor output
5 pinMode ( 1 0 ,OUTPUT) ;
6 f o r ( i = 0 ; i < 4 ; i ++){
7 analogWrite (9 , 100) ; // Motor r u n s a t a low s p e e d
8 analogWrite (10 , 0) ;
9 delay (3000) ; // 3 s e c o n d delay
10 analogWrite (9 , 0) ;
11 analogWrite (10 , 0) ; // Motor s t o p s f o r
12 delay (2000) ; // 1 s e c o n d s
13 analogWrite (9 , 0) ; //
14 analogWrite (10 , 100) ; // Motor r u n s i n t h e reverse direction for
15 delay (2000) ; // 2 s e c o n d s
16 analogWrite (9 , 0) ; // Stop t h e
17 analogWrite (10 , 0) ; // motor r o t a t i n g
18 delay (1000) ; // f o r 1 s e c o n d
19 }
20 }
21 void l o o p ( ) {
22 }
tioned earlier, the shield must be removed from the Arduino Uno and the Arduino
Uno needs to be connected to the computer with a USB cable, as shown in Fig. 2.4.
The reader should go through the instructions given in Sec. 3.2 before getting started.
Note: The readers are advised to affix a small (very lightweight) piece of paper at
the tip of the shaft of the DC motor. That will help them observe the direction of
rotation of the DC motor while running the experiments.
1. In the first experiment, we will learn how to drive the DC motor from Python.
The code for this experiment is given in Python Code 10.1. As explained earlier
in Sec. 4.4.1, we begin with importing necessary modules followed by setting
up the serial port. Next, the code has a command of the following form:
cmd_dcmotor_setup ( 1 , H−B r i d g e type , Motor number ,
PWM p i n 1 , PWM p i n 2 )
Here, we will pass the value 1 in Motor number. As mentioned earlier, for
each of the PWM pins on Arduino Uno board, the input can come from 8
bits. Thus, these pins can supply values between −255 and +255. Positive
values correspond to clockwise rotation while negative values correspond to
anti-clockwise rotation. Based on the PWM value and polarity, corresponding
analog voltage is generated. We put a PWM value of 100 to make the DC motor
run at an intermediate speed. As a result, the command cmd_dcmotor_run
becomes
10.3. Controlling the DC motor from Python 111
1 s e l f . obj_arduino . cmd_dcmotor_run ( 1 , 1 , 1 0 0 )
The above-mentioned command does not say for how long the motor should
run. This is taken care of by the sleep command, as given below:
1 sleep (3)
With this, the DC motor will run for or 3 seconds. At last, we release the DC
motor, as shown below:
1 s e l f . obj_arduino . cmd_dcmotor_release ( 1 , 1 )
With the execution of this command, the PWM functionality on the Arduino
Uno pins is ceased. This has the motor number as an input parameter. At
last, we close the serial port.
Note: If the sleep command (at line 29 of Python Code 10.1) were not
present, the DC motor will not even run: soon after putting the value 100,
the DC motor would be released, leaving no time in between. On the other
hand, if the DC motor is not released (i.e., line number 30 of Python Code 10.1
being commented), the DC motor will go on rotating. That’s why, it may be
inferred that line number 30 of Python Code 10.1 is mandatory for every pro-
gram. We encourage the readers to run Python Code 10.1 by commenting
any one or two of the lines numbered 29 and 30. Go ahead and do it - you
will not break anything. At the most, you may have to unplug the USB cable
connected to Arduino Uno and restart the whole thing from the beginning.
2. It is easy to make the DC motor run in the reverse direction by changing the
sign of PWM value being written. This is done in Python Code 10.2. In this
code, we make the DC motor run in one direction for 3 seconds and then make
it rotate in the reverse direction for 2 seconds. The rotation in reverse direction
is achieved by putting −100 in the command cmd_dcmotor_run, as shown
below:
1 s e l f . obj_arduino . cmd_dcmotor_run ( 1 , 1 , −100)
After adding a sleep of 2 seconds, we release the motor by issuing the com-
mand cmd_dcmotor_release, followed by closing the serial port:
1 s e l f . obj_arduino . cmd_dcmotor_release ( 1 , 1 )
3. Next, we make the DC motor run in forward and reverse directions, in a loop.
This is done through Python Code 10.3. We first write PWM +100 for 3
seconds. After that, halt the motor for 2 seconds by writing zero PWM value.
Next, make the motor rotate in the reverse direction by writing PWM −100 for
two seconds. Next, we make the motor stop for one second. This procedure is
put in a for loop which runs for 4 iterations. At last, we release the motor by
issuing the command cmd_dcmotor_release, followed by closing the serial
port
34 s e l f . obj_arduino . c l o s e _ s e r i a l ( )
35
36 d e f main ( ) :
37 obj_dcmotor = DCMOTOR_ROTATION( 1 1 5 2 0 0 )
38
39 i f __name__==’__main__ ’ :
40 main ( )
39 main ( )
Python Code 10.3 Rotating the DC motor in both directions in a loop. Available
at Origin/user-code/dcmotor/python/dcmotor-loop.py, see Footnote 2
on page 2.
1 import o s
2 import s y s
3 import o s
4 import s y s
5 cwd = o s . getcwd ( )
6 ( s e t p a t h , Examples ) = o s . path . s p l i t ( cwd )
7 s y s . path . append ( s e t p a t h )
8
9 from Arduino . Arduino import Arduino
10 from time import s l e e p
11
12 c l a s s DCMOTOR_ROTATION:
13 d e f __init__ ( s e l f , b a u d r a t e ) :
14 s e l f . baudrate = baudrate
15 s e l f . setup ()
16 s e l f . run ( )
17 s e l f . exit ()
18
19 def setup ( s e l f ) :
20 s e l f . obj_arduino = Arduino ( )
21 s e l f . p o r t = s e l f . obj_arduino . l o c a t e p o r t ( )
22 s e l f . obj_arduino . o p e n _ s e r i a l ( 1 , s e l f . port , s e l f . b a u d r a t e )
23
24 d e f run ( s e l f ) :
25 s e l f . pin1 = 9
26 s e l f . p i n 2 = 10
27 for i in range ( 4 ) :
28 s e l f . obj_arduino . cmd_dcmotor_setup ( 1 , 3 , 1 , s e l f . pin1 , s e l f . p i n 2 )
29 s e l f . obj_arduino . cmd_dcmotor_run ( 1 , 1 , 1 0 0 )
30 sleep (3)
31 s e l f . obj_arduino . cmd_dcmotor_run ( 1 , 1 , 0 )
32 sleep (2)
33 s e l f . obj_arduino . cmd_dcmotor_run ( 1 , 1 , −100)
34 sleep (2)
35 s e l f . obj_arduino . cmd_dcmotor_release ( 1 , 1 )
36
37 def exit ( s e l f ) :
38 s e l f . obj_arduino . c l o s e _ s e r i a l ( )
39
40 d e f main ( ) :
41 obj_dcmotor = DCMOTOR_ROTATION( 1 1 5 2 0 0 )
42
43 i f __name__== ’__main__ ’ :
10.3. Controlling the DC motor from Python 115
44 main ( )
116 10. Interfacing a DC Motor
Chapter 11
Implementation of Modbus
Protocol
In the previous chapters, we have discussed the programs to experiment with the
sensors and actuators that come with the shield, a DC motor, and a servomotor. One
may categorize these programs as either basic or intermediate. In this chapter, we
will learn one of the advanced applications that can be built using the toolbox. Recall
the FLOSS discussed in the book, by default, does not have the capability to connect
to Arduino. All such add-on functionalities are added to the FLOSS using toolboxes.
Beginners might want to skip this chapter in the first reading. This experiment
enables interfacing Modbus-based devices with the FLOSS-Arduino toolbox. This
functionality has a wide number of applications in the industrial sector.
11.1 Preliminaries
Modbus is an open serial communication protocol developed and published by Mod-
icon in 1979 [17] [18]. Because of ease of deployment and maintenance, it finds
wide applications in industries. The Modbus protocol provides a means to transmit
information over serial lines between several electronic devices to control and mon-
itor them. The controlling device requests for reading or writing information and
is known as the Modbus master/client. On the other hand, the device supplying
the information is called Modbus slave/server. All the slaves/servers have a unique
id and address. Typically, there is one master and a maximum of 247 slaves [19].
Fig. 11.1 shows a representation of Modbus protocol.
During the communication on a Modbus network, the protocol determines how
the controller gets to know its device address, recognizes the the message provided
and decides the action to be taken, and accordingly extracts data and information
118 11. Implementation of Modbus Protocol
Here, the voltage on one line equals to the inverse of the voltage on the other line.
In other words, the output is 1, if A - B > 200mV, and 0, if B - A > 200mV.
Fig. 11.3 shows the pins available on a typical RS485 module. As shown in Fig. 11.3,
there are four pins on each side of the module. Table 11.1 summarizes the usage of
these pins.
parameters through front panel keys. The reason behind using this energy meter is
the fact that it supports the Modbus RTU protocol for communication.
Multiple operations can be performed with devices supporting Modbus. Every
operation has its own fixed function code (coil status - 01, input status - 02, holding
registers - 03, input registers - 04, etc.), which is independent of devices. The function
code tells the slave which table to access and whether to read from or write to the
table. All the parameter values are stored in the output holding registers. Different
holding registers hold the values of different parameters. Table 11.2 summarizes
the various operations which Modbus RTU supports. One can locate the addresses
of individual parameters in the user manual for EM6400. Table 11.3 provides the
addresses for three individual parameters, which will be accessed in this chapter.
In Modbus protocol, the master needs to send a request packet (referred as RQ
hereafter) to the slave to read any of the slave’s parameters. When the slave receives
an RQ, it needs to come up with a response packet (referred as RP hereafter), which
contains the value requested by the master. In other words, an RQ is a message from
the master to a slave and an RP is a message from the slave back to the master. We
will first explain the structure of an RQ, followed by an example. An RQ consists of
the following fields:
1. Slave id: The first byte of every Modbus message is a slave id. The master
specifies the id of the slave to which the request message is addressed. Slaves
11.1. Preliminaries 121
Note: There are some online tools [20] by which one can calculate the CRC
bytes. However, one should note that the calculated CRC bytes should be men-
tioned in little-endian format, which means that the first register contains the
least significant bit (LSB) and the next register contains the most significant
bit (MSB).
Let us say, we want to access V1 (Voltage phase 1 to neutral) in the energy meter.
From Table 11.3, it may be noted that the address of V1 is 3927. The size of each
Modbus register is 16 bits and all EM6400 readings are of 32 bits. So, each reading
occupies two consecutive Modbus registers. Thus, we need to access two consective
holding registers (starting from 3926) to get V1. Table 11.4 summarizes the values
for the various fields in the RQ required to read/access V1. Now, we explain the
structure of an RP, followed by an example. An RP consists of following fields:
1. Slave id: In an RP, the slaves must specify their own id.
122 11. Implementation of Modbus Protocol
2. Function code: Like the RQ, the second byte of RP is the function code. This
code determines the type of operation to be performed by the slave. Table 11.2
enlists the various function codes.
3. Number of data bytes to follow: It refers to the total number of bytes read.
As our RQ has 2 registers each of two bytes, we expect a total of 4 bytes.
4. Data in the first requested register: It refers to the data stored in the first
register.
5. Data in the second requested register: It refers to the data stored in the second
register.
6. CRC bytes: As stated earlier, the last two bytes of every Modbus message
are CRC bytes. Like RQ, the receiving device also calculates the CRC and
compares it to the CRC from the sending device.
Let us consider the RP, which we have received as a response to the RQ mentioned
in Table 11.4. Table 11.5 summarizes the values for the various fields in this RP.
In this RP, we consider the data in the two requested registers to be 43732921 in
hexadecimal. The reason behind keeping the data in the second requested register
as the MSB is that the obtained values are being read in little-endian format. After
converting this value to floating point using the IEEE Standard for Floating-Point
Arithmetic (IEEE 754), we obtain the value as 243.16. Thus, the value of V1 (Voltage
phase 1 to neutral) in the energy meter is found to be 243.16 Volts.
11.1.2 Endianness
Most of the numeric values to be stored in the computer are more than one byte long.
Thus, there arises a question of how to store the multibyte values on the computer
machines where each byte has its own address i.e., which byte gets stored at the
“first” (lower) memory location and which bytes follow in higher memory locations.
11.1. Preliminaries 123
For example, let us picture this. A two-byte integer 0x5E5F is stored on the disk
by one machine, with the 0x5E (MSB) stored at the lower memory address and the
0x5F (LSB) stored at a higher memory address. But there is a different machine
that reads this integer by picking 0x5F for the MSB and 0x5E for the LSB, giving
0x5F5E. Hence, it results in a disagreement on the value of the integer between the
two machines. However, there is no so-called “right” ordering to store the bytes in
the case of multibyte quantities. Hardware is built to store the bytes in a particular
fashion, and as long as compatible hardware reads the bytes in the same fashion,
things are fine. Following are the two major types of storing the bytes:
For example, let us take a four-byte integer 0x436B84A3. Considering that the read
holding registers in Modbus protocol are 16-bits each, the LSB (or the little end) of
this integer is 0x84A3, and the MSB (or the big end) of this integer is 0x436B. Then,
the memory storage patterns for the integer would be like that shown in Table 11.6.
To represent the hexadecimal values of the read holding registers into user friendly
decimal (floating point) values, we follow IEEE 754 standard. Most common stan-
dards for representing floating point numbers are:
Figure 11.4: Block diagram for reading the parameters in energy meter
and the remaining 52 bits for mantissa. As the name indicates, this standard
is used where precision matters more.
There are several online converters [21] which peform the IEEE 754 floating point
conversion. In this chapter, a function has been formulated for this conversion,
wherever needed.
1. Arduino Uno has only one serial port. It communicates on the digital pins 0
and 1 as well as on the computer via USB. Since we want serial communication
which shouldn’t be disturbed by the USB port and the Serial Monitor, we use
the Software Serial library. Using this library, we can assign any digital pins
as RX and TX and use it for serial communication. In this experiment, pin
10 (used as RX) and pin 11 (used as TX) are connected to RO (Receive Out)
and DI (Data In) pins of the RS485 module respectively.
2. DE (Data Enable) and RE (Receive Enable) pins of RS 485 are shorted and
connected to digital pin 3 of the Arduino Uno board. This serves as a control
pin that will control when to receive and transmit serially.
11.3. Software required for this experiment 125
3. Vcc and GND of the RS485 module are connected to Vcc and GND of the
Arduino Uno board.
4. A and B pins of RS485 module are connected to A (Pin 7) and B (Pin 14) pins
of the energy meter. These two pins of the energy meter are meant for RS485
communication.
1. Firmware for Arduino Uno: This firmware is needed to communicate with the
FLOSS (using serial interface), and with RS485 module (using Software Serial
interface). Control logic to enable receive and transmit modes of MAX485 chip
is also present in this firmware. Fig. 11.6 demonstrates the overall implemen-
tation of this firmware. The firmware is provided in Sec. 11.3.1.
2. FLOSS code: This code requests the parameters in the energy meter by sending
an RQ to Arduino Uno from the FLOSS. Then it waits till an RP is available
126 11. Implementation of Modbus Protocol
from the Arduino Uno. After receiving the RP, it extracts the data from
this packet and converts it into IEEE 754 floating-point format. The overall
implementation is being described below:
11.4. Manifestation of Modbus protocol through Python 127
into how to acquire readings from the energy meter and interpret them accord-
ingly. As explained in Sec. 11.1.1, an energy meter is a device that gives us different
electrical parameters, including voltage, current, and power, consumed by a device.
Here, we aim to obtain these values using the Python-Arduino toolbox. For data
transmission, we have used an RS485 module.
Python is used for giving the required parameters to Arduino Uno. For example,
the user will tell the required slave address to be accessed and the number of registers
to be read from or written to. Here, Arduino Uno acts as a master and energy meter
as a slave. Therefore, referring to a particular slave address will refer to the registers
that hold the desired electrical parameters (current, voltage, power, etc.), which we
11.5. Reading the electrical parameters from Python 129
Note: The Python code files presented in this section were tested on the older
versions. Now, these codes may require minor changes in the newer versions. We
invite the experts to contribute the revised version of the code.
Python Code 11.2 Code for Single Phase Voltage Output. Available at Origin
/user-code/modbus/python, see Footnote 2 on page 2.
130 11. Implementation of Modbus Protocol
1 #! / u s r / b i n / python
2
3 import s e r i a l , time
4 import struct
5 import s y s
6
7 i f s e r i a l . S e r i a l ( ’COM2 ’ , 9 6 0 0 ) . isOpen ( ) :
8 s e r i a l . S e r i a l ( ’COM2 ’ , 9 6 0 0 ) . c l o s e ( )
9 s= s e r i a l . S e r i a l ( ’COM2 ’ , 9 6 0 0 )
10 #s . w r i t e ( "A" )
Python Code 11.3 Code for Single Phase Active Power Output. Available at Or
igin/user-code/modbus/python, see Footnote 2 on page 2.
1 #! / u s r / b i n / python
2
3 import s e r i a l , time
4 import struct
5 import s y s
6
7 i f s e r i a l . S e r i a l ( ’COM2 ’ , 9 6 0 0 ) . isOpen ( ) :
8 s e r i a l . S e r i a l ( ’COM2 ’ , 9 6 0 0 ) . c l o s e ( )
9 s= s e r i a l . S e r i a l ( ’COM2 ’ , 9 6 0 0 )
10 #s . w r i t e ( "A" )
Appendix A
One may need some or all of the components listed below to carry out the experiments
explained in the book:
1. Arduino Uno
We now provide an approximate cost of the above parts, mainly to keep a beginner
informed, see Table A.1. Because of the fluctuations in exchange rates, and the
availability issues, pricing could change considerably.
131
132 A. Procuring the Hardware
With the components and the Gerber file mentioned in Sec. 2.4, it should be
possible to create the PCB, and solder the components, so as to arrive at the shield,
as shown in Fig. 2.12. This is the least expensive option.
The readymade shield is also available on E-commerce websites like Amazon [22]
and Flipkart [23], in the name of Ecolight® Sensor Shield V-1.2 Compatible with
Arduino Uno R3.
Interested people may contact FLOSS-arduino@fossee.in or at +91 22 2576 4133.
References
133
134 References
[18] Paavni Shukla, Sonal Singh, Tanmayee Joshi, Sudhakar Kumar, Samrudha
Kelkar, Manas R. Das, and Kannan M. Moudgalya. Design and development of
a modbus automation system for industrial applications. In 2017 6th Interna-
tional Conference on Computer Applications In Electrical Engineering-Recent
Advances (CERA), pages 515–520, 2017.
[22] Ecolight® sensor shield v-1.2 compatible with arduino uno r3.
https://www.amazon.in/dp/B09G8BWDDD/. Seen on 8 Jan 2022.
[23] Ecolight sensor shield v-1.2 compatible with arduino uno educational electronic
hobby kit. https://www.flipkart.com/ecolight-sensor-shield-v-1-2-compatible-
arduino-uno-educational-electronic-hobby-kit/p/itm73d12ca9ae129. Seen on 8
Jan 2022.