the-complete-esp32-projects-guide-ebook (1)
the-complete-esp32-projects-guide-ebook (1)
Dogan Ibrahim
LEARN DESIGN SHARE
SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN
● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHA
N ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ●
SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIG
E ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHA
The Complete ESP32
Projects Guide
59 Experiments with
Arduino IDE and Python
Dogan Ibrahim
● All rights reserved. No part of this book may be reproduced in any material form, including
photocopying, or storing in any medium by electronic means and whether or not transiently or incidentally
to some other sue of this publication, without the written permission of the copyright holder except in
accordance with the provisions of the Copyright Designs and Patents Act 1988 or under the terms of a
licence issued by the Copyright Licencing Agency Ltd., 90 Tottenham Court Road, London, England W1P
9HE. Applications for the copyright holder's permission to reproduce any part of the publication should be
addressed to the publishers.
● Declaration
The author and publisher have used their best efforts in ensuring the correctness of the information provided
in this book. They do not assume, or hereby disclaim, any liability to any party for any loss or damage caused
by errors or omissions in this book, whether such errors or omissions result from negligence, accident or any
other cause.
● Acknowledgement
The authors would like to express their thanks to Espressif Systems for giving permission for the ESP32
related figures and tables to be included in this book.
● Disclaimer
The material in this publication is of the nature of general comment only, and does not represent
professional advice. It is not intended to provide specific guidance for particular circumstances and it should
not be relied on as the basis for any decision to take action or not take action on any matter which it covers.
Readers should obtain professional advice where appropriate, before making any such decision. To the
maximum extent permitted by law, the author and publisher disclaim all responsibility and liability to any
person, arising directly or indirectly from any person taking or not taking action based on the information in
this publication.
● ISBN 978-1-907920-75-2
Elektor is part of EIM, the world's leading source of essential technical information and electronics products for pro
engineers, electronics designers, and the companies seeking to engage them. Each day, our international team develops
and delivers high-quality content - via a variety of media channels (e.g., magazines, video, digital media, and social media)
in several languages - relating to electronics design and DIY electronics. www.elektor.com
Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
1.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
1.2.14 UART . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
1.2.23 Wi-Fi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
1.2.24 Bluetooth . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
1.4 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
●5
The Complete ESP32 Projects Guide
2.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
2.4 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
3.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
3.3 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Chapter 4 • Basic projects using the Arduino IDE and the ESP32 DevKitC . . . . . . . 47
4.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
4.2.1 Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
4.2.5 Construction. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
4.2.9 Suggestions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
4.3.1 Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
4.3.5 Construction. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
4.4.1 Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
●6
4.4.3 Block diagram: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
4.4.5 Construction. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
4.5.1 Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
4.5.5 Construction. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
4.5.9 Suggestions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
4.6.1 Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
4.6.5 Construction. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
4.6.10 Suggestions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
4.7.1 Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
4.7.5 Construction. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
●7
The Complete ESP32 Projects Guide
4.8.1 Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
4.8.5 Construction. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
4.9.1 Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
4.9.5 Construction. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
4.9.10 Suggestions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
4.10.1 Description. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
4.10.5 Construction. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
4.10.9 Suggestions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
●8
4.11.1 Description. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
4.11.5 Construction. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
4.11.9 Suggestion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
4.12.1 Description. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
4.12.5 Construction. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
4.12.9 Suggestions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
4.13.1 Description. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
4.14.1 Description. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
4.15.1 Description. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
●9
The Complete ESP32 Projects Guide
4.16 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC . . . . . . 94
5.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
5.2.1 Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
5.2.5 Construction. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
5.3.1 Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
● 10
5.5 PROJECT 4 – Darkness Reminder. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
● 11
The Complete ESP32 Projects Guide
● 12
5.12.1 Description. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
5.15 PROJECT 14 – Using the Touch Sensitive Inputs – Touch Based LED Control . . . . 156
● 13
The Complete ESP32 Projects Guide
5.16 PROJECT 15 – Using the Touch Sensitive Inputs – Changing the LED Brightness. . . 161
5.17 PROJECT 16 – Using Multiple Touch Sensitive Inputs – Electronic Organ . . . . . . . 163
5.18 PROJECT 17 – Using the SPI Bus – Digital to Analog Converter (DAC) . . . . . . . . 167
● 14
5.19.7 Program Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178
5.22 PROJECT 21 – Writing Floating Point Data to the Flash Memory . . . . . . . . . . . . . 183
5.23 PROJECT 22 – Reading Floating Point Data from the Flash Memory . . . . . . . . . . 185
● 15
The Complete ESP32 Projects Guide
Chapter 6 • Intermediate projects using the Arduino IDE and the ESP32 DevKitC . 187
● 16
6.5.4 Circuit Diagram . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
● 17
The Complete ESP32 Projects Guide
● 18
6.12.4 Circuit Diagram. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245
● 19
The Complete ESP32 Projects Guide
Chapter 7 • ESP32 DevKitC network programming using the Arduino IDE . . . . . . 276
● 20
9.2 The Block Diagram . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300
13.3 PROJECT 1 – Sending Data to Mobile Phone Using Bluetooth BLE. . . . . . . . . . . . 332
● 21
The Complete ESP32 Projects Guide
● 22
13.7.5 Program Listing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 351
● 23
The Complete ESP32 Projects Guide
● 24
Preface
Preface
Wi-Fi (or WiFi) networks are currently used nearly in all homes, offices, and public places in
developed countries to connect devices such as personal computers, smart mobile phones,
modern printers, and tablets to the internet. A wireless Access Point (AP) is used to provide
interconnection between all these devices. APs normally operate in the 2.4 GHz frequency
band and their ranges are limited to a maximum of 100 metres.
Microcontrollers are very popular electronic chips and are commonly used in many domes-
tic, commercial, and industrial electronic monitoring and control applications. It is estimat-
ed that there are more than 50 microcontrollers in every house in developed countries.
Some domestic equipments that have embedded microcontrollers are microwave ovens,
printers, keyboards, computers, tablets, washing machines, dish washers, smart televi-
sions, mobile phones, and many more.
A tiny chip called the ESP8266 has recently made it possible to interface any type of mi-
crocontroller to a Wi-Fi AP. The ESP8266 is a low-cost tiny Wi-Fi chip that has a full built-
in TCP/IP stack and a 32-bit microcontroller unit. This chip, produced by Shanghai based
Chinese manufacturer Espressif System is IEEE 802.11 b/g/n Wi-Fi compatible with on-chip
program and data memory, and general purpose input-output ports. Several manufactur-
ers have incorporated the ESP8266 chip in their hardware products (e.g. ESP-xx, NodeMCU
etc) and offer these products as a means of connecting a microcontroller system such as
the Android, PIC microcontroller or others to a Wi-Fi. The ESP8266 is a low-power chip and
costs only a few dollars.
In addition to their ESP8266 chip, the same company has recently developed a new mi-
crocontroller chip named the ESP32. This is big brother of the ESP8266 and can be used
in all projects that the ESP8266 is currently used. In addition to all the ESP8266 features,
the ESP32 provides Bluetooth communications capability, larger SRAM data memory, more
GPIOs, more interface signals, touch sensor, temperature sensor, higher CPU speed, CAN
bus connectivity, higher resolution ADC converters, DAC converters, and security features.
This book compliments the earlier book by the author, entitled "The Official ESP32 Book:
Discover All The Power" and is an advanced version of the earlier book. The book describes
main hardware and software features of the ESP32 chip and provides many projects using
these features. The main aim of the book is to teach how to use the ESP32 hardware and
software in practical projects, especially using the highly popular ESP32 development board
● 25
The Complete ESP32 Projects Guide
DevKitC. Many basic, simple, and intermediate level projects are given in the book are
based on the ESP32 DevKitC development board, using the highly popular Arduino IDE and
also the MicroPython programming language.
Attempt has been made by the author to cover all features of the ESP32 in projects. In
particular, the following features of the ESP32 processor are covered in projects in this ad-
vanced version of the book:
There is some level of overlap with the earlier ESP32 book of the author. Additionally, this
advanced version of the book makes an introduction to the native Espressif Systems ESP32
language ESP-IDF, and gives example projects using this powerful programming language
in projects. The projects have been organized in increasing levels of difficulty and the read-
ers are encouraged to read the projects in the given order.
A hardware kit is available from Elektor, especially prepared for the book. The kit contains
all the components used in the projects in this book. With the help of this hardware kit it
should be easy and fun to build the projects in the book.
● 26
Preface
We hope that you enjoy reading the book and at the same time learn how to use the ESP32
processor in your future projects.
Dogan Ibrahim
London, 2018
● 27
The Complete ESP32 Projects Guide
1 .1 Overview
The ESP8266 processor has been a highly popular processor costing less than $10 and it
is basically a Wi-Fi enabled microcontroller with GPIOs that can be used in small moni-
toring and control applications. The ESP8266 was developed by Shanghai based Chinese
manufacturer Espressif Systems and incorporates full TCP/IP stack. There is vast amount
of information, tutorials, data sheets, applications notes, books, and projects based on the
ESP8266. Several companies have created small development boards based on this proces-
sor, such as the ESP8266 Arduino and NodeMCU series.
Recently, Espressif has released a new and more powerful processor than the ESP8266,
called the ESP32. Although ESP32 has not been developed to replace the ESP8266, it im-
proves on it in many aspects. The new ESP32 processor not only has Wi-Fi support, but
it also has a Bluetooth communications module, enabling the processor to communicate
with Bluetooth compatible devices. The ESP32 CPU is the 32-bit Xtensa LX6, which is very
similar to the ESP8266 CPU, but in addition it has two cores, more data memory, more
GPIOs, higher CPU speed, ADC converters with higher resolution, DAC converter, and CAN
bus connectivity.
● 28
Chapter 1 • The ESP32 Processor
Table 1.1 shows a comparison of the basic features of ESP32 and ESP8266 processors.
GPIOs 36 17
Software PWM 16 8
CAN 1 None
● 29
The Complete ESP32 Projects Guide
Figure 1.2 shows the system structure, consisting of two core Harvard architecture CPUs
named PRO_CPU (for Protocol CPU) and APP_CPU (for Application CPU). The modules in the
middle of the two CPUs are common to both CPUs. Detailed information about the internal
architecture of the ESP32 can be obtained from the ESP32 Technical Reference Manual
(Espressif Systems, 2017). Some information about the internal modules are given below.
1 .2 .1 The CPU
The CPU can operate at up to 240 MHz and supports 7-stage pipelining with a 16/24-bit
instruction set. Floating Point Unit and DSP instructions such as 32-bit multiplier, 32-bit di-
vider, and 40-bit MAC are supported. Up to 70 external and internal interrupt sources with
32 interrupt vectors are available. Debugging can be done with the JTAG interface.
● 30
Chapter 1 • The ESP32 Processor
1 .2 .2 Internal Memory
520 KB SRAM and 448 KB ROM (for booting) are available on-chip. The Real Time Clock
module contains 8 KB slow memory and 8 KB fast memory. 1 Kbit of eFuse is available
with 256 bits used for the MAC address and chip configuration, and the remaining 768 bits
reserved for customer applications.
1 .2 .3 External Memory
Up to 4 x 16 MB external flash and SRAM memory that can be accessed through a high-
speed cache are supported. Up to 16 MB of the external flash are mapped onto the CPU
code space and up to 8 MB of the external flash/SRAM are mapped onto the CPU data
space. Although data read is supported both on the flash and SRAM, data writing is sup-
ported only on the SRAM.
1 .2 .5 Watchdog Timers
Three watchdog timers with programmable timeout values are available. Two watchdog
timers, called the main Watchdog Timers are inside the general purpose timers, while the
third one, called the RTC Watchdog Timer, is inside the RTC module. The actions taken when
a watchdog timer resets can be: interrupt, CPU reset, core reset, and system reset.
An 8 MHz accurate internal clock is also available. The programmer can either select the
external or the internal clock.
● 31
The Complete ESP32 Projects Guide
1 .2 .14 UART
Three UARTs with speeds up to 5 Mbps are provided for RS232, RS485 and IrDA serial
communications.
● 32
Chapter 1 • The ESP32 Processor
1 .2 .23 Wi-Fi
ESP32 includes a Wi-Fi module that can be used in projects to communicate with other
Wi-Fi devices, such as mobile phones, PCs, laptops and iPads, through a network router.
1 .2 .24 Bluetooth
A Bluetooth module is included on the ESP32 processor. With the help of this module we
can develop projects to communicate with other Bluetooth compatible devices, such as
mobile phones, PCs, iPads, and others.
● 33
The Complete ESP32 Projects Guide
• ESP32-EVB
• ESP32 Development Board by Pesky Products
• MakerHawk ESP32 Development Board
• Huzzah32 Development Board
• ESPea32
• NodeMCU-32s
• Node32S
• ESP32 DevKitC
1 .4 Summary
In this chapter we have briefly looked at the architecture of the ESP32 chip. Additionally, a
list of some of the popular ESP32 development boards are given in the chapter. The ESP32
DevKitC will be used as the development board in the remainder of this book.
In the next chapter we shall be looking at the hardware details of the ESP32 DevKitC and
also see how this development board can be used in ESP32 based projects.
● 34
Chapter 2 • ESP32 DevKitC Development Board
2 .1 Overview
In the last chapter we had a look at the architecture of the ESP32 processor and its basic
features and advantages. We have also listed some of the popular ESP32 development
boards available in the marketplace.
Currently, ESP32 DevKitC is one of the most popular development boards based on the
ESP32 processor. All projects in this book are based on this development board. It is there-
fore important that we learn the architecture and the features of this board in detail.
In this chapter we shall be looking at the features of the ESP32 DevKitC development board
in greater detail.
The board has two connectors located along each side of the board for GPIO, clock, and
power line interfaces. Each connector has 19 pins. As shown in Figure 2.2, the two connec-
tors carry the following signals:
● 35
The Complete ESP32 Projects Guide
IO33 IO19
IO25 IO18
IO26 IO5
IO27 IO17
IO14 IO16
IO12 IO4
GND IO0
IO13 IO2
SD2 IO15
SD3 SD1
CMD SD0
+5V CLK
The board has a mini USB connector for connecting it to a PC. The board also receives its
power from the USB port. Standard +5 V from the USB port is converted into +3.3 V on
the board. In addition, two buttons are provided on the board named EN and BOOT, having
the following functions:
● 36
Chapter 2 • ESP32 DevKitC Development Board
EN: This is the reset button where pressing this button resets the board
BOOT: This is the download button. The board is normally in operation mode where the
button is not pressed. Pressing and holding down this button and at the same time pressing
the EN button starts the firmware download mode where firmware can be downloaded to
the processor through the USB serial port.
The pins on the ESP32 DevKitC board have multiple functions. Figure 2.3 shows the func-
tions of each pin. For example, pin 10 is shared with functions GPIO port 26, DAC channel
2, ADC channel 19, RTC channel 7, and RX01.
Note that GPIO34, GPIO35, GPIO36, GPIO37, GPIO38 and GPIO39 ports are input only
and cannot be used as output ports (GPIO37 and GPIO38 are not available on the ESP32
board).
The board operates with a typical power supply of +3.3 V, although the absolute maximum
is specified as +3.6 V. It is recommended that the current capacity of each pin should not
exceed 6 mA, although the absolute maximum current capacity is specified as 12 mA. It
is therefore important to use current limiting resistors while driving external loads such as
LEDs.
Depending upon the configuration the RF power consumption during reception is around 80
mA and it can be in excess of 200 mA during a transmission.
● 37
The Complete ESP32 Projects Guide
ESP32 DevKitC is preloaded with firmware that can be used to test the board. This firmware
is activated by default when power is applied to the board. Before communicating with the
board, we have to run a terminal emulation software on our PC. There are several terminal
emulation software available free of charge. Some examples are HyperTerm, Putty, X-CTU
and so on. In this book we shall be using the Putty.
Putty is a popular terminal emulation program that runs on the PC. The program is availa-
ble on the following website:
www.putty.org
The steps to start communication with the ESP32 DevKitC board are given below:
• Connect your ESP32 DevKitC to one of the USB ports of your PC. You should see
the red LED on the board to turn on to indicate that power is applied to the board
• Find out the serial port number assigned to the USB port. This can be found from
a display of the Hardware Manager as shown in Figure 2.4. In this example the
required port number is COM47.
● 38
Chapter 2 • ESP32 DevKitC Development Board
• In addition, you may like to make the following configuration settings in Putty to
make the display more readable. Click Colours under Window in the left pane
and then:
• In addition, the font size can be increased if desired. Click on Appearance under
Windows in the left pane and then click to change the font to 12 points, bold.
• Click on Session in the left pane and give a name to your session. e.g. ESP32
and click Save to save your configuration.
You should now reset your ESP32 DevKitC board by pressing the reset button (the button
on the bottom left). The board will reset and will send messages to your terminal similar to
the ones shown in Figure 2.6 (only part of the display is shown here).
● 39
The Complete ESP32 Projects Guide
If you do not see anything on your display then you should check the connection between
the ESP32 DevKitC board and your PC. Also make sure that the correct port number and
communication speed are selected in Putty.
2 .4 Summary
In this chapter we have seen the basic features and pin layout of the ESP32 DevKitC hard-
ware development board.
In the next chapter we shall be learning how to program the ESP32 processor using the
Arduino IDE, and also how to upload an executable code to the ESP32 processor.
● 40
Chapter 3 • Arduino IDE for the ESP32 DevKitC
3 .1 Overview
By default, the ESP32 DevKitC is distributed with no programming firmware installed. It is
therefore necessary to install a programming language firmware on the processor so that
user programs can be developed and uploaded to the processor. Just like the ESP8266, the
ESP32 processor is compatible with various programming languages such as C, MicroPy-
thon and so on.
Arduino IDE is one of the most commonly used development environments for micro-
controllers, especially for the Arduino family of microcontrollers. This IDE is easy to use,
supports many microcontrollers, and includes a very rich library of functions that make
the programming easier. Most electrical/electronic engineering students and people whose
hobby is electronics are familiar with using the Arduino IDE. In this section we shall be see-
ing how to install the ESP32 processor into the Arduino IDE on a Windows PC.
Several simple projects are given in the next chapter on using the ESP32 DevKitC board
with the Arduino IDE. It is important to note that using the Arduino IDE has some limi-
tations and not all features of the ESP32 can be programmed with this IDE. We shall be
seeing in future chapters how to install and create the ESP-IDF development environment
which is the framework developed and supported by Espressif for the ESP32 processors.
Although using the ESP-IDF may be more complex than the Arduino IDE programming, it
has the advantage that it enables the programmer to access all the features of the ESP32
processor.
• Download and install the latest version of Arduino IDE from the following web
site:
https://www.arduino.cc/en/Main/Software
• Open your Arduino IDE and click File -> Preferences to open the Preferences win-
dow. Locate text box Additional Board Manager URLs at the bottom of the win-
dow and enter the following text as shown in Figure 3.1. If the text box contains
another URL, add the new URL after separating it with a comma:
https://dl.espressif.com/dl/package_esp32_index.json
● 41
The Complete ESP32 Projects Guide
• Click OK
• Click Tools -> Boards -> Board Managers window and search for ESP32 as
shown in Figure 3.2.
• Click Install button. You should see the Installed message as shown in Figure
3.3. Close the window.
● 42
Chapter 3 • Arduino IDE for the ESP32 DevKitC
• We should now test the installation to make sure that all the necessary files have
been loaded. We shall make use of one of the supplied example applications to
make sure that our program can be uploaded to the ESP32 processor and is
working correctly
• Plug in your ESP32 DevKitC to your PC and start the Arduino IDE
• Select Tools -> Board ->ESP32 Dev Module as shown in Figure 3.4.
• Select the serial port number. In this example this is COM47 as shown in Figure
3.5
● 43
The Complete ESP32 Projects Guide
• Open the example program in File -> Examples -> WiFi (in ESP32) ->WiFi
Scan as shown in Figure 3.6
● 44
Chapter 3 • Arduino IDE for the ESP32 DevKitC
• Now, we will upload the program to our ESP 32 DevKitC. First of all we have to
put the device into firmware upload mode. Press and hold the BOOT button (the
one on the right hand side). Press the Sketch -> Upload button in Arduino IDE
to compile and upload your program to the ESP32 DevKitC. Wait until finished.
After a successful process you should see a screen similar to the one shown in
Figure 3.8 Release the BOOT button at the end of uploading.
Now, open the Arduino IDE Serial monitor by clicking Tools -> Serial Monitor. Make sure
that the communication baud rate is set to 115200. You should see a list of the access
points close to you as shown in Figure 3.9. The list is updated every 5 seconds.
At this point we have successfully installed the ESP32 processor into our Arduino IDE.
● 45
The Complete ESP32 Projects Guide
3 .3 Summary
In this chapter we have seen how to install the ESP32 processor into the Arduino IDE so
that we can develop programs using the Arduino IDE and then upload them to our ESP32
DevKitC.
In the next chapter we shall be developing simple projects using the ESP32 DevKitC devel-
opment board with the Arduino IDE.
● 46
Chapter 4 • Basic projects using the Arduino IDE and the ESP32 DevKitC
4 .1 Overview
In the last chapter we have seen how to update the Arduino IDE so that the programs
developed using this IDE can be compiled and downloaded to the ESP32 DevKitC develop-
ment board.
In this chapter we will be developing basic projects using the Arduino IDE as the Integrated
Development Environment, and then compile and download these projects to our ESP32
DevKitC. Notice that all the project given in this book have been tested and are working.
The following sub-headings will be used for each project so that the projects can be de-
scribed fully:
• Project title
• Project description
• Aim of the project
• Project block diagram
• Project circuit diagram
• Project construction
• Project operation (PDL)
• Project program listing
• Description of the program
• Additional work (optional)
The operation of the projects will be described using the Program Description Language
(PDL). This is a free format English like description of the operation of a program using
keywords such as BEGIN, END, IF, THEN, ELSE, ENDIF, WHILE, REPEAT, DO, DO FOREVER,
ENDDO and so on. PDLs are preferred to Flow Charts as they consists of simple texts and
do not have any graphics. Also, using PDLs create structured programs without any goto
statements.
4 .2 .1 Description
In this project an LED is connected to GPIO port 23 of the ESP32 DevKitC. The LED is
flashed every second.
4 .2 .2 The Aim
The aim of this project is to show how an LED can be connected to a GPIO port and how it
can be turned on and off.
● 47
The Complete ESP32 Projects Guide
4 .2 .3 Block diagram
Figure 4.1 shows the block diagram of the project.
Figure 4.2 Top right hand side ESP32 DevKitC pin configuration
● 48
Chapter 4 • Basic projects using the Arduino IDE and the ESP32 DevKitC
4 .2 .5 Construction
The ESP32 DevKitC board is mounted on a breadboard as shown in Figure 4.4. The LED is
connected to the board through a current limiting resistor.
● 49
The Complete ESP32 Projects Guide
BEGIN
Assign LED to port pin GPIO23
Configure port pin GPIO23 as output
DO FOREVER
Set LED HIGH
Wait 1 second
Set LED LOW
Wait 1 second
ENDDO
END
4 .2 .7 Program Listing
The program listing of the project is very simple and is shown in Figure 4.6 (program:
FlashLED).
/****************************************************************
* FLASHING LED
* ============
*
* In this program an LED is connected to port GPIO23 of the
* ESP32 DevKitC. The program flashes the LED every second
*
* Program: FlashLED
* Date : July, 2017
**************************************************************/
#define LED 23
void setup()
{
pinMode(LED, OUTPUT);
}
void loop()
{
digitalWrite(LED, HIGH);
delay(1000);
digitalWrite(LED, LOW);
delay(1000);
}
Figure 4.6 Program listing
● 50
Chapter 4 • Basic projects using the Arduino IDE and the ESP32 DevKitC
4 .2 .8 Program Description
At the beginning of the program variable name LED is assigned to GPIO port 23. Then the
LED port is configured as an output port. The main program is run continuously in a loop,
where inside this loop the LED is turned ON (HIGH) and OFF (LOW) with one second delay
between each output.
Remember that you should press and hold the BOOT button on the ESP32 DevKitC during
the program compile and download process.
4 .2 .9 Suggestions
Modify the program in Figure 4.6 so that the LED ON time is 2 seconds and the OFF time
is 5 seconds.
4 .3 .1 Description
In this project an LED is connected to GPIO port 23 of the ESP32 DevKitC as in Project 1.
The LED is flashed in a group of two quick flashes every second. The flashing rate is as-
sumed to be 200 ms. This type of flashing is identified as GpFl(2) in maritime lighthouse
lights. Thus, the required flashing sequence can be expressed as follows:
LED ON
Wait 200 ms
LED OFF
Wait 100 ms
LED ON
Wait 200 ms
LED OFF
Wait 100 ms
Wait 400 ms
4 .3 .2 The Aim
The aim of this project is to show how an LED can be connected to a GPIO port and how it
can be turned on and off at different rates.
4 .3 .3 Block diagram:
The block diagram of the project is as in Figure 4.1.
4 .3 .4 Circuit Diagram
The circuit diagram of the project is as in Figure 4.3.
4 .3 .5 Construction
The LED is connected to the ESP32 DevKitC board through the current limiting resistor as
in Figure 4.4.
● 51
The Complete ESP32 Projects Guide
BEGIN
Assign LED to port pin GPIO23
Configure port pin GPIO23 as output
DO FOREVER
Set LED HIGH
Wait 200 ms
Set LED LOW
Wait 100 ms
Set LED HIGH
Wait 200 ms
Set LED LOW
Wait 100 ms
Wait 400 ms
ENDDO
END
Figure 4.7 PDL of the project
4 .3 .7 Program Listing
The program listing of the project is very simple and is shown in Figure 4.8 (program:
Lighthouse).
/****************************************************************
* LIGHHOUSE FLASHING LED
* ======================
*
* In this program an LED is connected to port GPIO23 of the
* ESP32 DevKitC. The program flashes the LED with the lighthouse
* lighting sequence GpFl(2)
*
* Program: Lighthouse
* Date : July, 2017
**************************************************************/
#define LED 23
#define ON HIGH
#define OFF LOW
void setup()
{
pinMode(LED, OUTPUT);
}
void loop()
● 52
Chapter 4 • Basic projects using the Arduino IDE and the ESP32 DevKitC
{
digitalWrite(LED, ON);
delay(200);
digitalWrite(LED, OFF);
delay(100);
digitalWrite(LED, ON);
delay(200);
digitalWrite(LED, OFF);
delay(100);
delay(400);
}
Figure 4.8 Program listing
4 .3 .8 Program Description
At the beginning of the program variable name LED is assigned to GPIO port 23 as in Pro-
ject 1. Then the LED port is configured as an output port. The main program is run contin-
uously in a loop, in which the LED is turned ON (HIGH) and OFF (LOW) as specified in the
lighthouse sequence GpFl(2).
4 .4 .1 Description
In this project two LEDs are connected to GPIO ports 22 and 23 of the ESP32 DevKitC.
4 .4 .2 The Aim
The aim of this project is to show how LEDs can be connected to a GPIO port and how they
can be turned on and off alternately.
4 .4 .3 Block diagram:
The block diagram of the project is shown in Figure 4.9. LED1 is connected to GPIO port 22
and LED2 to GPIO port 23.
4 .4 .4 Circuit Diagram
The circuit diagram of the project is shown in Figure 4.10. The LEDs are connected to the
port pins through 330 ohm current limiting resistors. See Figure 4.2 for pin configuration
of ESP32 DevKitC.
● 53
The Complete ESP32 Projects Guide
4 .4 .5 Construction
A breadboard is used to construct the project. The LEDs are connected to the ESP32 DevKitC
through the current limiting resistors as shown in Figure 4.11.
● 54
Chapter 4 • Basic projects using the Arduino IDE and the ESP32 DevKitC
BEGIN
Assign LED1 to port pin GPIO22
Assign LED2 to port pin GPIO23
Configure port pins GPIO22 and GPIO23 as outputs
DO FOREVER
Set LED1 HIGH
Set LED2 LOW
Wait 1 second
Set LED1 LOW
Set LED2 HIGH
Wait 1 second
ENDDO
END
Figure 4.12 PDL of the project
4 .4 .7 Program Listing
The program listing of the project is very simple and is shown in Figure 4.13 (program:
Altflash).
/****************************************************************
* ALTERNATE FLASHING LEDs
* =======================
*
* In this program two LEDs are connected to port GPIO22 and
* GPIO23 of the ESP32 DevKitC. The program flashes the LEDs
* alternately with one second delay between each output
*
* Program: Altflash
* Date : July, 2017
**************************************************************/
#define LED1 22
#define LED2 23
#define ON HIGH
#define OFF LOW
void setup()
{
pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
}
● 55
The Complete ESP32 Projects Guide
void loop()
{
digitalWrite(LED1, HIGH);
digitalWrite(LED2, LOW);
delay(1000);
digitalWrite(LED1, LOW);
digitalWrite(LED2, HIGH);
delay(1000);
}
Figure 4.13 Program listing
4 .4 .8 Program Description
At the beginning of the program variable names LED1 and LED2 are assigned to GPIO port
22 and 23 respectively. Then the port pins are configured outputs. The main program is run
continuously in a loop, in which LED1 and LED2 are turned ON and OFF alternately with one
second delay between each output.
4 .5 .1 Description
In this project four LEDs are connected to GPIO ports 23, 22, 1, and 3 (as shown in Fig-
ure 4.2, these port pins are next to each other). The LEDs are turned ON/OFF in a rotating
manner where only one LED is ON at any given time. i.e. the required LED pattern is as
follows:
The LED ON and OFF times are to be chosen as 500 ms and 100 ms respectively.
4 .5 .2 The Aim
The aim of this project is to show how an array and a for loop can be used in a program to
control multiple devices (LEDs) connected to the GPIOs.
● 56
Chapter 4 • Basic projects using the Arduino IDE and the ESP32 DevKitC
4 .5 .3 Block diagram:
The block diagram of the project is shown in Figure 4.15. LED1 to LED4 are connected to
GPIO ports 23, 22, 1 and 3 respectively.
4 .5 .4 Circuit Diagram
The circuit diagram of the project is shown in Figure 4.16. The LEDs are connected to the
port pins through 330 ohm current limiting resistors (see Figure 4.2 for the ESP32 DevKitC
pin configuration)
4 .5 .5 Construction
A breadboard is used to construct the project. The LEDs are connected to the ESP32 DevKitC
through the current limiting resistors as shown in Figure 4.17.
● 57
The Complete ESP32 Projects Guide
BEGIN
Store LED port numbers in array LEDs
Configure LED port pins as outputs and turn OFF the LEDs
DO FOREVER
DO FOR J = 0 TO 3
Turn ON LED indexed by LEDs[J]
Wait 500 ms
Turn OFF LED indexed by LEDs[J]
Wait 100 ms
ENDDO
ENDDO
END
Figure 4.18 PDL of the project
● 58
Chapter 4 • Basic projects using the Arduino IDE and the ESP32 DevKitC
4 .5 .7 Program Listing
The program listing of the project is very simple and is shown in Figure 4.19 (program:
RotateLEDs).
/****************************************************************
* ROTATING LEDs
* =============
*
* In this program four LEDs are connected to port GPIO23,
* GPIO22, GPIO1, and GPIO3 and of the ESP32 Devkitc. The
* program turns ON the LEDs in a rotating pattern. The ON
* and OFF times are chosen as 500 ms and 100 ms so that a
* nice rotating effect is displayed
*
* Program: RotateLEDs
* Date : July, 2017
**************************************************************/
int LEDs[] = {23, 22, 1, 3};
#define ON HIGH
#define OFF LOW
//
// Set GPIO pins 23,22,1,3 as outputs and turn OFF the LEDs
// to start with
//
void setup()
{
unsigned char i;
for(i=0; i <=3; i++)
{
pinMode(LEDs[i], OUTPUT);
digitalWrite(LEDs[i], OFF);
}
}
//
// Turn ON/OFF the LEDs in a rotating pattern
//
void loop()
{
unsigned char j;
for(j = 0; j <=3; j++)
{
digitalWrite(LEDs[j], ON);
● 59
The Complete ESP32 Projects Guide
delay(500);
digitalWrite(LEDs[j], OFF);
delay(100);
}
}
Figure 4.19 Program listing
4 .5 .8 Program Description
At the beginning of the program an array called LEDs is set up to store the port numbers
of the LEDs used in the project. Then, the GPIO ports that the LEDs are connected to are
configured as output ports and the LEDs are turned OFF to start with. Inside the main pro-
gram a for loop is set up to turn ON/OFF the LEDs connected to ports 23, 22, 1 and 3 in
that order. The ON and OFF times are chosen as 500 ms and 100 ms so that a nice rotating
LED effect is displayed.
4 .5 .9 Suggestions
You should increase the LED number to 8 and modify program 4.19 accordingly.
4 .6 .1 Description
In this project 4 LEDs are connected to the ESP32 DevKitC as in the previous project. The
LEDs are turned ON and OFF randomly every second.
4 .6 .2 The Aim
The aim of this project is to show how the random number generator function can be used
in a program.
4 .6 .3 Block diagram:
The block diagram of the project is as in Figure 4.15.
4 .6 .4 Circuit Diagram
The circuit diagram of the project is as in Figure 4.16.
4 .6 .5 Construction
The project is built on a breadboard as shown in Figure 4.17.
BEGIN/Main
Store LED port numbers in array LEDs
Configure LED port pins as outputs
DO FOREVER
Generate a random number between 1 and 15
Call Display with the number to turn ON the appropriate LED
● 60
Chapter 4 • Basic projects using the Arduino IDE and the ESP32 DevKitC
Wait 1 second
ENDDO
END/Main
BEGIN/Display
Extract bit 3 of the number
IF bit = 1 THEN
Turn ON LED1
ELSE
Turn OFF LED1
ENDIF
Extract bit 2 of the number
IF bit = 1 THEN
Turn ON LED2
ELSE
Turn OFF LED2
ENDIF
Extract bit 1 of the number
IF bit = 1 THEN
Turn ON LED3
ELSE
Turn OFF LED3
ENDIF
Extract bit 0 of the number
IF bit = 1 THEN
Turn ON LED4
ELSE
Turn OFF LED4
ENDIF
END/Display
4 .6 .7 Program Listing
The program listing of the project is very simple and is shown in Figure 4.21 (program:
Christmas).
/****************************************************************
* CHRISTMAS LIGHTS
* ================
*
* In this program four LEDs are connected to port GPIO23,
* GPIO22, GPIO1, and GPIO3 and of the ESP32 DevKitC. The
* program turns ON the LEDs in a random manner every second
* to give the effect of for example Christmas lights
● 61
The Complete ESP32 Projects Guide
*
* Program: Christmas
* Date : July, 2017
**************************************************************/
int LEDs[] = {23, 22, 1, 3};
unsigned char Ran;
//
// Set GPIO pins 23,22,1,3 as outputs
//
void setup()
{
unsigned char i;
for(i=0; i <=3; i++)
{
pinMode(LEDs[i], OUTPUT);
}
randomSeed(10);
}
//
// Turn ON the appropriate LED
//
void Display(unsigned char No)
{
digitalWrite(23,(No & B00001000));
digitalWrite(22,(No & B00000100));
digitalWrite(1, (No & B00000010));
digitalWrite(3, (No & B00000001));
}
//
// Turn ON/OFF the LEDs randomly by generating a random number
// between 1 and 15
//
void loop()
{
Ran = random(1, 16);
Display(Ran);
delay(1000);
}
Figure 4.21 Program listing
● 62
Chapter 4 • Basic projects using the Arduino IDE and the ESP32 DevKitC
4 .6 .8 Program Description
At the beginning of the program an array called LEDs is set up to store the port numbers
of the LEDs used in the project. Then, the GPIO ports that the LEDs are connected to are
configured as output ports. Function randomSeed is called with an integer number to start
the random number generator. Inside the main program a random number is generated
between 1 and 15 (notice that the random function includes the lower bound, but excludes
the upper bound). Then, function Display is called to extract the bits of this number and to
turn ON or OFF the appropriate LED. Function Display receives an integer number between
1 and 15 and extracts the bits of this number. For example, if the number is 12 (binary
1100) then the left two LEDs (LED1 and LED2) are turned ON.
4 .6 .9 Modified Program
The program given in Figure 4.21 can be made more efficient by modifying the function
Display. The new program listing is shown in Figure 4.22 (program: Christmas2). Here,
function Display has two arguments: No is the number to be displayed as a binary bit
pattern on the LEDs, and L is the width of the number in bits. Bits are extracted from the
number and are sent to the LEDs to turn ON/OFF the correct LED. The program runs in
an endless loop, where a random number is generated between 1 and 15 and stored in
variable Ran. Function Display is then called as Display(Ran, 4) to turn ON/OFF the
appropriate LEDs. Notice that here the width of the number is 4-bits (there are 4 LEDs).
/****************************************************************
* CHRISTMAS LIGHTS
* ================
*
* In this program four LEDs are connected to port GPIO23,
* GPIO22, GPIO1, and GPIO3 and of the ESP32 DevKitC. The
* program turns ON the LEDs in a random manner every second
* to give the effect of for example Christmas lights.
*
* In this modified program function Display is modified and
* the program is more efficient and easier to maintain
*
* Program: Christmas2
* Date : July, 2017
**************************************************************/
int LEDs[] = {23, 22, 1, 3};
unsigned char Ran;
//
// Set GPIO pins 23,22,1,3 as outputs
//
void setup()
{
unsigned char i;
for(i=0; i <=3; i++)
● 63
The Complete ESP32 Projects Guide
{
pinMode(LEDs[i], OUTPUT);
}
randomSeed(10);
}
//
// Turn ON the appropriate LED
//
void Display(unsigned char No, unsigned char L)
{
unsigned char j, m, i;
m = L - 1;
for(i = 0; i < L; i++)
{
j = pow(2, m);
digitalWrite(LEDs[i], (No & j));
m--;
}
}
//
// Turn ON/OFF the LEDs randomly by generating a random number
// between 1 and 15
//
void loop()
{
Ran = random(1, 15);
Display(Ran, 4);
delay(1000);
}
Figure 4.22 Modified program
4 .6 .10 Suggestions
The number of LEDs can be increased by connecting more in series and in parallel and
placed for example on a Christmas tree.
4 .7 .1 Description
In this project 8 LEDs are connected to the ESP32 DevKitC. The program counts up from 0
to 255 where the count is displayed on the 8 LEDs in binary format.
● 64
Chapter 4 • Basic projects using the Arduino IDE and the ESP32 DevKitC
4 .7 .2 The Aim
The aim of this project is to show how any 8 port pins can be grouped together and treated
like an 8-bit output port.
4 .7 .3 Block diagram:
The block diagram of the project is shown in Figure 4.23. The LEDs are connected to the
following GPIO port pins (see ESP32 DevKitC pin configuration in Figure 4.2):
23 (MSB)
22
1
3
21
19
18
5 (LSB)
4 .7 .4 Circuit Diagram
The circuit diagram of the project is shown in Figure 4.24. 8 LEDs are connected to the
GPIO ports through 330 ohm current limiting resistors.
● 65
The Complete ESP32 Projects Guide
4 .7 .5 Construction
The project is built on a breadboard as shown in Figure 4.25.
BEGIN/Main
Store LED port numbers in array LEDs
Configure LED port pins as outputs
Set Count to 0
DO FOREVER
Call Display with Count and 8 (width) as the arguments
Increment Count
Wait 1 second
ENDDO
END/Main
BEGIN/Display
Extract bits of the number and send to appropriate GPIO pins
END/Display
● 66
Chapter 4 • Basic projects using the Arduino IDE and the ESP32 DevKitC
4 .7 .7 Program Listing
The program listing of the project is very simple and is shown in Figure 4.27 (program:
Counter).
/****************************************************************
* BINARY UP COUNTER
* ==================
*
* In this program 8 LEDs are connected to port pins GPIO23,
* GPIO22, GPIO1, GPIO3, GPIO21, GPIO19, GPIO18, and GPIO5
* of the ESP32 DevKitC. The program counts up by one and
* sends the count to he GPIO pins to turn ON/OFF the
* appropriate LEDs so that the LEDs count up by one in binary.
* One second delay is inserted between each output
*
*
* Program: Counter
* Date : July, 2017
**************************************************************/
int LEDs[] = {23, 22, 1, 3, 21, 19, 18, 5};
unsigned char Count = 0;
//
// Set GPIO pins 23,22,1,3,21,19,18,5 as outputs
//
void setup()
{
unsigned char i;
for(i=0; i < 8; i++)
{
pinMode(LEDs[i], OUTPUT);
}
}
//
// Turn ON the appropriate LED
//
void Display(unsigned char No, unsigned char L)
{
unsigned char j, m, i;
m = L - 1;
for(i = 0; i < L; i++)
{
j = pow(2, m);
digitalWrite(LEDs[i], (No & j));
● 67
The Complete ESP32 Projects Guide
m--;
}
}
//
// Increment Count every second and send Count to GPIO
// pins. Notice that the width is 8-bits (i.e. there are
// 8 LEDs)
//
void loop()
{
Display(Count, 8);
if(Count == 255)
Count = 0;
else
Count++;
delay(1000);
}
Figure 4.27 Program listing
4 .7 .8 Program Description
At the beginning of the program an array called LEDs is set up to store the port numbers
of the LEDs used in the project. Global variable Count is initialised to zero. Then, the GPIO
ports where the LEDs are connected to are configured as output ports. Inside the main pro-
gram function Display is called and Count is sent as the argument. This function extracts
the bits of Count and turns ON/OFF the appropriate LEDs. Number 8 is also sent to function
Display as an argument since there are 8 LEDs (i.e. the width of the number is 8 bits). The
LEDs count up in binary from 0 to 255 continuously with one second delay between each
count. You should see the pattern shown in Figure 4.28 on the LEDs.
● 68
Chapter 4 • Basic projects using the Arduino IDE and the ESP32 DevKitC
4 .8 .1 Description
In this project 8 LEDs are connected to the ESP32 DevKitC as in the previous project. In
addition a push-button switch (or simply a button) is connected to GPIO pin 17. When
the button is not pressed the program counts up, and when the button is held pressed the
program counts down.
4 .8 .2 The Aim
The aim of this project is to show how a push-button switch can be connected to an ESP32
DevKitC GPIO port and how the port can be configured as an input.
4 .8 .3 Block diagram:
The block diagram of the project is shown in Figure 4.29. The LEDs are connected to the
following GPIO port pins (see ESP32 DevKitC pin configuration in Figure 4.2):
23 (MSB)
22
1
3
21
19
18
5 (LSB)
4 .8 .4 Circuit Diagram
The circuit diagram of the project is as in Figure 4.30. 8 LEDs are connected to the GPIO
ports through 330 ohm current limiting resistors. Notice that the button can be connected
in two different ways to a GPIO port. In Figure 4.31, the output of the button is at logic 1
and goes to logic 0 when the button is pressed. In figure 4.32, the output of the button goes
from logic 0 to logic 1 when the button is pressed. In this example the second method is
used. Thus, GPIO pin is normally at logic 0 and goes to logic 1 when the button is pressed.
● 69
The Complete ESP32 Projects Guide
4 .8 .5 Construction
The project is built on a breadboard as shown in Figure 4.33.
● 70
Chapter 4 • Basic projects using the Arduino IDE and the ESP32 DevKitC
BEGIN/Main
Store LED port numbers in array LEDs
Configure LED port pins as outputs
Set Count to 0
DO FOREVER
Call Display with Count and 8 (width) as the arguments
IF Button not pressed THEN
Increment Count
ELSE IF Button is pressed THEN
Decrement Count
ENDIF
Wait 1 second
ENDDO
END/Main
BEGIN/Display
Extract bits of the number and send to appropriate GPIO pins
END/Display
● 71
The Complete ESP32 Projects Guide
4 .8 .7 Program Listing
The program listing of the project is very simple and is shown in Figure 4.35 (program:
UpDown).
/****************************************************************
* BINARY UP/DOWN COUNTER
* ======================
*
* In this program 8 LEDs are connected to port pins GPIO23,
* GPIO22, GPIO1, GPIO3, GPIO21, GPIO19, GPIO18, and GPIO5
* of the ESP32 DevKitC. In addition, a push-button switch
* is conencted to port pin 17. Normally the switch output is
* at logic 0 and when the switch is pressed its output goes
* to logic 1. The program normally counts up. When the switch
* is pressed and held down then the program starts to count
* down from its last value. The appropriate LEDs are turned
* ON/OFF
*
*
* Program: UpDown
* Date : July, 2017
**************************************************************/
#define Button 17
#define UP 0
#define DOWN 1
int LEDs[] = {23, 22, 1, 3, 21, 19, 18, 5};
unsigned char Count = 0;
unsigned char Button_State;
//
// Set GPIO pins 23,22,1,3,21,19,18,5 as outputs and GPIO pin 17
// as input
//
void setup()
{
unsigned char i;
for(i=0; i < 8; i++)
{
pinMode(LEDs[i], OUTPUT);
}
pinMode(Button, INPUT);
}
//
// Turn ON the appropriate LED
● 72
Chapter 4 • Basic projects using the Arduino IDE and the ESP32 DevKitC
//
void Display(unsigned char No, unsigned char L)
{
unsigned char j, m, i;
m = L - 1;
for(i = 0; i < L; i++)
{
j = pow(2, m);
digitalWrite(LEDs[i], (No & j));
m--;
}
}
//
// When teh button is not pressed increment Count every second
// and send Count to GPIO pins. When the button is pressed
// count down from the last value and send Count to GPIO pins
// Notice that the width is 8-bits (i.e. there are 8 LEDs)
//
void loop()
{
Display(Count, 8);
Button_State = digitalRead(Button); // Read Button state
if(Button_State == UP) // If UP count
{
if(Count == 255)
Count = 0; // Reset Count
else
Count++; // Increment Count
}
else if(Button_State = DOWN) // If DOWN count
{
if(Count == 0)
Count = 255; // Reset Count
else
Count--; // Decreament Count
}
delay(1000); // Wait 1 second
}
Figure 4.35 Program listing
● 73
The Complete ESP32 Projects Guide
4 .8 .8 Program Description
At the beginning of the program an array called LEDs is set up to store the port numbers
of the LEDs used in the project. Name Button is assigned to GPIO port 17, and names
UP and DOWN are assigned to 0 and 1 respectively. Global variable Count is initialised to
zero. Then, the GPIO ports that the LEDs are connected to are configured as output ports,
and the GPIO port where the Button is connected to is configured as an input port. Inside
the main program function Display is called and Count is sent as the argument. Then,
the state of the Button is read: if the Button is not pressed (Button_State equal to UP)
then an UP count is performed. If on the other hand the Button is pressed (Button_State
equal to DOWN) then a DOWN count is performed. Notice that variable Count is reset at
the end of the counts. i.e. during an up count when the count reaches to 255 it is reset to
0 on the next cycle. Similarly, on a down count when the count reaches to 0 it is reset to
255 on the next cycle.
4 .9 .1 Description
Knight Rider is a TV action movie where a super intelligent car that talk and self-navigate.
A strip of lights are mounted in-front of the car. These lights turn ON one by one in one di-
rection, and then in the reverse direction back and forth continuously. In this project 8 LEDs
are connected to the ESP32 DevKitC and the LEDs simulate the Knight Rider car lights.
4 .9 .2 The Aim
The aim of this project is to show how the Knight Rider car lights can be simulated with the
ESP32 processor.
4 .9 .3 Block diagram:
The block diagram of the project is as shown in Figure 4.23.
4 .9 .4 Circuit Diagram
The circuit diagram of the project is as shown in Figure 4.24. 8 LEDs are connected to the
GPIO ports through 330 ohm current limiting resistors.
4 .9 .5 Construction
The project is built on a breadboard as shown in Figure 4.25.
BEGIN
Store LED port numbers in array LEDs
Configure LED port pins as outputs
DO FOREVER
Do k From 0 to 8
Turn ON LED at index LEDs[k]
Wait 100 ms
● 74
Chapter 4 • Basic projects using the Arduino IDE and the ESP32 DevKitC
4 .9 .7 Program Listing
The program listing of the project is very simple and is shown in Figure 4.37 (program:
KnightRider).
/****************************************************************
* KNIGHT RIDER LEDs
* =================
*
* In this program 8 LEDs are connected to port pins GPIO23,
* GPIO22, GPIO1, GPIO3, GPIO21, GPIO19, GPIO18, and GPIO5
* of the ESP32 DevKitC. The program simulates the lights of
* the Knight Rider car as in the TV action movie Knight Rider.
*
*
* Program: KnightRider
* Date : July, 2017
**************************************************************/
int LEDs[] = {23, 22, 1, 3, 21, 19, 18, 5};
unsigned char Count = 0;
unsigned char del = 100;
//
// Set GPIO pins 23,22,1,3,21,19,18,5 as outputs
//
void setup()
{
unsigned char i;
for(i=0; i < 8; i++)
{
pinMode(LEDs[i], OUTPUT);
}
}
● 75
The Complete ESP32 Projects Guide
//
// Turn the LEDs ON/OFF to simulate the Knight Rider car
//
void loop()
{
for(int k = 0; k < 8; k++)
{
digitalWrite(LEDs[k], HIGH);
delay(del);
digitalWrite(LEDs[k], LOW);
}
4 .9 .8 Program Description
At the beginning of the program an array called LEDs is set up to store the port numbers
of the LEDs used in the project. Then, the GPIO ports that the LEDs are connected to are
configured as output ports. Inside the main program two for loops are established. Inside
the first for loop the LEDs from MSB to LSB are turned on for 100 ms. Inside the second
loop the LEDs from LSB to MSB are turned ON for 100 ms. Thus, the net effect is that the
LEDs chase each other in both directions.
4 .9 .10 Suggestions
In Figure 4.37, the delay time between each output is set to 100 ms. Try modifying this
time and see the effects on the display.
4 .10 .1 Description
In this project an LED is connected to the ESP32 DevKitC. The program changes the bright-
ness of the LED by changing the voltage applied to the LED.
● 76
Chapter 4 • Basic projects using the Arduino IDE and the ESP32 DevKitC
4 .10 .5 Construction
The project is built on a breadboard as shown in Figure 4.4.
BEGIN
Define LED port
Define PWM frequency, channel, and resolution
Configure LED port pin as output
Setup and attach port 23 to PWM channel 0
DO FOREVER
DO 20 Times
Increment the duty cycle by 5%, from 0% to 100%
Send the waveform to port 23
Wait 50 ms
ENDDO
DO 20 Times
Decrement the duty cycle by 5%, from 100% to 0%
Send the waveform to port 23
Wait 50 ms
ENDDO
ENDDO
END
/****************************************************************
* CHANGING THE LED BRIGHTNESS
* ===========================
*
* In this program an LED is conencte dto GPIO port pin 23.
* The program changes teh brightness of the LED by varying
* the voltage applied to the LED. The LED PWM function is used
* in this project where the duty cycle of the PWM waveform is
* varied from 0 to its full value of 255
● 77
The Complete ESP32 Projects Guide
*
* Program: Brightness
* Date : July, 2017
**************************************************************/
int LED = 23;
int frequency = 1000;
int resolution = 8;
int channel = 0;
//
// Set GPIO pin 23 as output. Setup the PWM channel 0 and attach
// GPIO pin 23 to this channel
//
void setup()
{
pinMode(LED, OUTPUT);
ledcSetup(channel, frequency, resolution);
ledcAttachPin(LED, channel);
}
//
// Change the brightness of the LED by varying the duty cycle
// from 0% (0) to 100% (255)
//
void loop()
{
for(int duty = 0; duty < 255; duty +=5)
{
ledcWrite(channel, duty);
delay(50);
}
● 78
Chapter 4 • Basic projects using the Arduino IDE and the ESP32 DevKitC
or
Thus, for example, when the duty cycle is 0% the ON time is 0, and when the duty cycle is
100% the OFF time is 0.
The program uses the LED PWM function of the ESP32 which consists of 16 independent
channels with configurable duty cycles, frequencies, and resolutions. A channel from 0 to
15, and a resolution from 1 to 16 bits can be selected. The PWM setup function is called
ledcSetup and it has the following format with integer parameters:
After the setup, we have to attach the GPIO pin that we will be using as the PWM pin to the
selected channel. This is done using function ledcAttach which has the format:
The PWM waveform is then sent to the selected GPIO pin using function ledcWrite which
has the format:
For an 8-bit resolution, the duty cycle is 0 for 0% and 255 for 100%.
In this project, the frequency is set to 1000 Hz, and channel 0 is used with the GPIO pin
● 79
The Complete ESP32 Projects Guide
23. The resolution is set to 8 bits. The duty cycle is changed from 0 to 100% in steps of 5%
every 50 milliseconds. The effect is that the brightness of the LED changes from no light
(0% duty cycle) to full brightness (100% duty cycle) where the brightness is increased by
5% every 50 ms. Similarly, after the full brightness is reached, the program waits for 500
ms and starts to fade the LED from full brightness to no light, again by 5% every 50 ms.
4 .10 .9 Suggestions
In Figure 4.39, the delay time is set to 50 ms and the duty cycle step is set to 5. Try mod-
ifying both of these values see their effects on the LED brightness.
4 .11 .1 Description
In this project a passive buzzer is connected to GPIO port pin 23 of the ESP32 DevKitC. The
buzzer generates sound with frequencies randomly changing between 100 Hz and 5 kHz.
● 80
Chapter 4 • Basic projects using the Arduino IDE and the ESP32 DevKitC
4 .11 .5 Construction
The project is built on a breadboard as shown in Figure 4.43. Figure 4.44 shows the passive
buzzer used in this project.
BEGIN
Define LED port
Define PWM initial frequency, channel, and resolution
Configure LED port pin as output
Setup and attach port 23 to PWM channel 0
DO FOREVER
● 81
The Complete ESP32 Projects Guide
/****************************************************************
* Random Buzzer
* =============
*
* In this program a passive Buzzer is conencted to GPIO port
* pin 23. The program generates random numbers between 1000
* and 5000 and these numbers are used as the random feequency
* to drive the Buzzer. The net effect is that the Buzzer
* generates sound with random frequencies. The duty cycle of
* the waveform is set to 50% (127). 500 ms delay is inserted
* between each output.
*
*
* Program: RandomBuzzer
* Date : July, 2017
**************************************************************/
int Buzzer = 23; // Buzzer on GPIO pin 23
int duty = 127; // 50% duty cycle
int freq = 1000; // Initial freq 1000 Hz
int resolution = 8; // Resolution 8 bits
int channel = 0; // Channel 0
//
// Set GPIO pin 23 as output. Setup the PWM channel 0 and attach
// GPIO pin 23 to this channel
//
void setup()
{
pinMode(Buzzer, OUTPUT);
ledcSetup(channel, freq, resolution);
ledcAttachPin(Buzzer, channel);
randomSeed(10);
}
● 82
Chapter 4 • Basic projects using the Arduino IDE and the ESP32 DevKitC
//
// Use the random number generator to generate the frequency
// values between 1000 Hz and 5000 Hz. The duty cycle is set
// to 50% (127)
//
void loop()
{
freq = random(1000, 5000);
ledcWriteTone(channel, freq);
delay(500);
}
Figure 4.46 Program listing
As in the previous project, the ledcSetup and ledcAttach functions are used to setup
and attach the required GPIO pin to the PWM channel. Function ledcWriteTone is used to
change the frequency of the PWM signal. The format of this function is:
In this project, channel 0 is used with the GPIO pin 23 and the resolution is set to 8 bits.
The duty cycle is set to 50% (127). A random number is generated between 1000 and
5000 and this number is used as the frequency to activate the buzzer. 500 ms delay is used
between each output.
4 .11 .9 Suggestion
In Figure 4.46 only the frequency is changed randomly. Modify the program to change the
duty cycle as well and observe the difference.
4 .12 .1 Description
In this project an RGB LED is used to generate different colours of light, just like a colour
wand.
● 83
The Complete ESP32 Projects Guide
● 84
Chapter 4 • Basic projects using the Arduino IDE and the ESP32 DevKitC
BEGIN
Define port numbers for Red, Green and Blue pins
Configure ports as outputs
DO FOREVER
Create a random number between 1 and 1 for Red
Create a random number between 1 and 1 for Green
Create a random number between 1 and 1 for Blue
Write Red value to Red port
● 85
The Complete ESP32 Projects Guide
/****************************************************************
* RGB LED
* =======
*
* In this program an RGB LED is connected to the ESP32 DevKitC
* where Red pin to GPIO23, Green pin to GPIO22, and the Blue pin
* to GPIO1. The LEDs are turned ON and OFF randomly.
*
*
* Program: RGB
* Date : July, 2017
**************************************************************/
#define RED 23
#define GREEN 22
#define BLUE 1
int R, G, B;
//
// Set GPIO pin 23, 22 and 1 as outputs
//
void setup()
{
pinMode(RED, OUTPUT);
pinMode(GREEN, OUTPUT);
pinMode(BLUE, OUTPUT);
randomSeed(10);
}
//
// Use the random number generator to generate ON (1) or OFF
// (0) values for the three colours
//
void loop()
● 86
Chapter 4 • Basic projects using the Arduino IDE and the ESP32 DevKitC
{
R = random(0, 2);
G = random(0, 2);
B = random(0, 2);
digitalWrite(RED, R);
digitalWrite(GREEN, G);
digitalWrite(BLUE, B);
delay(500);
}
Figure 4.52 Program listing
4 .12 .9 Suggestions
In the program in Figure 4.52 the delay time is set to 500 ms. Try cg=hanging this time
and see its effects.
4 .13 .1 Description
This is a door lock alarm project where a magnet, an active buzzer, and a DevKitC develop-
ment board are used. When the door is closed the magnet is very close to the DevKitC de-
velopment board. The development board reads the magnetic field using its on-board Hall
sensor and then turns OFF the buzzer. As soon as the door opens the magnet moves away
from the development board and the Hall sensor returns a different value. The processor
reads this value and turns ON the buzzer to indicate that the door is opened.
● 87
The Complete ESP32 Projects Guide
BEGIN
Configure Buzzer as output
Turn OFF the Buzzer
DO FOREVER
Read Hall sensor output
IF returned value > 10 THEN
Turn Buzzer ON
ELSE
Turn Buzzer OFF
ENDIF
ENDDO
END
Figure 4.55 PDL of the project
● 88
Chapter 4 • Basic projects using the Arduino IDE and the ESP32 DevKitC
void setup()
{
Serial.begin(9600);
}
void loop()
{
int magnet;
magnet = hallRead();
Serial.print("Hall sensor output = ");
Serial.println(magnet);
delay(1000);
}
Figure 4.56 shows the values returned from the Hall sensor. Without any magnet the re-
turned values are between 18 and 21. When a small magnet is placed near the develop-
ment board the readings fall to around 3. We can now write our main program based on
this simple experiment.
● 89
The Complete ESP32 Projects Guide
The program listing of the project is very simple and is shown in Figure 4.57 (program:
Hall). At the beginning of the program, a buzzer is assigned to GPIO port 23. Inside the
main program loop the program reads output of the Hall sensor using function hallRead. If
the returned value is greater than 10 then it is assumed that the door is opened (magnet is
away from the Hall sensor) and the buzzer is turned ON, otherwise the buzzer is turned OFF.
/****************************************************************
* HALL SENSOR DOOR ALARM
* ======================
*
* In this program a Buzzer is connected to the ESP32 DevKitC GPIO
* port 23. The built-in Hall sensor is used in this project. The
* magnet is near the development board when the door is closed
* and therefore the values returned by the Hall sensor are around
* 3. When the door opens the magnet gets away from the door and
* the Hall sensor returns values greater than 10, which is detected
* by the program and a buzzer is activated to indicate that the
* door is opened.
*
* Program: Hall
* Date : October, 2018
**************************************************************/
#define Buzzer 23
#define ON HIGH
#define OFF LOW
void setup()
{
pinMode(Buzzer, OUTPUT); // Buzzer is output
digitalWrite(Buzzer, OFF); // Buzzer OFF initially
}
void loop()
{
int magnet;
while(1) // Do Forever
{
magnet = hallRead(); // Read Hall sensor
if(magnet > 10) // If door opened
digitalWrite(Buzzer, ON); // Buzzer ON
else // Else...
digitalWrite(Buzzer, OFF); // Buzzer OFF
}
}
Figure 4.57 Program listing
● 90
Chapter 4 • Basic projects using the Arduino IDE and the ESP32 DevKitC
4 .14 .1 Description
The built-in temperature sensor of the ESP32 processor is not meant for measuring the ab-
solute ambient temperature. This sensor measures the chip temperature and can be used
to measure delta temperatures, i.e. changes in the temperature. One application of this
temperature sensor could be to make sure that the processor temperature is stable. In this
project, the chip temperature is measured and displayed on the PC screen using the Putty
terminal emulator program. The measured value is returned in Degrees Fahrenheit. In this
project this is converted into Degrees Centigrade before displayed.
/****************************************************************
* ON-CHIP TEMPERATURE SENSOR
* ==========================
*
* This program uses the on-chip temperature sensor of the DevKitC
* development board to display the temperature. But note that the
* absolute temperature is not measured. The measured value can be
* used as delta temperature. i.e. to compare the change in the chip
* temperature. the reyuened value is in Fahrenheit and can easily
* be converted into Centigrade.
*
* Program: OnChipTemp
* Date : October, 2018
**************************************************************/
#ifdef __cplusplus
extern "C"
{
#endif
uint8_t temprature_sens_read();
#ifdef __cplusplus
}
#endif
uint8_t temprature_sens_read();
void setup()
{
Serial.begin(9600);
}
● 91
The Complete ESP32 Projects Guide
void loop()
{
while(1)
{
Serial.print("temperature = ");
Serial.println((temprature_sens_read() - 32.0) / 1.8);
delay(1000);
}
}
4 .15 .1 Description
The chip ID is basically same as the 6 byte chip MAC address. This project reads the ESP32
chip ID and displays on the PC screen.
● 92
Chapter 4 • Basic projects using the Arduino IDE and the ESP32 DevKitC
/*****************************************************************
* READ THE CHIP ID
* =================
*
* This program reads and then displays the chip id on the PC screen
*
* File: ChipId
* Author: Dogan Ibrahim
* Date: November, 2018
****************************************************************/
unsigned long long ChipID;
unsigned short MSD; // Unsigned 16 bits
unsigned long LSD; // Unsigned 32 bits
void setup()
{
Serial.begin(9600);
}
void loop()
{
ChipID = ESP.getEfuseMac();
MSD = ChipID >> 32;
LSD = ChipID & 0xFFFFFFFF;
Serial.printf("\n\rChip Id (Dec)= %d%d\n\r", MSD,LSD);
Serial.printf("Chip Id (Hex)= %04X%08X\n\r", MSD,LSD);
while(1);
}
Figure 4.60 Program listing
4 .16 Summary
In this chapter we have seen the development of some very basic projects using the ESP32
DevKitC. In the next chapter we shall be looking at the development of slightly more com-
plex projects.
● 93
The Complete ESP32 Projects Guide
5 .1 Overview
In the last chapter we have seen the development of some basic projects using the ESP32
DevKitC. In this chapter we shall be developing slightly more complex projects using the
Arduino IDE as the development software.
As with the previous projects, the title, description, aim, block diagram and so on of all the
projects will be given.
5 .2 .1 Description
In this project an analog temperature sensor chip is used to get the ambient temperature.
The temperature is displayed every second on the PC screen using the Arduino IDE Serial
Monitor.
5 .2 .2 The Aim
The aim of this project is to show how an analog input of the ESP32 DevKitC can be used to
read analog data. In addition, it is shown how to display data on the PC screen.
5 .2 .3 Block diagram:
Figure 5.1 shows the block diagram of the project.
5 .2 .4 Circuit Diagram
In this project the TMP36 analog temperature chip is used to get the ambient temperature.
TMP36 temperature sensor chip is a 3-pin device having the pin layout as shown in Figure
5.2. The device operates with a power supply in the range 2.7 V to 5.5 V and can meas-
ure the temperature in the range -40 ºC to +125 ºC. The output voltage of the device is
proportional to the measured temperature and is given by:
C = (V – 500) / 10
● 94
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC
Where C is the measured temperature in ºC, V is the output voltage of the sensor chip in
mV. Thus, for example, an output voltage of 800 mV corresponds to 30 ºC and so on.
Figure 5.3 shows the circuit diagram of the project. Two pins of the TMP36 are connected to
the +3.3 V power supply and the ground. The output pin of the TMP36 temperature sensor
chip is connected to GPIO4 which is also the ADC2_0 of the ESP32 DevKitC (see Figure
4.2). The ADC is 12-bits wide and has a reference voltage of +3.3 V.
5 .2 .5 Construction
The ESP32 DevKitC board is mounted on a breadboard as shown in Figure 5.4. The output
of the TMP36 is connected to GPIO pin 4.
● 95
The Complete ESP32 Projects Guide
BEGIN
Define TMP36 as GPIO pin 4
Set the Serial Monitor baud rate to 9600
DO FOREVER
Read the ambient temperature
Convert the temperature into Degrees Centigrade
Send the readings to Serial Monitor
Wait 1 second
ENDO
END
● 96
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC
5 .2 .7 Program Listing
The program listing of the project is shown in Figure 5.6 (program: TMP36).
/****************************************************************
* THERMOMETER WITH SERIAL MONITOR
* ===============================
*
* In this program a TMP36 type analog temperature sensor chip
* is connected to GPIO pin 4 which is also an analog input.
* The program reads the ambient temperature every second and
* sends the readings to the Serial Monitor
*
*
* Program: TMP36
* Date : July, 2017
**************************************************************/
#define TMP36 4
void setup()
{
Serial.begin(9600);
}
//
// Read the ambient temperaure, convert into Degrees Centigrade
// and send the readings to the Serial Monitor. Repeat this
// process every second
//
void loop()
{
int Temp = analogRead(TMP36);
float mV = Temp * 3300.0 / 4096.0;
float Temperature = (mV - 500.0) / 10.0;
Serial.println(Temperature);
delay(1000);
}
Figure 5.6 Program listing
5 .2 .8 Program Description
At the beginning of the program TMP36 is defined as port GPIO4 which is one of the analog
input ports of the ESP32 DevKitC, and the Serial Monitor baud rate is set to 9600. The re-
mainder of the program is executed in an endless loop. Inside this loop, the analog output
of the TMP36 is read using the analogRead library function. The reading is then converted
into absolute millivolts. Notice that the ADC reference voltage is 3300 mV and the ADC is
12-bits wide (0 to 4095). The reading is then converted into Degrees Celsius by subtracting
● 97
The Complete ESP32 Projects Guide
500 and dividing by 10. The temperature values are then sent to the Serial Monitor so that
they can be displayed on the PC screen. To do this, click Tool -> Serial Monitor and select
the baud rate as 9600. A typical output from the Serial Monitor is shown in Figure 5.7. We
can make the display more user-friendly by displaying the text Temperature before its
value by modifying the code as follows. The resultant display is shown in Figure 5.8.
It is important to mention at this point that the ESP32 DevKitC used by the author (any
many others as reported on the Internet) has ADC linearity problems which may result in
inaccurate readings. In order to get accurate results from the ADC it is recommended to
● 98
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC
carry out an experiment and create a table or an equation showing the actual relationship
between the analog input voltages and the digital values returned by the ADC. This table
or the equation can then be used to correct the ADC readings.
5 .3 .1 Description
In this project the DHT11 temperature and relative humidity sensor chip is used to get the
ambient temperature and the relative humidity. The readings are displayed every second
on the PC screen using the Arduino Serial Monitor.
5 .3 .2 The Aim
The aim of this project is to show how the popular DHT11 relative humidity and tempera-
ture sensor chip can be used in projects.
5 .3 .3 Block diagram:
Figure 5.9 shows the block diagram of the project.
5 .3 .4 Circuit Diagram
In this project the DHT11 relative humidity and temperature sensor chip is used. The
standard DHT11 is a 4-pin digital output device (only 3 pins are used) as shown in Figure
5.10, having pins +V, GND, and Data. The Data pin must be pulled-up to +V through a 10K
resistor. The chip uses capacitive humidity sensor and a thermistor to measure the ambi-
ent temperature. Data output is available from the chip around every second. The basic
features of DHT11 are:
• 3 to 5 V operation
• 2.5mA current consumption (during a conversion)
• Temperature reading in the range 0-50 ºC with an accuracy of ±2 ºC
• Humidity reading in the range 20-80% with 5% accuracy
• Breadboard compatible with 0.1 inch pin spacings
● 99
The Complete ESP32 Projects Guide
In this example the DHT11 module with built-in 10K pull-up resistor, available from Elektor,
is used. This is a 3-pin device with the pin layout as shown in Figure 5.11.
Figure 5.12 shows the circuit diagram of the project. Here, the Data output of the DHT11
is connected to pin GPIO23 of the ESP32 DevKitC.
● 100
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC
5 .3 .5 Construction
The ESP32 DevKitC board is mounted on a breadboard as shown in Figure 5.13 with the
DHT11 sensor chip connected to +3.3 V, GND and GPIO23 of the development board.
BEGIN
Include the necessary header files
Define GPIO23 as the DHT11 port
Define the DHT type as DHT11
Set the Serial Monitor baud rate to 9600
Initialize the DHT library
DO FOREVER
Read the relative humidity
Read the ambient temperature
Display the relative humidity and temperature on Serial Monitor
Wait 1 second
ENDO
END
● 101
The Complete ESP32 Projects Guide
5 .3 .7 Program Listing
It is necessary to install the DHT sensor library before the sensor chip can be used in an
ESP32 processor based project. The steps to install this library into the Arduino IDE envi-
ronment are given below:
• Search for library DHT-sensor-library as shown in Figure 5.15 and click to in-
stall the library.
• We now have to install the Adafruit Unified Sensor library. Click Sketch ->
Include Library -> Manage Libraries.
• Search for library Adafruit Unified Sensor as shown in Figure 5.16 and click to
install the library.
• Make sure that you have the following two folders under your Libraries folder
inside the Arduino main folder: DHT_Sensor_Library and Adafruit_Unified_
Sensor.
• We are now ready to develop our program to read the relative humidity and the
temperature. Figure 5.17 shows the program listing (program: DHT11).
● 102
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC
/****************************************************************
* RELATIVE HUMIDITY AND TEMPERATURE WITH SERIAL MONITOR
* =====================================================
*
* In this program a DHT11 type relative humidity and temperature
* sensor chip is connected to GPIO pin 23. The relative humidity
* and the ambient temperature are read every second and the
* readings are displayed on the Serial monitor.
*
* Program: DHT11
* Date : July, 2017
**************************************************************/
#include <Adafruit_Sensor.h>
#include "DHT.h"
#define DHT11_PIN 23
#define DHTTYPE DHT11
//
// Set the Serial Monitor baud rate to 9600 and initislize the
// DHT library
//
void setup()
{
Serial.begin(9600);
dht.begin();
}
//
// Read the relative humidity and the ambient temperaure and
// display the results on the Serial Monitor
//
void loop()
{
float humidity = dht.readHumidity(); // Read humidity
float temperature = dht.readTemperature(); // Read temperature
Serial.print("Temperature = "); // Display "Temperature="
Serial.print(temperature); // Display temperature
Serial.print(" Humidity = "); // Display "Humidity="
Serial.println(humidity); // Display humidity
delay(1000); // Wait 1 second
}
Figure 5.17 Program listing
● 103
The Complete ESP32 Projects Guide
5 .3 .8 Program Description
At the beginning of the program header files Adafruit_Sensor .h and DHT .h are included
in the program. GPIO pin that the DHT11 is connected to is defined as pin 23, and the DHT
type is specified as DHT11. Then, the Serial Monitor baud rate is set to 9600 and the DHT
library is initialised.
The remainder of the program is executed in an endless loop. Inside this loop the relative
humidity and the ambient temperature are read and displayed on the Serial Monitor every
second. Figure 5.18 shows a sample output displayed on the Serial Monitor.
5 .4 .1 Description
In this project a light dependent resistor (LDR) is used to measure the light level every
second. The reading is then displayed on the Serial Monitor.
5 .4 .2 The Aim
The aim of this project is to show how an LDR can be used in ESP32 processor based pro-
jects.
5 .4 .3 Block diagram:
Figure 5.19 shows the block diagram of the project.
● 104
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC
5 .4 .4 Circuit Diagram
LDRs are simple resistors (Figure 5.20) whose resistances decrease with increasing incident
light. These devices are usually used in light level control applications. Figure 5.21 shows
the characteristic curve of a typical LDR. As you can see, the resistance of the device de-
creases as the light intensity increases.
The circuit diagram of the project is shown in Figure 5.22. One leg of the LDR is connected
to ground (0 V). The other leg is connected to +3.3 V (3 V) through a 10K resistor. The
junction of the LDR with the 10K resistor is connected to analog input GPIO4 of the ESP32
DevKitC. Notice that, just like resistors, LDRs have no polarities.
● 105
The Complete ESP32 Projects Guide
5 .4 .5 Construction
The ESP32 DevKitC board is mounted on a breadboard as shown in Figure 5.23 with the
LDR and a 10K resistor.
BEGIN
Define LDR as GPIO4
Set the Serial Monitor baud rate to 9600
DO FOREVER
Read the voltage across the LDR through the ADC
Display the reading on the Serial Monitor
Wait 1 second
ENDO
END
5 .4 .7 Program Listing
The program is very simple and its listing is shown in Figure 5.25 (program: LDR).
● 106
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC
/****************************************************************
* MEASURING THE LIGHT LEVEL
* =========================
*
* In this program a light dependent resistor is connected
* to analog input GPIO4 of the ESP32 Devkitc. The program
* measures and then displays the light level through the
* Serial Monitor. The resistance of the LDR increases in
* dark and as a result a higher reading is obtained.
*
*
* Program: LDR
* Date : July, 2017
**************************************************************/
#define LDR 4
//
// Set the Serial Monitor baud rate to 9600
//
void setup()
{
Serial.begin(9600);
}
//
// Read the light level and display through the Serial Monitor
//
void loop()
{
int ldr = analogRead(LDR);
Serial.println(ldr);
delay(1000);
}
Figure 5.25 Program listing
5 .4 .8 Program Description
At the beginning of the program LDR is assigned to analog input port GPIO4. Inside the
main program the voltage across the LDR is read through the ADC and is the displayed on
the Serial Monitor. Notice that what is displayed is the binary value read by the ADC and
not the actual physical voltage across the LDR.
In normal light conditions the readings are around a few hundred. In the dark the resist-
ance of the LDR increases and the reading goes over 2000. The program should be calibrat-
ed using a commercial light meter so that correct light level readings are correct.
● 107
The Complete ESP32 Projects Guide
5 .4 .9 Suggestions
A variable resistor can be used instead of the 10K fixed resistor. This way, the circuit can
be made more sensitive to other light levels.
5 .5 .1 Description
In this project a light dependent resistor (LDR) is used as in the previous project. Here, an
active buzzer and an LED are connected to GPIO pins 23 and 22 respectively. The project
reminds darkness where both the buzzer and the LED are turned ON when the LDR senses
darkness.
5 .5 .2 The Aim
The aim of this project is to show how a simple darkness reminder project can be designed
using the ESP32 DevKitC.
5 .5 .3 Block diagram:
Figure 5.27 shows the block diagram of the project.
● 108
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC
5 .5 .4 Circuit Diagram
The circuit diagram of the project is shown in Figure 5.28.
5 .5 .5 Construction
The ESP32 DevKitC board is mounted on a breadboard as shown in Figure 5.29 with the
LDR, a 10K resistor, and an active buzzer.
Make sure that the active buzzer you are using does not require more than about 5 mA and
it can operate with +3.3 V. A transistor switch may be required to protect the output port
loading if the buzzer requires more than 5 mA.
● 109
The Complete ESP32 Projects Guide
BEGIN
Define LDR as GPIO4
Define BUZZER as GPIO23
Define LED as GPIO22
Configure GPIO22 and GPIO23 as outputs
Turn OFF both BUZZER and LED to start with
Set the Serial Monitor baud rate to 9600
DO FOREVER
Read the voltage across the LDR through the ADC
IF reading > 2000 THEN
Turn ON BUZZER
Turn ON LED
ELSE
Turn OFF BUZZER
Turn OFF LED
ENDIF
ENDO
END
5 .5 .7 Program Listing
The program is very simple and its listing is shown in Figure 5.31 (program: LDRALARM).
/****************************************************************
* DARKNESS REMINDER
* =================
*
* In this program a light dependent resistor is connected
* to analog input GPIO4 of the ESP32 Devkitc. In addition,
* a buzzer and an LED are connecte dto GPIO ports 23 and 22
* respectively. Normally both the buzzer and the LED are OFF
* and they turn ON when it becomes dark. Darkness is assumed
* when the LDR reading is above 2000.
*
*
* Program: LDRALARM
* Date : July, 2017
**************************************************************/
#define LDR 4
#define BUZZER 23
● 110
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC
#define LED 22
//
// Configure both the BUZZER and the LED as outputs
//
void setup()
{
pinMode(BUZZER, OUTPUT);
pinMode(LED, OUTPUT);
digitalWrite(BUZZER, LOW);
digitalWrite(LED, LOW);
}
//
// Read the light level and turn on both the BUZZER and the LED
// when it becomes dark. In this project the darkness has been
// assumed when the LDR reading is above 2000
//
void loop()
{
int ldr = analogRead(LDR);
if(ldr > 2000)
{
digitalWrite(BUZZER, HIGH);
digitalWrite(LED, HIGH);
}
else
{
digitalWrite(BUZZER, LOW);
digitalWrite(LED, LOW);
}
}
Figure 5.31 Program listing
5 .5 .8 Program Description
At the beginning of the program LDR is defined as port 4, BUZZER as port 23 and LED as
port 22. Digital ports 23 and 22 are configured as outputs. Inside the main program the
output of the LDR is read and stored in integer variable ldr. Darkness is assumed if ldr is
greater than 2000 (see the previous project) and when this happens both the buzzer and
the LED are turned ON to indicate the darkness.
5 .5 .9 Suggestions
In this project a buzzer and an LED are used as the output devices. It is possible to connect
a relay to an output port of the ESP32 DevKitC and, for example, turn ON the room lights
automatically when it becomes dark.
● 111
The Complete ESP32 Projects Guide
5 .6 .1 Description
This is a simple dice project based on LEDs and a push-button switch. The LEDs are organ-
ised to simulate the look of the faces of a real dice. When the push-button switch is pressed
a random number is generated between 1 and 6 and is displayed on the LEDs. Normally the
LEDs are all OFF to indicate that the system is ready to generate a new dice number. After
3 seconds the LEDs turn OFF again.
5 .6 .2 The Aim
The aim of this project is to show how an LED based dice can be designed.
5 .6 .3 Block diagram:
Figure 5.32 shows the block diagram of the project.
As shown in Figure 5.33, the LEDs are organised such that when they turn ON, they indicate
the numbers as in a real dice. Operation of the project is as follows: Normally the LEDs are
all OFF to indicate that the system is ready to generate a new dice number. Pressing the
switch generates a random dice number between 1 and 6 and displays on the LEDs for 3
seconds. After 3 seconds the LEDs turn OFF again.
1 2 3 4 5 6
Figure 5.33 LED dice
5 .6 .4 Circuit Diagram
The circuit diagram of the project is shown in Figure 5.34. The 7 LEDs are connected to
GPIO pins 23, 22, 1, 3, 21, 19, and 18 through 330 ohm current limiting resistors. The
connection is as follows:
● 112
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC
D4 21
D5 22
D6 3
D7 18
The push-button switch is connected to GPIO pin 5 through a 10K pull-up resistor so that
normally the button output is at logic 1 and it goes to logic 0 when the button is pressed.
5 .6 .5 Construction
The ESP32 DevKitC board is mounted on a breadboard with the 7 LEDs and the push-button
switch as shown in Figure 5.35.
● 113
The Complete ESP32 Projects Guide
5 .6 .7 Program Listing
The program listing is shown in Figure 5.37 (program: DICE).
/****************************************************************
* LED DICE
* ========
*
* In this program 7 LEDs are connected in to the ESP32 Devkitc
* to simulate the faces of a dice. In addition, a push-button
* switch is used. When the switch is pressed, a random number
* is generated between 1 and 6 and the LEDs are turned ON to
* indicate the number as if it is a real dice. The LEDs display
* the number for 3 seconds and then turn OFF to indicate that
* the system is ready so that the user can press the button
* again if desired.
*
* The connections of the LEDs and the push-button switch are
* as follows:
*
* D1: GPIO23, D2: GPIO1, D3: GPIO19, D4: GPIO21, D5: GPIO22
* D6: GPIO3, D7: GPIO18
● 114
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC
//
// Configure the LEDs as outputs, and the Button as input
//
void setup()
{
for(int i = 0; i < 7; i++)
{
pinMode(LEDs[i], OUTPUT);
}
pinMode(Button, INPUT);
randomSeed(10);
//
// Turn all LEDs OFF
//
void ALL_OFF()
{
for(int i = 0; i < 7; i++)
{
digitalWrite(LEDs[i], LOW);
}
}
//
// Turn OFF all LEDS so that the system is ready to accept a
// new button press. Wait until the Button is pressed. Then,
// generate a random number between 1 and 6. Turn ON the
● 115
The Complete ESP32 Projects Guide
switch (dice)
{
case 1: // Number 1
digitalWrite(D4, HIGH); // Turn ON D4
break;
case 2: // Number 2
digitalWrite(D2, HIGH); // Turn ON D2,D6
digitalWrite(D6, HIGH);
break;
case 3: // Number 3
digitalWrite(D2, HIGH); // Turn ON D2,D4,D6
digitalWrite(D4, HIGH);
digitalWrite(D6, HIGH);
break;
case 4: // Number 4
digitalWrite(D1, HIGH); // Turn ON D1,D3,D5,D7
digitalWrite(D3, HIGH);
digitalWrite(D5, HIGH);
digitalWrite(D7, HIGH);
break;
case 5: // Number 5
digitalWrite(D1, HIGH); // Turn ON D1,D3,D4,D5,D7
digitalWrite(D3, HIGH);
digitalWrite(D4, HIGH);
digitalWrite(D5, HIGH);
digitalWrite(D7, HIGH);
break;
case 6: // Number 6
digitalWrite(D1, HIGH); // Turn ON D1,D2,D3,D5,D6,D7
digitalWrite(D2, HIGH);
digitalWrite(D3, HIGH);
digitalWrite(D5, HIGH);
digitalWrite(D6, HIGH);
digitalWrite(D7, HIGH);
break;
}
● 116
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC
5 .6 .8 Program Description
At the beginning of the program Button is assigned to GPIO port 5. Similarly, LEDs D1,
D2, D3, D4, D5, D6 are assigned to GPIO ports 23, 1, 19, 21, 22, 3 and 18 respectively.
All the LEDs are configured as outputs and the Button is configured as an input.
The main program is executed in an endless loop. Inside this loop all the LEDs are turned
OFF initially. The program then waits until the Button is pressed. When the button is pressed
a random number is generated between 1 and 6. A switch statement is then used to turn
ON the appropriate LEDs depending upon the generated number. The program displays the
generated number for 3 seconds. After this time the above process is repeated.
5 .7 .1 Description
This project is a simple logic probe. A logic probe is used to indicate the logic status of an
unknown digital signal. In a typical application a test lead (probe) is used to detect the
unknown signal and two different colour LEDs are used to indicate the logic status. If, for
example, the signal is logic 0, then the RED colour LED is turned ON. If, on the other hand,
the signal is logic 1, then the GREEN LED is turned ON.
5 .7 .2 The Aim
The aim of this project is to show how a logic probe can be designed to test the logic state
of an applied logic signal.
● 117
The Complete ESP32 Projects Guide
5 .7 .3 Block diagram:
Figure 5.39 shows the block diagram of the project. The RED and GREEN LEDs are connect-
ed to GPIO ports 23 and 22 respectively. The logic signal to be tested is applied to GPIO
port 1.
5 .7 .4 Circuit Diagram
The circuit diagram of the project is shown in Figure 5.40. The LEDs are connected to GPIO
pins through 330 ohm current limiting resistors. The logic signal to be tested is directly
applied to GPIO port 1.
5 .7 .5 Construction
The ESP32 DevKitC board is mounted on a breadboard with the two LEDs as shown in
Figure 5.41.
● 118
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC
BEGIN
Assign RED to GPIO port 23
Assign GREEN to GPIO port 22
Assign Probe to GPIO port 1
Configure GPIO ports 22,23 as outputs
Configure GPIO port 1 as input
DO FOREVER
IF Probe is logic 0 THEN
Turn ON RED LED
Turn Off GREEN LED
ELSE
Turn ON GREEN LED
Turn OFF RED LED
ENDIF
ENDDO
END
● 119
The Complete ESP32 Projects Guide
5 .7 .7 Program Listing
The program listing is shown in Figure 5.43 (program: Probe).
/****************************************************************
* LOGIC PROBE
* ===========
*
* This is a logic probe program. Two LEDs, one RED and one
* GREEN are connected to GPIO ports 23 and 22 respectively.
* The program determins the state of the logic signal applied
* to GPIO port 5. If the applied logic level is 0 then the
* RED LED is turned ON. If on teh other hand the applied
* logic level is 1 then the GREEN LED is turned ON.
*
*
* Program: Probe
* Date : July, 2017
**************************************************************/
#define Probe 1
#define RED 23
#define GREEN 22
//
// Configure the LEDs as outputs, and the Probe as input
//
void setup()
{
pinMode(RED, OUTPUT);
pinMode(GREEN, OUTPUT);
pinMode(Probe, INPUT);
}
//
// Examine the state of the applied external logic signal. If
// the state is 0, then turn ON the RED LED. if on the other
// hand the external applied logic state is 1, then turn ON the
// GREEN LED
//
void loop()
{
if(digitalRead(Probe) == 0) // Logic state is 0
{
digitalWrite(RED, HIGH); // RED ON
digitalWrite(GREEN, LOW); // GREEN OFF
}
else // Logic state 1
● 120
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC
{
digitalWrite(GREEN, HIGH); // GREEN ON
digitalWrite(RED, LOW); // RED OFF
}
}
Figure 5.43 Program listing
5 .7 .8 Program Description
At the beginning of the program, Probe is assigned to GPIO port 1, RED LED is assigned
to GPIO port 23 and the GREEN LED is assigned to GPIO port 22. The LED ports are then
configured as outputs and the Probe is configured as an input.
The remainder of the program is executed in an endless loop. Inside this loop, the state of
the external logic signal is read and if it is logic 0 then the RED LED is turned ON, otherwise
the GREEN LED is turned ON. This process is repeated continuously.
5 .7 .9 Modified Program
The logic probe program shown in Figure 5.43 has a problem that one of the LEDs is always
ON, even if the probe is not connected to any external digital signal (e.g. the high-imped-
ance state). We can develop the project further so that the high-impedance state can also
be detected and none of the LEDs are turned ON when there is no applied logic level.
Figure 5.44 shows the modified circuit diagram. Notice here that a transistor (BC108 or
any other npn transistor) is used at the front end of the circuit. The operation of the circuit
is as follows:
The transistor is configured as an emitter-follower stage with the base connected to GPIO
port 3, configured as an output port. The external logic signal is applied to the base of the
transistor through a 10K resistor. The emitter of the transistor is connected to GPIO port
1, which is configured as an input port. GPIO port 3 applies logic levels to the base of the
transistor and then pin GPIO port 1 determines the state of the external signal as shown
in Table 5.2. For example, if after setting port 3 = 1, we detect that port 1 =1 and also
after setting port 3 = 0 we again detect that port 1 = 1, then the probe must be at logic 1.
● 121
The Complete ESP32 Projects Guide
At high impedance 1 1
0 0
Probe at logic 1 1 1
0 1
Probe at logic 0 1 0
0 0
Figure 5.45 shows the modified program listing (program: Probe2). At the beginning of
the program Probe is assigned to GPIO1, RED and GREEN assigned to GPIO23 and
GPIO22 respectively, and CHECK assigned to GPIO3. The LEDs and CHECK are then con-
figured as digital outputs and Probe configured as digital input.
The remainder of the program executes in an endless loop and implements the logic given
in Table 5.2 in order to turn ON/OFF the RED and GREEN LEDs.
****************************************************************
* LOGIC PROBE
* ===========
*
* This is a logic probe program. Two LEDs, one RED and one
* GREEN are connected to GPIO ports 23 and 22 respectively.
* The program determins the state of the logic signal applied
* to GPIO port 5. If the applied logic level is 0 then the
* RED LED is turned ON. If on teh other hand the applied
* logic level is 1 then the GREEN LED is turned ON.
*
* This modified program detects the high impedance state when
* there is no logic level applied at the input
*
*
* Program: Probe2
* Date : July, 2017
**************************************************************/
#define Probe 1
#define RED 23
#define GREEN 22
#define CHECK 3
//
// Configure the LEDs as outputs, and the Probe as input
//
void setup()
{
● 122
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC
pinMode(RED, OUTPUT);
pinMode(GREEN, OUTPUT);
pinMode(CHECK, OUTPUT);
pinMode(Probe, INPUT);
}
//
// Examine the state of the applied external logic signal. If
// there is nothing connected at the input then assume high
// impedance state and turn OFF both LEDs. If on the other
// hand the state is 0, then turn ON the RED LED. if on the
// other hand the external applied logic state is 1, then
// turn ON the GREEN LED
//
void loop()
{
digitalWrite(CHECK, HIGH); // Set CHECK = 1
delay(1);
if(digitalRead(Probe) == 1)
{
digitalWrite(CHECK, LOW);
delay(1);
if(digitalRead(Probe) == 0)
{
digitalWrite(RED, LOW); // High impedance state
digitalWrite(GREEN, LOW);
}
else
{
digitalWrite(RED, LOW);
digitalWrite(GREEN, HIGH);
}
}
else
{
digitalWrite(CHECK, LOW);
delay(1);
if(digitalRead(Probe) == 0)
{
digitalWrite(GREEN, LOW);
digitalWrite(RED, HIGH);
}
}
}
Figure 5.45 Modified program
● 123
The Complete ESP32 Projects Guide
5 .8 .1 Description
This is a simple project and it describes the design of a 7-segment LED based counter which
counts from 0 to 9 continuously with one second delay between each count.
7-segment displays are used frequently in electronic circuits to show numeric or alphanu-
meric values. A 7-segment display basically consists of 7 LEDs (see Figure 5.47) connected
such that numbers from 0 to 9 and some letters can be displayed. Segments are identified
by letters from a to g and Figure 5.48 shows the segment names of a typical 7-segment
LED display.
● 124
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC
Figure 5.49 shows how numbers from 0 to 9 can be obtained by turning ON/OFF different
segments of the display.
In a common anode configuration, the anode terminals of all the LEDs are connected
together as shown in Figure 5.51. This common point is then normally connected to the
supply voltage. A segment is turned ON by connecting its cathode terminal to logic 0 via a
current limiting resistor.
● 125
The Complete ESP32 Projects Guide
In this project, a SMA42056 model common cathode 7-segment display is used. This is a
14.20 mm (0.56 inch) large display that can be viewed from a distance up to 7 metres. The
LED forward voltage is about 2 V. The display has 10 pins and it also has a segment LED for
the decimal point. Table 5.3 shows the pin configuration of this display. The pin numbering
starts from the bottom left corner of the display with pin 1 as shown in Figure 5.52. The
bottom right corner is pin 5, and the top left corner is pin 10.
1 E
2 D
3 common cathode
4 C
5 decimal point
6 B
7 A
8 common cathode
9 F
10 G
Table 5.3 SMA42056 7-segment LED pin configuration
● 126
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC
5 .8 .2 The Aim
The aim of this project is to show how a 7-segment LED can be interfaced and used in an
ESP32 DevKitC project.
5 .8 .3 Block diagram
The block diagram of the project is shown in Figure 5.53.
5 .8 .4 Circuit Diagram
The circuit diagram of the project is shown in Figure 5.54. The segments of the LED are
connected to GPIO pins through 330 ohm current limiting resistors. The connection be-
tween the display segments and the GPIO pins are as follows:
Before driving the display we have to know the relationship between the numbers to be
displayed and the GPIO pins that should be HIGH. This is shown below:
● 127
The Complete ESP32 Projects Guide
5 .8 .5 Construction
The ESP32 DevKitC board is mounted on a breadboard with the 7-segment LED and the
current limiting resistors as shown in Figure 5.55.
BEGIN
Declare array Num and store segments to be turned ON for every number
Declare array Strt and store starting index of each number within Num
Declare array LEDs and store all the GPIO port numbers used
● 128
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC
Set Count to 0
Configure all used GPIO ports as outputs
DO FOREVER
Display Count
Wait one second
Increment Count
Turn OFF all segments
IF Count = 10 THEN
Count = 0
ENDIF
ENDDO
END
5 .8 .7 Program Listing
The program listing is shown in Figure 5.57 (program: SevenSegment).
/****************************************************************
* 7-SEGMENT LED COUNTER
* =====================
*
* In this project a 7-segment LED is connected to the ESP32
* DevKitC. The program counts up from 0 to 9 with one second
* intervals. The connections between the GPIO pins and the
* 7-segment LED segments are as follows:
*
* Segment GPIO pin
* a 23
* b 22
* c 1
* d 3
* e 21
* f 19
* g 18
*
*
* Program: SevenSegment
* Date : July, 2017
**************************************************************/
int Num[]= {6, 23, 22, 1, 3, 21, 19, //0
2, 22, 1, //1
5, 23, 22, 18, 21, 3, //2
5, 23, 22, 18, 1, 3, //3
4, 19, 18, 22,1, //4
5, 23, 19, 18, 1, 3, //5
● 129
The Complete ESP32 Projects Guide
//
// Configure the LEDs as outputs, and also turn OFF all segments
//
void setup()
{
for(int i = 0; i < 7; i++)
{
pinMode(LEDs[i], OUTPUT);
ALL_OFF();
}
}
//
// Turn OFF all segments
//
void ALL_OFF()
{
for(int i = 0; i < 8; i++)
{
digitalWrite(LEDs[i], LOW);
}
}
//
// This function display a given number N on the 7-segment display
//
void Display(int N)
{
int i, k;
k = Strt[N]; // Starting index
i = Num[k]; // Length
for(int m = k + 1; m < k + 1 + i; m++)
{
digitalWrite(Num[m], HIGH);
}
}
//
// Increment variable Count by 1 and display on the 7-segment
// display every second
● 130
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC
//
//
void loop()
{
Display(Count);
delay(1000);
ALL_OFF();
Count++;
if(Count == 10)Count = 0;
}
Figure 5.57 Program listing
5 .8 .8 Program Description
At the beginning of the program three arrays are declared: Num, Strt, and LEDs. Array
Num stores the segments to be turned ON in terms of the GPIO port numbers where the
rows correspond to the numbers to be displayed and the first number in every row is the
number of segments to be turned ON for the given number. For example, the row corre-
sponding to number 3 is:
The first number 5 here is the number of segments to be turned ON and these segments
are connected to GPIO ports 23, 22, 18, 1 and 3.
The second array Strt stores the starting index number within array Num of every number
to be displayed. For example, number 3 starting index is 16 in array Num where the 16th
element of array Num is the number of segments to be turned ON as described above.
Array LEDs stores the GPIO port addresses of all the LEDs and this array is used to config-
ure all the ports as outputs and also to turn OFF all the segments when required.
Function Display receives the number to be displayed as its argument. This function ex-
tracts the segments to be turned ON and then turns them ON using the digitalWrite state-
ment.
The main program is executed in an endless loop. Inside this loop, the current value of
variable Count is displayed. After one second delay, all the segments are turned OFF ready
for the next number. Count is incremented by one and it is reset to 0 when it reaches 10.
5 .8 .9 Modified Program
The program given in Figure 5.57 can be simplified and made more user-friendly if we
group the GPIO ports into an 8-bit byte and then access all the port bits by sending a byte
to this port. This technique was shown in Figure 4.22 back in Chapter 4.
The modified program listing is shown in Figure 5.58 (program: SevenSegment2). Here,
the GPIO port bits are grouped as follows:
● 131
The Complete ESP32 Projects Guide
MSB LSB
X 23 22 1 3 21 19 18
X, here, is not used. The relationship between the numbers to be displayed and the number
to be sent to the grouped port can be derived as follows (X is taken as 0):
/****************************************************************
* 7-SEGMENT LED COUNTER
* =====================
*
* In this project a 7-segment LED is connected to the ESP32
* DevKitC. The program counts up from 0 to 9 with one second
* intervals. The connections between the GPIO pins and the
* 7-segment LED segments are as follows:
*
* Segment GPIO pin
* a 23
* b 22
* c 1
* d 3
* e 21
* f 19
* g 18
*
*
* Program: SevenSegment2
* Date : July, 2017
**************************************************************/
int Num[] = {0x7E, 0x30, 0x6D, 0x79, 0x33, 0x5B, 0x1F, 0x70, 0x7F, 0x73};
int LEDs[] = {23, 22, 1, 3, 21, 19, 18};
int Ports[] = {0, 23, 22, 1, 3, 21, 19, 18};
int Count = 0;
● 132
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC
//
// Configure the LEDs as outputs
//
void setup()
{
for(int i = 0; i < 7; i++)
{
pinMode(LEDs[i], OUTPUT);
}
}
//
// Turn ON the appropriate LED
//
void Display(int No, unsigned char L)
{
unsigned char j, m, i;
m = L - 1;
for(i = 0; i < L; i++)
{
j = pow(2, m);
digitalWrite(Ports[i], (No & j));
m--;
}
}
//
// Increment variable Count by 1 and display on the 7-segment
// display every second
//
//
void loop()
{
Display(Num[Count], 8);
delay(1000);
Count++;
if(Count == 10)Count = 0;
}
Figure 5.58 Modified program
● 133
The Complete ESP32 Projects Guide
5 .9 .1 Description
In this project a sound sensor module (called the Small Microphone Module) and an LED are
used. The LED changes state (i.e. is toggled) when sound is detected by the sound sensor
module, such as clapping hands, where if the LED is OFF, it turns ON when we clap hands
near the microphone. Clapping hands again turns the LED back OFF. In this project an LED
is used, but there is no reason why the LED cannot be replaced by a relay and for example
room lights or garage door connected to the relay.
5 .9 .2 The Aim
The aim of this project is to show how a sound sensor module can be connected to the
ESP32 DevKitC and how it can be used to control an external device such as an LED, relay,
or any other logic operated device.
5 .9 .3 Block diagram
In this project the Small Microphone Module (available from Elektor) is used (see Figure
5.59). This is a 4-pin module having the following pin definitions:
The analog output is not used in this project. A small potentiometer is used to adjust the
triggering point (i.e. the sensitivity) of the digital output such that the output is set to be
normally logic LOW and goes to logic HIGH when sound is detected by the microphone.
The block diagram of the project is shown in Figure 5.60 where the GPIO pins 23 and 22
are used for the sound sensor module and the LED respectively.
● 134
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC
5 .9 .4 Circuit Diagram
The circuit diagram of the project is shown in Figure 5.61. The digital output D0 of the
sound sensor module is connected to GPIO port 23 of the ESP32 DevKitC. The LED is con-
nected to GPIO port 22 through a 330 ohm current limiting resistor.
5 .9 .5 Construction
The ESP32 DevKitC board is mounted on a breadboard with the sound sensor module and
the LED connected to it as shown in Figure 5.62.
● 135
The Complete ESP32 Projects Guide
BEGIN
Assign GPIO port 22 to the LED
Assign GPIO port 23 to the sound sensor module
Configure GPIO22 as output
Configure GPIO23 as input
DO FOREVER
IF output of sound sensor module = 1
Toggle the LED
Wait 500 ms
ENDIF
ENDO
END
5 .9 .7 Program Listing
The program listing is shown in Figure 5.64 (program: Sound).
/**************************************************************
* CLAP ON - CLAP OFF
* ==================
*
* In this project a sound sensor module (called the Small
* Microphone Module) is connected to GPIO port 23 of the
* ESP32 Devkitc. In addition, an LED is connected to GPIO
* port 22. The LED is normally OFF and is turned ON when
* sound is detected by the sensor (e.g. by clapping hands).
* The LED is toggled every time sound is detected by the
* sensor.
*
**************************************************************/
#define LED 22
#define SoundSensor 23
int state = 0;
//
// Configure GPIO ports LED as output and SoundSensor as input
//
void setup ()
{
pinMode (LED, OUTPUT);
pinMode(SoundSensor, INPUT);
digitalWrite(LED, LOW);
● 136
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC
//
// Toggle the LED when sound is detected by the sensor
//
void loop ()
{
if(digitalRead(SoundSensor) == 1)
{
digitalWrite(LED, (state) ? HIGH : LOW);
state = !state;
delay(500);
}
}
Figure 5.64 Program listing
5 .9 .8 Program Description
At the beginning of the program GPIO 23 and 22 are assigned to the LED and the sound
sensor module respectively. The LED port is configured as output and the sound sensor port
is configured as input.
The main program runs in an endless loop. Inside this loop, the output of the sound sensor
is read. If the output is at logic 1 (i.e. sound is detected) then the state of the LED is tog-
gled. This process is repeated after 500 milliseconds.
5 .10 .1 Description
This is a simple LCD project. The project displays the text Hello from ESP32 on the first
row of a 16x2 character LCD.
GPIO ports 21 and 22 are available for use by the I2C bus interface on the ESP32 DevKitC,
where port 21 is the data line (SDA) and port 22 is the clock line (SCL).
● 137
The Complete ESP32 Projects Guide
Figure 5.65 shows the front and back of the I2C based LCD. Notice that the LCD has a
small board mounted at its back to control the I2C interface. The LCD contrast is adjusted
through the small potentiometer mounted on this board. A jumper is provided on this board
to disable the backlight if required. The block diagram of the project is shown in Figure
5.66, where the GPIO pins 21 and 22 are used for the SDA and SCL of the LCD respectively.
● 138
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC
5 .10 .5 Construction
The ESP32 DevKitC board is mounted on a breadboard and jumper wires are used to make
connection to the I2C LCD as shown in Figure 5.68.
• Create a folder named LiquidCrystal_I2C under the folder named libraries in your
Arduino IDE folder (see Figure 5.69).
https://github.com/fdebrabander/Arduino-LiquidCrystal-I2C-library
● 139
The Complete ESP32 Projects Guide
• Click the button Clone or download (see Figure 5.70) and copy all the files to
the LiquidCrystal_I2C folder as shown in Figure 5.71.
Start the Arduino IDE. Go to File -> Examples and you should see LiquidCrystal_I2C
examples in the drop down menu if the library has been installed correctly.
BEGIN
Include libraries Wire and LiquidCrystal_I2C
Set I2C LCD address and configuration
Initialize I2C LCD
Turn ON backlight
Display text Hello from ESP32
END
/*************************************************************
* LCD TEXT
* ========
*
● 140
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC
//
// Set the LCD address to 0x27 and the configuration to
// 16 chars and 2 rows display
//
LiquidCrystal_I2C lcd(0x27, 16, 2); // LCD address 0x27
void setup()
{
lcd.begin(); // Initialize LCD
lcd.backlight(); // Turn ON backlight
lcd.print("Hello from ESP32"); // Display Text
}
void loop()
{
// No code here
}
Figure 5.73 Program listing
5 .11 .1 Description
This is an LCD event counter project. The project counts external events occurring on one
of the GPIO ports and displays the results on an LCD. In this project an event is said to oc-
cur if the state of GPIO port 23 changes from logic 1 to logic 0. Here, a push-button switch
is used to simulate the occurrence of external events.
● 141
The Complete ESP32 Projects Guide
5 .11 .4 Diagram
The circuit diagram of the project is shown in Figure 5.75. The SDA and CL pins of the I2C
LCD are connected to GPIO ports 21 and 22 respectively. The push-button switch is con-
nected to GPIO port 23.
5 .11 .5 Construction
The ESP32 DevKitC board is mounted on a breadboard with the push-button switch. The
I2C LCD is connected to DevKitC through jumper wires as shown in Figure 5.76.
● 142
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC
BEGIN
Include libraries Wire and LiquidCrystal_I2C
Assign GPIO port 23 to EVENTS
Clear variable Count to 0
Configure port 23 as input
Set I2C LCD address and configuration
Initialize I2C LCD
Turn ON backlight
Display text Event Counter
DO FOREVER
Wait until an event occurs
Contact debounce
Clear LCD
Increment Count
Convert Count into string
Display Count on LCD
ENDDO
END
● 143
The Complete ESP32 Projects Guide
/*************************************************************
* LCD EVENT COUNTER
* =================
*
* This is an event counter program with an LCD. Events are
* assumed to occur on GPIO port 23 where an event is the HIGH
* to LOW transition of this pin. In this project events are
* simulated using a push-button switch connected to GPIO23 and
* pulled high. An I2C LCD is connected to the ESP32 Devkitc.
*
* File: LCDCounter
* Date: July 2017
* Author: Dogan Ibrahim
*************************************************************/
#define EVENTS 23
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
int Count = 0;
char Res[4];
//
// Set the LCD address to 0x27 and the configuration to
// 16 chars and 2 rows display. Also configure port 23 as
// an input
//
LiquidCrystal_I2C lcd(0x27, 16, 2); // LCD address 0x27
void setup()
{
pinMode(EVENTS, INPUT);
lcd.begin(); // Initialize LCD
lcd.backlight(); // Turn ON backlight
lcd.print("Event Counter"); // Display Text
}
void loop()
{
while(digitalRead(EVENTS) == 1); // Wait until event
delay(150); // Contact debounce
lcd.clear(); // Clear LCD
Count++; // Incement Count
snprintf(Res, 4, "%d", Count); // Covert to string
lcd.print(Res); // Display on LCD
}
Figure 5.78 Program listing
● 144
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC
The remainder of the program runs in an endless loop where the program waits until an
event occurs. A small delay is then introduced to the program to wait until the switch
contacts stop bouncing (called contact debouncing). The program then clears the LCD,
increments Count by one, converts it into a string using function snprintf and displays the
value of Count on the LCD.
Notice that we could have also used the command lcd .print(Count) to display the value
of variable Count before converting it into a string.
5 .12 .1 Description
In this project we shall be looking at the available LCD commands and display text in var-
ious formats.
5 .12 .5 Construction
The ESP32 DevKitC board is mounted on a breadboard as in Figure 5.68.
● 145
The Complete ESP32 Projects Guide
Turn backlight ON
Clear LCD
Go to column 7, row 0
Display text "At 7,0"
Go to column 7, row 1
Display text "At 7,1"
Wait 1 second
Clear LCD
Disable cursor
Display text "No cursor"
Wait 1 second
Enable cursor
Set to scroll display right to left
Wait 1 second
Clear LCD
Set cursor to column 10, row 0
Display text "HELLO"
Set back to scroll display left to right
Set Count to 100
Clear LCD
Display Count
/*************************************************************
* LCD COMMANDS
* ============
*
* This program uses various LCD commands with the aim of making
● 146
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC
//
// Set the LCD address to 0x27 and the configuration to
// 16 chars and 2 rows display
//
LiquidCrystal_I2C lcd(0x27, 16, 2); // LCD address 0x27
void setup()
{
lcd.begin(); // Initialize LCD
lcd.backlight(); // Turn ON backlight
lcd.clear(); // Clear LCD
lcd.setCursor(7, 0); // column 7, row 0
lcd.print("At 7,0"); // Display "At 7,0"
lcd.setCursor(7, 1); // Column 7, row 1
lcd.print("At 7,1"); // Display "At 7,1"
delay(1000); // Wait 1 second
lcd.clear(); // Clear LCD
lcd.noCursor(); // Disable cursor
lcd.print("No cursor"); // Display "No cursor"
delay(1000); // Wait 1 second
lcd.cursor(); // Enable cursor
lcd.scrollDisplayRight(); // Scroll right
delay(1000); // Wait 1 second
lcd.clear();
lcd.setCursor(10,0);
lcd.rightToLeft(); // Right to left
lcd.print("Hello"); // Display "Hello"
lcd.leftToRight(); // Left to right
delay(1000); // Wait 1 second
Count = 100; // Count = 100
lcd.clear(); // Clear LCD
lcd.print(Count); // Display Count
}
void loop()
● 147
The Complete ESP32 Projects Guide
{
// No code
}
Figure 5.79 Program listing
● 148
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC
5 .13 .1 Description
In this project an LED is connected to GPIO pin 23. Also a push-button switch is connected
to GPIO pin 22. The LED normally flashes every 500 ms. Pressing the button generates
and external interrupt. If the LED is flashing when the interrupt is generated then it stops
flashing. If on the other hand the LED is already stopped, then it starts to flash when the
button is pressed.
● 149
The Complete ESP32 Projects Guide
5 .13 .5 Construction
The ESP32 DevKitC, the LED, and the push-button switch are mounted on a breadboard as
in Figure 5.87.
BEGIN
Assign LED to GPIO port 23
Assign IntPin to GPIO port 22
Configure LED port as output
Configure IntPin as input
Flag = 1
DO FOREVER
IF Flag = 1 THEN
Flash the LED
● 150
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC
ELSE
Stop flashing
ENDIF
ENDDO
END
/*************************************************************
* EXTERNAL INTERRUPT
* ==================
*
* This is an example of using an external interrupt on the
* ESP32 DevKitC. In this example an LED is connected to GPIO
* port 23 through a 330 ohm resistor. In addition, a push-button
* switch is connected to GPIO pin 22 and this button is then
* configured as an interrupt pin such that pressing the button
* generates an external interrupt in the program. Normally the
* LED flashes every 500 ms. If the button is pressed when the
* LED is flashing then the flashing stops. If on the other hand
* the flashing is stopped, pressing the button will re-start
* the LED to flash.
*
*
* File: ExtInt
* Date: July 2017
* Author: Dogan Ibrahim
*************************************************************/
#define LED 23 // LED on GPIO 23
#define IntPin 22 // Interrupt pin
int Flag = 1; // LED flag
//
// Configure LED port as output, interrupt pin as input, and
// PULL-UP this pin so that is state is at normally logic HIGH.
// Also, Attach the interrupt pin IntPin to function LEDControl,
// and accept interrupts on the FALLING edge (logic HIGH to LOW)
● 151
The Complete ESP32 Projects Guide
//
// Flash the LED every 500 ms. The flashing is stopped and
// re-started by the interrupt pin. When interrupt occurs
// by pressing the IntPin, the state of variable Flag is
// changed (if 0, it becomes 1; and if 1 it becomes 0)
//
void LEDControl()
{
if(Flag == 0)
Flag = 1;
else Flag = 0;
}
//
// Flash the LED every second unless topped by the interrupt
//
void loop()
{
if(Flag == 1)
{
digitalWrite(LED, LOW); // LED OFF
delay(500); // 500 ms delay
digitalWrite(LED, HIGH); // LED ON
delay(500); // 500 ms delay
}
else
{
digitalWrite(LED, LOW); // LED OFF
}
}
● 152
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC
Then, the external interrupt pin is attached to function LEDControl, which is the interrupt
service routine in this example. Thus, when button IntPin is pressed an external interrupt
will be generated and the program will automatically jump to function LEDControl. Inside
the main program the LED flashes every 500 ms when variable Flag is 1. This variable is
toggled inside function LEDControl. Thus, when the button is pressed variable Flag chang-
es its value to 0 and the flashing stops. Pressing the button again will change Flag back to
1 and hence the flashing will start again.
RISING: The interrupt is activated on the rising edge (LOW to HIGH) transition of
the interrupt pin.
FALLING: The interrupt is activated on the FALLING edge (HIGH to LOW) of the
interrupt pin.
CHANGE: The interrupt is activated when the state of the interrupt pin changes
(HIGH to LOW or LOW to HIGH).
LOW: The interrupt is activated when the interrupt pin is LOW.
5 .14 .1 Description
In this project an LED is connected to GPIO pin 23 as in the previous project. The project
uses a timer interrupt to flash the LED at every 500 ms.
5 .14 .5 Construction
The ESP32 DevKitC and the LED are mounted on a breadboard as in Figure 4.4.
BEGIN
Assign LED to GPIO port 23
Configure LED port as output
● 153
The Complete ESP32 Projects Guide
/*************************************************************
* TIMER INTERRUPT
* ===============
*
* This is an example of using a timer interrupt on the
* ESP32 Devkitc. In this example an LED is connected to GPIO
* port 23. The LED is flashed every 500 ms inside the interrupt
* service routine.
*
*
* File: TimerInt
* Date: July 2017
* Author: Dogan Ibrahim
*************************************************************/
#define LED 23 // LED on GPIO 23
int state = 0;
//
// Configure LED port as output. We are using timer 0 (1st timer)
// in timerBegin with the prescaler set to 80 and counting mode
// is up (set to true).
//
// The clock frequency is 80 MHz, thus, by using a pre-scaler
// value of 80, we have 1 MHz, or the timer interrupt rate will
// be every microsecond. The interrupt service routine is called
// LEDControl. We are setting to call function LEDControl when
// the timer expires and a timer interrupt is generated. Because
// teh edge mode is set to true in timerAttachInterrupt function,
// interrupts will be accepted on edge of the clock.
● 154
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC
//
// In timerAlarmWrite function the timer alarm value is set to
// 500 ms and auto repeat is set to be true so that the interrupt
// service routine (LEDControl) will be called every 500 ms (
// remember that 1 second is equal to 1000000 microseconds).
//
//
void setup()
{
pinMode(LED, OUTPUT); // LED is output
timer = timerBegin(0, 80, true); // Timer every microsecond
timerAttachInterrupt(timer, &LEDControl, true);
timerAlarmWrite(timer, 500000, true);
timerAlarmEnable(timer);
}
//
// This is the timer interrupt service routine. Flash the LED
// every 500 ms
//
void LEDControl()
{
if(state == 0)
{
state = 1;
digitalWrite(LED, LOW); // LED OFF
}
else
{
state = 0;
digitalWrite(LED, HIGH); // LED ON
}
}
void loop()
{
// no code
}
Figure 5.91 Program listing
● 155
The Complete ESP32 Projects Guide
interrupt timing is one microsecond. Function LEDControl is attached to the timer inter-
rupt so that whenever the timer overflows and generates an interrupt, the program will
jump to function LEDControl automatically. Timer alarm is set to 500 ms (500000 micro-
seconds) and in auto repeat mode so that the timer interrupt repeats.
Function LEDControl basically toggles the LED such that if it is OFF it is turned ON, and
vice versa.
5 .15 PROJECT 14 – Using the Touch Sensitive Inputs – Touch Based LED
Control
5 .15 .1 Description
In this project an LED is connected to GPIO pin 23 of the ESP32 as in the previous project.
In addition, a piece of wire is connected to one of the touch sensor inputs of the ESP32. The
LED is turned ON when one touches the wire.
The ESP32 processor has 10 capacitive touch sensitive input pins that respond when
touched by hand. These pins can be used in projects in which external devices may be
required to be controlled by touching the pins. (We could use buttons instead of the touch
sensitive inputs, but buttons have limited lifetimes and also force has to be applied to ac-
tivate them.) The following pins are the touch sensitive pins of the ESP32 DevKitC. Notice
that Touch1 (T1) is not available as a touch sensitive input since this pin is pulled HIGH and
the BOOT switch is connected to this pin:
● 156
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC
5 .15 .5 Construction
The ESP32 DevKitC and the LED are mounted on a breadboard as shown in Figure 5.94. A
short piece of wire is connected to touch sensitive input GPIO pin 4 (Touch0 or T0).
● 157
The Complete ESP32 Projects Guide
BEGIN
Configure GPIO port 23 as output
Turn OFF LED
DO FOREVER
IF touch sensor input T0 is touched THEN
Turn ON LED
ELSE
Turn OFF LED
ENDIF
ENDDO
END
#define TouchPin T0
int TouchValue;
void setup()
{
Serial.begin(9600);
}
void loop()
{
TouchValue = touchRead(T0);
Serial.println(TouchValue);
delay(1000);
}
The values displayed on the PC screen are shown in Figure 5.96. The returned values were
as follows:
● 158
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC
In this project we shall assume that a value lower than 50 indicates that the wire is touched.
The program listing (program: TouchLED) of the project is shown in Figure 5.97. At the
beginning of the program, TouchPin is defined as touch sensitive input T0, integer variable
TouchValue is created, and LED is assigned to GPIO port 23. Inside the setup routine
the LED is configured as an OUTPUT and it is turned OFF. Inside the main program loop
the value returned by the touch sensitive input T0 is read into variable TouchValue. If the
returned value is less than 50 it is assumed that the wire is touched and the LED is turned
ON, otherwise the LED is turned OFF.
/****************************************************************
* TOCUCH SENSOR LED CONTROL
* =========================
*
* In this program an LED is connected to the ESP32 DevKitC
* GPIO port 23. Additionally, a piece of wire is connected
* to touch sensitive input GPIO 4 (TOUCH0, or T0). The LED
* turns ON when we touch the wire.
*
* Program: TouchLED
* Date : October, 2018
**************************************************************/
● 159
The Complete ESP32 Projects Guide
#define TouchPin T0
int TouchValue;
#define ON HIGH
#define OFF LOW
#define LED 23 // LED on port GPIO23
void setup()
{
pinMode(LED, OUTPUT); // Configure as OUTPUT
digitalWrite(LED, OFF); // LED OFF at beginning
}
void loop()
{
TouchValue = touchRead(T0); // Read touch sensitive input
if(TouchValue < 50) // If touched...
digitalWrite(LED, ON); // Turn ON LED
else // Otherwise...
digitalWrite(LED, OFF); // Turn OFF LED
}
Figure 5.97 Program listing
Tn, here, is the touch sensitive input name (T0 to T9), ISR is the function to be called when
the pin is touched to, and threshold defines the sensitivity of the touch input. Normally the
threshold is set to 40, and higher values give greater sensitivities. In the following example
code, touch sensitive input T2 is used with sensitivity set to 40, where function MyTouch
will be called when we touch input T2:
● 160
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC
5 .16 PROJECT 15 – Using the Touch Sensitive Inputs – Changing the LED
Brightness
5 .16 .1 Description
In this project an LED is connected to GPIO pin 23 and a piece of wire is connected to touch
sensitive input T0 of the ESP32 as in the previous project. A PWM waveform is sent to the
LED whose duty cycle changes as we touch (or squeeze) the wire. As a result, the bright-
ness of the LED changes accordingly.
BEGIN
Configure GPIO port 23 as output
Configure PWM channel 0
DO FOREVER
Read touch sensitive input value
Change this value to PWM duty cycle (between 0 and 255)
Send the PWM waveform to the LED
ENDDO
END
The program listing (program: TouchLED2) is shown in Figure 5.99. At the beginning of
the program the PWM parameters for channel 0 are defined and the PWM channel is con-
figured inside the setup routine. The resolution of the PWM is set to 8 and its frequency to
1000 Hz. Inside the main program loop the program reads the value returned by function
touchRead . As was shown in the previous project, the returned value is around 54 when
not touching the wire, and it goes down to 9 when we squeeze the wire. The value returned
by function touchRead is multiplied by 4 and taken away from 200 and the resulting
● 161
The Complete ESP32 Projects Guide
value is used to set the duty cycle of the PWM waveform. Therefore, when the wire is not
touched, the duty cycle is around 255 - 5*54, which is less than zero and the LED is turned
OFF. When we touch the wire the duty cycle becomes around 255 – 5*12 = 195 which turns
the LED ON. By squeezing the wire the duty cycle increases, thus making the LED brighter.
Different multiplier values can be used for different touch sensitivities.
/**************************************************************
* TOUCH SENSOR LED BRIGHTNESS CONTROL
* ===================================
*
* In this program an LED is connected to the ESP32 Devkitc
* GPIO port 23. Additionally, a piece of wire is connected
* to touch sensitive input GPIO 4 (TOUCH0, or T0). The LED
* brightness is changed by touching or squezzing the wire.
*
* Program: TouchLED2
* Date : October, 2018
************************************************************/
#define TouchPin T0
int TouchValue;
//
// PWM parameters
//
int pwmDuty;
int pwmresolution = 8;
int pwmchannel = 0;
int pwmfreq = 1000;
#define ON HIGH
#define OFF LOW
#define LED 23 // LED on port GPIO23
//
// Configure LED as output, configure the PWM channel 0
// Attach to the LED port
//
void setup()
{
pinMode(LED, OUTPUT);
ledcSetup(pwmchannel, pwmfreq, pwmresolution);
ledcAttachPin(LED, pwmchannel);
}
void loop()
● 162
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC
{
TouchValue = touchRead(T0); // Get touch value
pwmDuty = 255 - 5*TouchValue;
if(pwmDuty < 0)pwmDuty = 0; // If < 0
ledcWrite(pwmchannel, pwmDuty); // Change duty cycle
}
Figure 5.99 Program listing
5 .17 .1 Description
In this project 8 touch sensitive inputs of the ESP32 processor are used to make an elec-
tronic organ for one octave. The musical notes are generated by touching small metal
plates connected to the touch sensitive inputs via wires. A buzzer is used to generate the
required musical notes. PWM waveforms are sent to the buzzer at the correct musical note
frequencies.
● 163
The Complete ESP32 Projects Guide
BEGIN
Store musical note frequencies in an array
Configure PWM channel 0 duty cycle to 50%
Configure Buzzer as output
DO FOREVER
IF touch sensitive input T0 is touched to THEN
Generate musical note C
ELSE IF touch sensitive input T8 is touched to THEN
Generate musical note D
ELSE IF touch sensitive input T2 is touched to THEN
Generate musical note E
ELSE IF touch sensitive input T3 is touched to THEN
Generate musical note F
ELSE IF touch sensitive input T4 is touched to THEN
Generate musical note G
ELSE IF touch sensitive input T5 is touched to THEN
Generate musical note A
ELSE IF touch sensitive input T6 is touched to THEN
● 164
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC
Notes C D E F G A B C
In this project, the PWM waveform is generated at GPIO port 23, to which the buzzer is
connected. The duty cycle of this waveform is set to 50%, but its frequency is changed
depending on which touch sensitive metal panel the user touches.
Figure 5.103 shows the program listing (program: TouchOrgan). At the beginning of the
program the frequencies of the musical notes for one octave are stored in an array called
Notes. Then, the PWM parameters are defined where the duty cycle is set to 50%. Inside
the setup routine the Buzzer is configured as an output and the PWM waveform is directed
to the port that the Buzzer is connected to. The main program runs in an endless loop.
Inside this loop the 8 touch sensitive inputs are checked to see if any of these inputs are
touched to and if so the frequency of the PWM waveform is changed to the requested mu-
sical note frequency. If none of the inputs are touched to then the PWM frequency is set to
0 which silences the Buzzer. Notice here that the touchRead threshold point is taken as 30
so that the inputs are not very sensitive.
/****************************************************************
* TOUCH SENSOR ELECTRONIC ORGAN
* =============================
*
* In this program a Buzzer is connected to the ESP32 DevKitC
* GPIO port 23. Additionally, 8 small metal panels are
* connected to 8 touch sensitive inputs using wires. The musical
* notes for one octave can be played by touching the metal plates
*
* Program: TouchOrgan
* Date : October, 2018
**************************************************************/
● 165
The Complete ESP32 Projects Guide
//
// Assign musical notes to touch sensitive pins
//
#define C1 0
#define D 1
#define E 2
#define F 3
#define G 4
#define A 5
#define B 6
#define C2 7
int Notes[] = {262,294,330,349,392,440,494,523};
int TouchValue;
//
// PWM parameters
//
int pwmDuty = 127; // 50% duty cycle
int pwmresolution = 8; // 8 bit resolution
int pwmchannel = 0; // PWM channel 0
int pwmfreq = 1000; // intila frequency
#define ON HIGH
#define OFF LOW
#define BUZZER 23 // BUZZER on port GPIO23
//
// Configure BUZZER as output, configure the PWM channel 0
// Attach to the BUZZER port, set the duty cycle to 50%
//
void setup()
{
pinMode(BUZZER, OUTPUT);
ledcSetup(pwmchannel, pwmfreq, pwmresolution);
ledcWrite(pwmchannel, pwmDuty);
ledcAttachPin(BUZZER, pwmchannel);
}
//
// Check the touch sensitive inputs and generate a musical note
// depending on the touch sensitive input pin touched to
//
void loop()
{
if(touchRead(T0) < 30)
● 166
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC
ledcWriteTone(pwmchannel,Notes[C1]);
else if(touchRead(T8) < 30)
ledcWriteTone(pwmchannel, Notes[D]);
else if(touchRead(T2) < 30)
ledcWriteTone(pwmchannel, Notes[E]);
else if(touchRead(T3) < 30)
ledcWriteTone(pwmchannel, Notes[F]);
else if(touchRead(T4) < 30)
ledcWriteTone(pwmchannel, Notes[G]);
else if(touchRead(T5) < 30)
ledcWriteTone(pwmchannel, Notes[A]);
else if(touchRead(T6) < 30)
ledcWriteTone(pwmchannel, Notes[B]);
else if(touchRead(T7) < 30)
ledcWriteTone(pwmchannel, Notes[C2]);
else
ledcWriteTone(pwmchannel, 0);
}
Figure 5.103 Program listing
5 .18 PROJECT 17 – Using the SPI Bus – Digital to Analog Converter (DAC)
5 .18 .1 Description
The SPI bus is one of the commonly used protocols to connect sensors and many other
devices to microcontrollers. The SPI bus is a master-slave-type bus protocol. In this pro-
tocol, one device (the microcontroller) is designated as the master, and one or more other
devices (usually sensors) are designated as slaves. In a minimum bus configuration there
is one master and only one slave. The master establishes communication with the slaves
and controls all activity on the bus.
Figure 5.104 shows an SPI bus example with one master and three slaves. The SPI bus
uses three signals: clock (SCK), data in (SDI), and data out (SDO). SDO of the master is
connected to the SDIs of the slaves, and SDOs of the slaves are connected to the SDI of the
master. The master generates the SCK signals to enable data to be transferred on the bus.
In every clock pulse one bit of data is moved from master to slave, or from slave to master.
The communication is only between a master and a slave, and the slaves cannot commu-
nicate with each other. It is important to note that only one slave can be active at a time
since there is no mechanism to identify the slaves. Thus, slave devices have enable lines
(e.g. CS) which are normally controlled by the master. A typical communication between a
master and several slaves is as follows:
● 167
The Complete ESP32 Projects Guide
CS CS CS
Microcontroller
SLAVE 1 SLAVE 2 SLAVE 3
SPI BUS
SCK
SDI
SD
The SPI signal names are also called MISO (Master in, Slave out), and MOSI (Master out,
Slave in). Clock signal SCK is also called SCLK and the CS is also called SSEL.
Before using the SPI interface we have to define the following SPI parameters: speed, data
order, and data mode. Users should refer to the device data sheets before setting these
parameters. These parameters are defined in the function called SPISettings, in the fol-
lowing order:
The speed is the data transfer speed in Hz and it depends on the peripheral SPI device
used. The data order defines whether the MSB bit or the LSB bit will be sent out first.
By default the MSB bit is sent out first. Valid values are MSBFIRST or LSBFIRST. Data
mode defines the clock phase and polarity. There are four ways that the SPI clock can be
sampled: Mode0, Mode1, Mode2, and Mode3. Assuming that CPOL is the clock polarity and
CPHA is the clock phase the modes can be explained as follows (see Figure 5.105):
Mode0: This is the default mode. Here the clock is normally LOW (CPOL = 0) and
data is sampled when the clock goes from LOW to HIGH (i.e. on leading edge of
the clock) where CPHA = 0.
Mode1: In this mode the clock is LOW (CPOL = 0) and data is sampled when the
clock goes from HIGH to LOW (i.e. on trailing edge of the clock) where CPHA = 1.
Mode2: In this mode the clock is normally HIGH (CPOL = 1) and data is sampled
when the clock goes from HIGH to LOW (i.e. on the leading edge of the clock)
where CPHA = 0.
● 168
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC
Mode3: Here, the clock is normally HIGH (CPOL = 1) and data is sampled when
the clock goes from LOW to HIGH (i.e. on trailing edge of the clock) where CPHA
= 1.
In this project an SPI bus based DAC chip is connected to the ESP32 DevKitC development
board. The project generates square wave output with a voltage of 1 V, duty cycle of 50%,
and frequency of 1 kHz (period of 1 ms).
● 169
The Complete ESP32 Projects Guide
• 12-bit resolution
• Up to 20 MHz clock rate (SPI)
• Fast settling time of 4.5 µs
• Unity or 2x gain output
• External Vref input
• 2.7 V to 5.5 V operation
• Extended temperature range (-40 ºC to +125 ºC)
• 8-pin DIL package
Figure 5.107 shows the pin layout of the MCP4921. The pin definitions are:
The SPI port on the ESP32 DevKitC has one SPI bus port with the following GPIO pins:
Figure 5.108 shows the circuit diagram of the project. The SDI, SCK and CS inputs of the
MCP4921 are connected to GPIO pins SPI MOSI, SPI SCK, and GPIO22. The reference
voltage Vref and the supply voltage Vdd are connected to a +3.3 V pin of DevKitC. Pins
LDAC and Avss are connected to ground. The output of the DAC is connected to a PC based
oscilloscope in order to record the generated waveform.
● 170
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC
BEGIN/MAIN
Configure the SPI bus to MSB first and Mode 0
Set CS as output
Disable CS
Configure SPI
DO FOREVER
Call SendData to send 1V to DAC
Wait 0.5ms
Call SendData to send 0V to DAC
● 171
The Complete ESP32 Projects Guide
Wait 0.5ms
ENDDO
END/MAIN
BEGIN/SendData
Enable CS
Extract the HIGH byte
Send HIGH byte to DAC with Gain = 1
Extract LOW byte
Send LOW byte to DAC
Disable CS
END/SendData
/****************************************************************
* SPI BUS DIGITAL TO ANALOG CONVERTER
* ===================================
*
* This program uses the SPI bus DAC chip MCP4921. This is a 12-bit
* DAC. The program outputs a square waveform with an amplitude of 1V
* and a frequency of 1kHz (period 1ms) through the DAC.
*
* Program: SPI
* Date : October, 2018
* Author : Dogan Ibrahim
**************************************************************/
#include "SPI.h"
#define CS 22
#define ENABLE LOW
#define DISABLE HIGH
void setup()
{
pinMode(CS, OUTPUT); // CS is output
digitalWrite(CS, DISABLE); // Disable CS
SPI.begin(); // Begin SPI
SPI.beginTransaction(MySettings); // Configure SPI
}
● 172
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC
//
// Send Data to DAC through the SPI bus
//
void SendData(unsigned int MyData)
{
unsigned char xdata;
//
// Main program loop. Call function SendData to send data to the
// DAC to generate a square waveform with ferquency of 1kHz and
// duty cycle of 50%
//
void loop()
{
float V;
unsigned int OutData;
Vo = G x (Vref x Dn ) / 2n
● 173
The Complete ESP32 Projects Guide
Where G is the output gain (can be 1 or 2), Dn is the DAC input code, and n is 12. The gain
is normally set to 1 and therefore, with a +3.3 V reference voltage, the output voltage is
given by:
Vo = (3.3 x Dn ) / 4096
For example, if the input code is 0000 0000 0001 then the output voltage will be 0.805
mV. Similarly, if the input code is 0000 0000 0010 then the output voltage will be 1.61
mV. The output data of MCP4921 is presented in two bytes. As shown in Figure 5.112, the
lower byte is the data bits D0 to D7. Four lower nibble of the upper byte is the data bits D7
to D11. The bits in the higher nibble of the higher byte are used to configure the device as
follows:
BUF: this is the input buffer (0: data is unbuffered, 1: data is buffered). In most
applications the input data is set to be unbuffered.
G: This bit controls the output gain (0: Gain is 2, 1: Gain is 1).
SHDN: This is the shutdown bit (1: normal operation, 0: shutdown the device).
In normal operations the upper nibble of the higher byte is set to 0011.
The output pin of the MCP4921 was connected to a PC based oscilloscope and the waveform
is shown in Figure 5.113. It is clear from this figure that the frequency and amplitude of the
generated square waveform are 1 kHz and 1 V respectively.
● 174
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC
Notice that the MCP4921 operates with the MSB bit received/sent first and in mode SPI_
MODE0. The clock frequency is set to 2000000 Hz in this project.
5 .19 .1 Description
UART has traditionally been used for many years to establish serial communication be-
tween two or more devices. In this project a random number is generated every 3 seconds
between 1 and 255 and is sent to a UART port. Another UART port reads the generated
number and stores in a variable. This number is then displayed on the PC screen using the
serial USB interface of the ESP32 DevKitC development kit.
● 175
The Complete ESP32 Projects Guide
The UART consisting of pins GPIO23 and GPIO22 is named as Ser1 and the UART consisting
of pins GPIO5 and GPIO18 is named as Ser2. The TXD and RXD pins of Ser1 are connected
to RXD and TXD pins of Ser2 respectively.
BEGIN
Define the two UART pins
Configure the two UART ports
DO FOREVER
Generate a random number between 1 and 255
Send the number to UART port Ser1
● 176
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC
/****************************************************************
* UART COMMUNICATIONS
* ===================
*
* This program demonstrates how multiple UARTs on the ESP32 DevKitC
* development board can be used. A random number is generated between
* 1 and 255 every 3 seconds. This number is sent to a UART port where
* another UART port reads the number and stores in a variable.The
* number is then displayed on the PC screen.
*
* Program: UART
* Date : October, 2018
* Author : Dogan Ibrahim
**************************************************************/
#include "HardwareSerial.h"
#define RXD1 23 // First UART RX
#define TXD1 22 // First UART TX
#define RXD2 5 // Second UART RX
#define TXD2 18 // Second UART TX
HardwareSerial Ser1(1);
HardwareSerial Ser2(2);
void setup()
{
Serial.begin(9600); // USB port
Ser1.begin(9600, SERIAL_8N1, RXD1,TXD1); // First UART
Ser2.begin(9600, SERIAL_8N1, RXD2,TXD2); // Second UART
}
//
// This is the main program loop. Generate a random number and send
// it to a UART port. Read the same number from another UART port.
● 177
The Complete ESP32 Projects Guide
● 178
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC
5 .20 .1 Description
Data can be saved in the non-volatile flash memory of the ESP32 processor so that the
data remains there even after reset or when power is removed. (Notice that ESP32 has
no EEPROM memory but we can save data in the non-volatile flash memory as if it is an
EEPROM.) This is especially useful to save data such as configuration data, username,
password, last value of a variable (e.g. the highest or the lowest temperature) and so on.
The Arduino IDE EEPROM library is used to read and write the flash memory of ESP32. Up
to 512 bytes of flash memory can be used by this library. This means that up to 512 char-
acters can be stored permanently in the flash memory.
In this project an analog temperature sensor chip is connected to the ESP32 DevKitC. The
program runs for 60 seconds and reads the ambient temperature every second. The max-
imum temperature during this period is stored in the flash memory in the first two bytes.
Only integer temperature is considered in this project where the data is stored in ASCII
format. i.e. a two digit temperature value (e.g. 25) is stored as two digit ASCII numeric
data (e.g. as "2" and "5").
BEGIN
Define EEPROM size
Define TMP36 port number
Initialize the EEPROM
DO 60 times
Read temperature
Convert into degrees centigrade
Calculate the maximum temperature so far
Wait one second
ENDDO
Save the maximum temperature in the first 2 locations of EEPROM
Stop
END
Figure 5.119 PDL of the project
● 179
The Complete ESP32 Projects Guide
/****************************************************************
* WRITE TO FLASH MEMORY
* =====================
*
* In this program the ambient temperature is read using an analog
* temperature snesor chip. The temperature is read every second
* for 60 seconds and the maximum temperature is stored in the
* flash memory in the first two bytes of the memory in integer
* format as two digits
*
* Program: FLASH
* Date : October, 2018
* Author : Dogan Ibrahim
**************************************************************/
#include "EEPROM.h"
#define EEPROM_SIZE 2 // No of bytes to access
#define TMP36 4 // TMP36 on GPIO4
void setup()
{
EEPROM.begin(EEPROM_SIZE);
}
void loop()
{
char buffer[5]; // Buffer to store temp
int T, Temp, MaxT = 0;
float mV, Temperature;
● 180
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC
Normally data is written or read as a byte, having a value of 0 to 255. Using the functions
EEPROM .put and EEPROM .get we can write any type of data, such as integer, floating
point, structure, etc. Notice that the program returns 255 if we try to read from an EEPROM
location that data was not saved to before.
At the beginning of the program the EEPROM header file EEPROM .h is included in the pro-
gram and the number of bytes to be accessed is defined in EEPROM_SIZE as two bytes.
Inside the setup routine the EEPROM is initialised. The remainder of the program runs in
a loop which is iterated every second and runs for 60 seconds. Inside this loop the tem-
perature is read from TMP36 as an analog value and is converted into degrees Celsius and
stored in variable Temperature. This reading is then converted into integer and is stored
in a variable called T. The program then checks if this reading is greater than the existing
maximum reading and if so makes this reading to be the maximum temperature reading
so far. At the end of the loop the reading is converted into ASCII format and is stored in
character array called buffer, where buffer[0] and buffer[1] hold the MSD and LSD of
the maximum readings respectively. These two values are then written to the first two lo-
cations of the flash memory and they are saved by calling function EEPROM .commit. The
program then terminates by waiting in a loop.
5 .21 .1 Description
In this project the maximum temperature value stored in the flash memory in the previous
project is read and displayed on the PC screen.
● 181
The Complete ESP32 Projects Guide
BEGIN
Define No of bytes to be read
Initialize EEPROM
Read MSD digit
Read LSD digit
Display heading "Maximum Temperature = "
Display MSD and LSD
Stop
END
/****************************************************************
* READ FROM FLASH MEMORY
* ======================
*
* In the previous program the ambient temperature was stored as
* an integer number in the first two locations of the flash memory.
* This program reads this data and displays the maximum temperature
* on the PC screen.
*
* Program: FlashRead
* Date : October, 2018
* Author : Dogan Ibrahim
**************************************************************/
#include "EEPROM.h"
#define EEPROM_SIZE 2 // No of bytes to access
void setup()
{
Serial.begin(9600);
EEPROM.begin(EEPROM_SIZE);
}
● 182
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC
void loop()
{
char MSD, LSD;
while(1); // Stop
}
Figure 5.122 Program listing
Maximum Temperature = nn
5 .22 .1 Description
This project is similar to Project 19, but here the maximum temperature is stored as float-
ing point data in the flash memory.
● 183
The Complete ESP32 Projects Guide
/****************************************************************
* WRITE FLOATING POINT DATA TO FLASH MEMORY
* =========================================
*
* In this program the maximum temperature is stored as a floating
* point number in the flash memory
*
* Program: FLASH2
* Date : October, 2018
* Author : Dogan Ibrahim
**************************************************************/
#include "EEPROM.h"
#define EEPROM_SIZE 4 // No of bytes to access
#define TMP36 4 // TMP36 on GPIO4
void setup()
{
EEPROM.begin(EEPROM_SIZE);
}
void loop()
{
int Temp;
float mV, CTemp, MaxT = 0.0;
● 184
Chapter 5 • Simple projects using the Arduino IDE and the ESP32 DevKitC
5 .23 PROJECT 22 – Reading Floating Point Data from the Flash Memory
5 .23 .1 Description
This project is similar to Project 20, but here the temperature is read as floating point data
from the flash memory.
/****************************************************************
* READ FLOATING POINT DATA FROM FLASH MEMORY
* =========================================
*
* In this program the maximum temperature is read as a floating
* point number from the flash memory
*
* Program: ReadFlash2
* Date : October, 2018
* Author : Dogan Ibrahim
**************************************************************/
#include "EEPROM.h"
#define EEPROM_SIZE 4 // No of bytes to access
void setup()
{
Serial.begin(9600);
EEPROM.begin(EEPROM_SIZE);
}
void loop()
● 185
The Complete ESP32 Projects Guide
{
float Temp;
5 .24 Summary
In this chapter we have developed a number of simple projects using the ESP32 DevKitC.
In the next chapter we shall be looking at the development of intermediate level projects
which are more complex than the projects we have developed so far.
● 186
Chapter 6 • Intermediate projects using the Arduino IDE and the ESP32 DevKitC
6 .1 Overview
In the last chapter we have seen the development of some simple projects using the ESP32
DevKitC. In this chapter we shall be developing more complex projects using the Arduino
IDE as the development software.
As with the previous projects, the title, description, aim, block diagram and so on of all the
projects will be given.
6 .2 .1 Description
This is an ON-OFF temperature control project. A temperature sensor measures the tem-
perature of the place (e.g. a room) where the temperature is to be controlled and compares
it with a set temperature. A heater is connected to the ESP32 DevKitC through a relay. If
the measured temperature is below the set temperature then the heater is turned ON. If,
on the other hand, the measured temperature is above the set temperature then the heat-
er is turned OFF. An I2C LCD is used to show both the set temperature and the measured
temperature. In addition, a push-button switch (SetPoint) is connected to the DevKitC
and the required temperature is set using this push-button switch and the LCD. Another
push-button switch (START) is used to start the control algorithm. The temperature can be
set between 15 ºC and 30 ºC. Every time the push-button switch is pressed the set point
temperature is increased by 1 ºC and this is shown on the LCD.
6 .2 .2 The Aim
The aim of this project is to show how an ON-OFF temperature control system can be de-
signed using the ESP32 DevKitC.
6 .2 .3 Block diagram:
Figure 6.1 shows the block diagram of the project. The temperature is measured using the
DHT11 sensor chip which can measure both the temperature and the humidity (see Project
5.3). The temperature control range is between 15 ºC and 30 ºC. The push-button switch
SetPoint is used to set the required temperature so that every time the button is pressed
the set temperature goes up by 1 ºC (returns back to 15 ºC after 30 ºC). The LCD helps to
see the settings while the SetPoint button is pressed. Another button called START starts
the control algorithm. The heater is turned ON and OFF by the relay. The LCD shows both
the measured and the required temperature values every second. In addition the status of
the relay is shown as either ON or OFF.
● 187
The Complete ESP32 Projects Guide
6 .2 .4 Circuit Diagram
The circuit diagram of the system is shown in Figure 6.2. The push-button switch SetPoint is
connected to GPIO port 23. The relay is connected to GPIO port 1. The SDA and SCL pins of
the I2C LCD are connected to GPIO ports 21 and 22 respectively. The DHT11 temperature
sensor chip is connected to GPIO port 18. The START button is connected to GPIO port 19.
In this project the Relay from their Elektor Sensor Kit is used (see Figure 6.3). The relay has
3 pins: + (power supply), S (control input), and – (power supply ground). Also, the 3-pin
DHT11 sensor from the same kit is used (see Figure 6.4) to measure the temperature. The
DHT11 also has 3 pins: + (power supply), S (data output), and – (power supply ground).
● 188
Chapter 6 • Intermediate projects using the Arduino IDE and the ESP32 DevKitC
6 .2 .5 Construction
The ESP32 DevKitC board is mounted on a breadboard together with the push-button
switches and the DHT11 temperature sensor chip as shown in Figure 6.5. The I2C LCD is
connected to the DevKitC using jumper wires.
● 189
The Complete ESP32 Projects Guide
BEGIN
Assign SetPoint to GPIO port 23
Assign RELAY to GPIO port 1
Assign START to GPIO port 19
Include I2C and DHT11 libraries
Configure SetPoint and START as input ports
Configure RELAY as output port
Turn OFF the relay to start with
DO FOREVER
Read the required temperature setting
Read the temperature from DHT11
Display both the measured and the required temperatures
IF required temperature > measured temperature THEN
Turn ON relay
Display text ON
ELSE
Turn OFF relay
Display OFF
ENDIF
Wait 1 second
ENDDO
END
Figure 6.6 PDL of the project
6 .2 .7 Program Listing
The program listing of the project is shown in Figure 6.7 (program: ONOFF).
/*************************************************************
* ON-OFF TEMPERATURE CONTROL
* ==========================
*
* This is an ON-OFF temperature control project. A temperature
* sensor measures the temperature of the place (e.g. a room)
* where the temperature is to be controlled and compares it
* with a set temperature. A heater is connected to the ESP32
* Devkitc through a relay. If the measured temperature is below
* the set temperature then the heater is turned ON. If on the
* other hand the measured temperature is above the set point
* temperature then the heater is turned OFF. An I2C LCD is used
* to show both the set temperature and the measured temperature.
* In addition, a push-button switch is connected to the Devkitc
* and the required temperature is set using this push-button
* switch and the LCD. The temperature can be set between 15oC
* and 30oC. Every time the push-button switch is pressed the set
* point temperature is increased by one Degree Centigrade and
* this is shown on the LCD. The temperature control process
● 190
Chapter 6 • Intermediate projects using the Arduino IDE and the ESP32 DevKitC
//
// Set the LCD address to 0x27 and the configuration to
// 16 chars and 2 rows display. Also, initialize the LCD
// and the DHT11 sensor chip, turn the RELAY OFF to start
// with and clear the LCD
//
LiquidCrystal_I2C lcd(0x27, 16, 2); // LCD address 0x27
void setup()
{
pinMode(RELAY, OUTPUT); // Configure output
pinMode(SetPoint, INPUT); // Configure input
pinMode(START, INPUT); // Configure input
digitalWrite(RELAY, LOW); // RELAY OFF to start with
dht.begin(); // Initialize DHT11
● 191
The Complete ESP32 Projects Guide
//
// This function sets the required temperature. Pressing the
// SetPoint button increases the required temperature value by
// 1. When the required setting is reached, you should press
// the START button to exit from this function. The required
// temperature can be between 15 and 30 degrees Centigrade
//
int SetTemperature()
{
int ExitFlag = 0;
lcd.setCursor(0, 0); // Go to col 0, row 0
lcd.print("Req. Temperature"); // Display "Req. Temperature"
lcd.setCursor(0, 1); // Go to col 0, row 1
RequiredTemperature = MinTemperature;
lcd.print(RequiredTemperature); // Display req temp
//
// Main program. At the beginning the required temperature is read
// from the user. The program then implements the ON-OFF temp
// algorithm to control the temperature. Both the measured and
● 192
Chapter 6 • Intermediate projects using the Arduino IDE and the ESP32 DevKitC
6 .2 .8 Program Description
At the beginning of the program, SetPoint, RELAY, and START are assigned to GPIO ports
23, 1 and 19, respectively. Then the I2C and the DHT11 libraries are included in the pro-
gram. The required temperature range is set between MinTemperature and MaxTem-
perature, which are initialised to 15 and 30 respectively.
Inside the setup routine, RELAY is configured as an output, and SetPoint and START but-
tons are configured as inputs. The relay is turned OFF at the beginning of the program, the
DHT11 and I2C LCD libraries are initialised and the LCD is cleared.
● 193
The Complete ESP32 Projects Guide
The remaining program runs in an endless loop. At the beginning of the loop, function
SetTemperature is called once to set the required temperature. Here, variable Re-
quiredTemperature is initialised to MinTemperature and the state of button SetPoint is
checked, and every time the button is pressed variable RequiredTemperature is increment-
ed by 1 (the limits are 15 to 30). The function exits and the control algorithm starts when
the START button is pressed (see Figure 6.8).
Inside the main program the temperature is read from the DHT11 chip and both the meas-
ured temperature and the required temperature are displayed. If the required temperature
is greater than the measured temperature then the relay is turned ON (and hence the
heater connected to the relay) and the text ON is displayed at the second row of the LCD
(see Figure 6.9). If, on the other hand, the required temperature is less than the measured
temperature, then the relay is turned OFF and the text OFF is displayed at the second row
of the LCD. The above process is repeated forever after one second delay.
Notice: You must be careful and be aware of the possibility of electric shock if you intend
to use mains electricity in this project. You should seek professional advice before using
the mains power in any electronic circuit.
6 .3 .1 Description
This project shows how a Sawtooth waveform can be generated using the ESP32 DevKitC.
● 194
Chapter 6 • Intermediate projects using the Arduino IDE and the ESP32 DevKitC
6 .3 .2 The Aim
The aim of this project is to show how the DAC on the ESP32 DevKitC can be used to gen-
erate a Sawtooth waveform.
6 .3 .3 Block diagram:
Figure 6.10 shows the block diagram of the project. Here, the ESP32 processor generates
the required Sawtooth waveform as a digital signal, and then, the DAC outputs this signal
through the GPIO port reserved for the DAC.
• The processor calculates the waveform points in real-time and sends them to
the DAC.
• The waveform points are stored in a look-up table. The processor reads these
points from the table and sends them to the DAC. (This method is used to gen-
erate any arbitrary waveform, or to generate higher frequency waveforms.)The
rate at which the waveform points are sent to the DAC determines the frequency
of the waveform.
6 .3 .4 The DAC
A DAC converts digital signals to analog. Although a DAC can be an external component,
most microcontrollers have built-in DACs. For example, the ESP32 processor has two 8-bit
DACs. In external DACs, the digital input can either be in serial or in parallel form. In exter-
nal parallel converters, the width of the digital input is equal to the width of the converter.
For example, 10-bit DACs have 10 input bits. External serial DACs generally use the SPI
or the I2C bus, and a clock and a data line are used to send the data to be converted to
the DAC. Parallel converters provide much faster conversion times, but they are housed in
larger packages.
DACs are manufactured as either unipolar or bipolar as far as the output voltages are con-
cerned. Unipolar converters can only output positive voltages, whereas bipolar converters
can output both positive and negative voltages.
The relationship between the digital input-output and the voltage reference of a DAC is
given by:
● 195
The Complete ESP32 Projects Guide
VO, here, is the output voltage, Vref is the reference voltage, and n is the width of the con-
verter. For example, in an 8-bit converter with a +3.3 V reference voltage,
Thus, for example, if the input digital value is 00000001, the analog output voltage will be
12.89 mV, if the input digital value is 00000010, the analog output voltage will be 25.78
mV, and so on.
In this project we will be generating a Sawtooth waveform with the following specifications:
Output voltage: 0 to +3.3 V
6 .3 .5 Circuit Diagram
The circuit diagram of the system is shown in Figure 6.11. The ESP32 processor has two
built-in 8-bit DACs on GPIO ports 25 and 26. In this project we shall be using the one at
GPIO port 25.
6 .3 .6 Construction
The ESP32 DevKitC board is mounted on a breadboard. The analog output voltage was
displayed and captured using the PC based oscilloscope PSCGU250.
● 196
Chapter 6 • Intermediate projects using the Arduino IDE and the ESP32 DevKitC
BEGIN
Assign Sawtooth to GPIO port 25
Configure port 25 as analog
DO FOREVER
Send a step to the DAC
Wait 909 microseconds
ENDDO
END
6 .3 .8 Program Listing
The program listing of the project is shown in Figure 6.13 (program: Sawtooth).
/*************************************************************
* SAWTOOTH WAVEFORM GENERATION
* ============================
*
* In this project a Sawtooth waveform is generated through the
* DAC at GPIO port 25 of teh ESP32 Devkitc.
*
* The specifications of the generated waveform are:
* Output voltage: 0 to +3.3V
* Frequency: 100 Hz (period 10 ms)
* Step size: 0.1 ms
*
* File: Sawtooth
* Date: July 2017
* Author: Dogan Ibrahim
*************************************************************/
#define Sawtooth 25
int DAC_Value;
void setup()
{
pinMode(Sawtooth, ANALOG); // Configure as analog
}
● 197
The Complete ESP32 Projects Guide
void loop()
{
for(float i = 0; i <= 1; i=i+0.1)
{
DAC_Value = i * 255;
dacWrite(Sawtooth, DAC_Value); // Send to DAC
delayMicroseconds(909); // 909 us delay
}
}
Figure 6.13 Program listing
6 .3 .9 Program Description
At the beginning of the program Sawtooth is assigned to GPIO port 25 and it is configured
as an analog port. Inside the main program 11 steps are continuously sent to the DAC with
909 µs delay between each step. Function dacWrite is used to send the steps to the DAC.
This function has two arguments: DAC port number, and the digital value to be converted
into analog.
Figure 6.14 shows the generated Sawtooth waveform, captured on the PSCGU250 PC
based oscilloscope.
6 .4 .1 Description
This project shows how a Triangle waveform can be generated using the ESP32 DevKitC.
6 .4 .2 The Aim
The aim of this project is to show how the DAC on the ESP32 DevKitC can be used to gen-
erate a Triangle waveform.
6 .4 .3 Block diagram:
The block diagram is same as in Figure 6.10.
● 198
Chapter 6 • Intermediate projects using the Arduino IDE and the ESP32 DevKitC
In this project we will be generating a Triangle waveform with the following specifications:
Output voltage: 0 to +3.3 V
6 .4 .4 Circuit Diagram
The circuit diagram of the system is same as in Figure 6.11.
BEGIN
Assign Triangle to GPIO port 25
Configure port 25 as analog
DO FOREVER
Send a step to the DAC
Wait 454 microseconds
ENDDO
END
6 .4 .6 Program Listing
The program listing of the project is shown in Figure 6.16 (program Triangle).
/*************************************************************
* TRIANGLE WAVEFORM GENERATION
* ============================
*
* In this project a Triangle waveform is generated through the
* DAC at GPIO port 25 of teh ESP32 Devkitc.
*
* The specifications of the generated waveform are:
* Output voltage: 0 to +3.3V
* Frequency: 100 Hz (period 10 ms)
* Step size: 0.1 ms
*
* File: Triangle
* Date: July 2017
* Author: Dogan Ibrahim
*************************************************************/
#define Triangle 25
int DAC_Value;
● 199
The Complete ESP32 Projects Guide
void setup()
{
pinMode(Triangle, ANALOG); // Configure as analog
}
void loop()
{
DAC_Value = Sample * 255;
dacWrite(Triangle, DAC_Value); // Send to DAC
Sample = Sample + Inc;
if(Sample > 1.0 || Sample < 0.0)
{
Inc = -Inc;
Sample = Sample + Inc;
}
delayMicroseconds(454); // 909 us delay
}
Figure 6.16 Program listing
6 .4 .7 Program Description
At the beginning of the program, Triangle is assigned to GPIO port 25 and it is configured
as an analog port. Inside the main program samples are sent to the DAC with 454 µs delay
between each sample. Function dacWrite is used to send the samples to the DAC.
Figure 6.17 shows the generated Triangle waveform, captured on the PSCGU250 PC based
oscilloscope.
● 200
Chapter 6 • Intermediate projects using the Arduino IDE and the ESP32 DevKitC
6 .5 .1 Description
In this project a Port Expander chip (MCP23017) is used to give additional 16 I/O ports to
the ESP32 DevKitC. An LED is connected to port pin GPA0 (pin 21) of MCP23017 for test-
ing the hardware and the software where the LED is flashed ON and OFF every second. A
330 ohm current limiting resistor is used in series with the LED.
6 .5 .2 The Aim
The aim of this project is to show how the I2C commands can be used with the ESP32
DevKitC and the Arduino IDE, and also how the Port Expander chip MCP23017 can be pro-
grammed.
6 .5 .3 Block diagram:
Figure 6.18 shows the block diagram of the project where the LED is connected to one of
the ports and 15 more I/O ports are available from the MCP23017.
6 .5 .4 Circuit Diagram
The circuit diagram of the project is shown in Figure 6.19. MCP23017 is connected to ESP32
DevKitC through the I2C bus, where the SDA and the SCL lines of both devices are connect-
ed to each other and 10K pull-up resistors are used on these lines. The LED is connected to
port pin GPA0 of the MCP23017 chip. Address select bits of the MCP23017 are all connected
to ground so that the device slave address is set to 0x20.
● 201
The Complete ESP32 Projects Guide
6 .5 .5 The MCP23017
The MCP23017 is a 28 pin chip with the following features. Figure 6.20 shows a picture of
the chip. The pin configuration is shown in Figure 6.21.
● 202
Chapter 6 • Intermediate projects using the Arduino IDE and the ESP32 DevKitC
Pin Description
VSS Ground
The MCP23017 is addressed using pins A0 to A2. Table 6.2 shows the address selection. In
this project the address pins are connected to ground, thus the address of the chip is 0x20.
A2 A1 A0 Address
0 0 0 0x20
0 0 1 0x21
0 1 0 0x22
0 1 1 0x23
1 0 0 0x24
1 0 1 0x25
1 1 0 0x26
1 1 1 0x27
The MCP23017 chip has 8 internal registers that can be configured for its operation. The
device can either be operated in 16-bit mode or in two 8-bit mode by configuring bit IO-
CON.BANK. On power-up this bit is cleared which chooses the two 8-bit mode by default.
The I/O direction of the port pins are controlled with registers IODIRA (at address 0x00)
and IODIRB (at address 0x01). Clearing a bit to 0 in these registers make the correspond-
ing port pin(s) output(s). Similarly, setting a bit to 1 in these registers make the corre-
sponding port pin(s) input(s). GPIOA and GPIOB register addresses are 0x12 and 0x13
respectively. This is shown in Figure 6.22.
● 203
The Complete ESP32 Projects Guide
More information on the MCP23017 chip can be obtained from the data sheet:
http://docs-europe.electrocomponents.com/webdocs/137e/0900766b8137eed4.pdf
6 .5 .6 Construction
ESP32 DevKitC is mounted on a breadboard together with the MCP23017 Port Expander
chip and the LED as shown in Figure 6.23.
BEGIN
Include I2C library
Define slave address and register addresses
Initialize I2C bus
Configure GPIOA as output
DO FOREVER
Turn OFF LED (Send 0)
Wait 1 second
● 204
Chapter 6 • Intermediate projects using the Arduino IDE and the ESP32 DevKitC
6 .5 .8 Program Listing
The program listing of the project is shown in Figure 6.25 (program: Expander).
/*************************************************************
* PORT EXPANDER
* =============
*
* In this project an MCP23017 Port Expander chip is used to
* add 16 more I/O ports to the ESP32 Devkitc. This chip is
* interfaced to a processor via the I2C bus (SDA and SCL lines).
* 10K pull-up resistors are used at these lines. In order to
* test the hardware and teh software, an LED is connected to
* port GPA0 (pin 21) of the MCP23017 chip. The program flashes
* the LED every second.
*
*
* File: Expander
* Date: July 2017
* Author: Dogan Ibrahim
*************************************************************/
#include <Wire.h> // Include I2C library
const byte slave_addr=0x20; // MCP23017 I2C address
const byte IODIRA=0x00; // IODIRA address
const byte GPIOA=0x12; // GPIOA address
//
// This function configures the MCP23017 chip such that Port pin
// GPA0 is an output pin. PortDir is the address of the port
// direction register (IODIRA or IODIRB), and Data is the
// direction data such that 0 sets the corresponding port pin to
// output, and 1 sets the corresponding port pin to input
//
void Configure(char PortDir, char Data)
{
Wire.beginTransmission(slave_addr);
Wire.write(PortDir);
Wire.write(Data);
Wire.endTransmission();
}
● 205
The Complete ESP32 Projects Guide
//
// This function sends data to the specified port. The port can be
// GPIOA or GPIOB and data is a byte
//
void Send(char Port, char Data)
{
Wire.beginTransmission(slave_addr);
Wire.write(Port);
Wire.write(Data);
Wire.endTransmission();
}
//
// Initialize the I2C bus, configure port GPIOA as an output port
//
void setup()
{
Wire.begin();
Configure(IODIRA, 0xFE);
}
//
// Main program initializes the I2C, configures the GPIOA port
// and flashes the LED connected to port pin GPA0 every second
//
void loop()
{
Send(GPIOA, 0); // LED OFF
delay(1000); // Wait 1 second
Send(GPIOA, 1); // LED ON
delay(1000); // Wait 1 second
}
Figure 6.25 Program listing
6 .5 .9 Program Description
Sending data to an I2C slave device is a 5 step process as described below:
• Begin transmission.
• Send device address.
• Send register address.
• Send data to the register.
• End transmission.
● 206
Chapter 6 • Intermediate projects using the Arduino IDE and the ESP32 DevKitC
At the beginning of the program the I2C library is included in the program, slave address is
set to 0x20, and the IODIRA and GPIOA addresses are set to 0x00 and 0x12 respectively.
Inside the setup routine the I2C is initialised and the MCP23017 is configured so that GPIOA
pin 0 is an output port. Notice that the hexadecimal number 0xFE (binary: 1111 1110) is
sent to the register so that bit 0 is output, and all the other bits are inputs. Inside the main
program function Send is called to turn the LED ON and OFF. One second delay is inserted
between each output.
6 .6 .1 Description
In this project a mini electronic organ is designed using the ESP32 DevKitC together with a
4 x 4 keypad with16-keys to produce musical tones in one octave.
6 .6 .2 The Aim
The aim of this project is to show how a keypad can be used in an ESP32 DevKitC project
and also how a mini electronic organ can be designed using this keypad.
6 .6 .3 Block diagram:
Figure 6.26 shows the block diagram of the project where the keypad and a passive buzzer
are connected to the ESP32 DevKitC.
6 .6 .4 Circuit Diagram
Figure 6.27 shows the keypad used in this design. It basically has 16 keys, labelled from
S1 to S16 as follows:
Row 1: S1 to S4
Row 2: S5 to S8
Row 3: S9 to S12
Row 4: S13 to S16
● 207
The Complete ESP32 Projects Guide
The circuit diagram of the keypad is shown in Figure 6.28. Rows are numbered from top to
bottom as 1 to 4. Similarly, columns are numbered from left to right as 1 to 4.
The circuit diagram of the project is shown in Figure 6.29. The rows and columns of the
keypad are connected as follows (pin 1 is the top pin when the pins are on the left of the
keypad). See Figure 4.2 for the ESP32 DevKitC pin assignments.
● 208
Chapter 6 • Intermediate projects using the Arduino IDE and the ESP32 DevKitC
C4 D4 E4 F4
G4 A4 B4 C5
C4# D4# F4# G4#
A4#
Hz 261.63 277.18 293.66 311.13 329.63 349.23 370 392 415.3 440 466.16 493.88 523.25
6 .6 .5 Construction
ESP32 DevKitC is mounted on a breadboard together with the keypad and the passive
buzzer as shown in Figure 6.30.
● 209
The Complete ESP32 Projects Guide
After installing the Keypad library, you should include the header file Keypad .h in your
programs.
BEGIN
Include Keypad.h in the program
Assign BUZZER to GPIO 4
Define musical tones for an octave
Define PWM parameters
Define keypad parameters
Define the interface between the keypad and the GPIO ports
DO FOREVER
● 210
Chapter 6 • Intermediate projects using the Arduino IDE and the ESP32 DevKitC
6 .6 .7 Program Listing
Before writing the complete program it is worthwhile to construct the hardware and then
write a program that will test the keypad interface by displaying the key numbers on the
Serial Monitor of the Arduino IDE as the keys are pressed one by one. This program code
is shown in Figure 6.33 (program: TestKeypad). Run the program and press keys on the
keypad, you should see the key numbers (1 to 9 or a to g) displayed on the monitor as
shown in Figure 6.34.
BEGIN
Include Keypad.h in the program
Assign BUZZER to GPIO 4
Define musical tones for an octave
Define PWM parameters
Define keypad parameters
Define the interface between the keypad and the GPIO ports
DO FOREVER
IF a key is pressed THEN
Find the numeric value of the key
Find the required tone frequency
Send tone to the buzzer for 250 ms
ENDIF
ENDDO
END
● 211
The Complete ESP32 Projects Guide
The complete program listing of the project is shown in Figure 6.35 (program Organ).
/*************************************************************
* MINI ELECTRONIC ORGAN
* =====================
*
* In this project a 4x4 keypad is connected to the ESP32 DevKitC
* boars. In addition, a passive buzzer is connected to GPIO
* port 17. The program configures the keypad so that the
* musical notes for one octave can be played by using the
* keypad.
*
* The keypad is configured as follows (A to G are the musical
* notes):
* C4 D4 E4 F4
* G4 A4 B4 C5
* C4# D4# F4# G4#
* A4#
*
*
* File: Organ
* Date: July 2017
* Author: Dogan Ibrahim
*************************************************************/
#include "Keypad.h" // Include Keypad library
#define BUZZER 4
int Notes[] = {0,262,294,330,349,392,440,494,524,277,311,370,415,466};
//
// Define PWM parameters
● 212
Chapter 6 • Intermediate projects using the Arduino IDE and the ESP32 DevKitC
//
int duty = 127; // Duty cycle (50%)
int resolution = 8; // 8 bit resolution
int channel = 0; // Channel 0
int freq = 1000; // To start with
//
// Define Keypad parameters
//
const byte Rows = 4; // Number of rows
const byte Cols = 4; // Number of columns
//
// Define the keymap on the keypad
//
char keys[Rows][Cols] =
{
{‘1’, ‘2’, ‘3’, ‘4’},
{‘5’, ‘6’, ‘7’, ‘8’},
{‘9’, ‘a’, ‘b’, ‘c’},
{‘d’, ‘e’, ‘f’, ‘g’}
};
//
// Define the Keypad connections for the rows and columns
//
byte rowPins[Rows] = {18, 5, 17, 16}; // Rows 1 to 4
byte colPins[Cols] = {19, 21, 22, 23}; // Cols 1 to 4
//
// Initialize the Keypad library with the row and columns defs.
// Here, we have to specify the key map name (keys), row pin
// assignments to GPIO ports (rowPins), and the column pin
// assignments to GPIO ports (colPins)
//
Keypad kpd=Keypad(makeKeymap(keys),rowPins,colPins,Rows,Cols);
//
// Configure BUZZER as an output port. Also, configure the PWM
//
void setup()
{
pinMode(BUZZER, OUTPUT);
ledcSetup(channel, freq, resolution);
ledcAttachPin(BUZZER, channel);
}
● 213
The Complete ESP32 Projects Guide
//
// Inside the main program, look for a key press. When a key is
// pressed, get its code, convert to a number, find the frequency
// corresponding to this number, and then activate the buzzer by
// sending it the reuired frequency. The buzzer sounds for 250 ms
// where after this time the buzzer stops.
//
void loop()
{
char keypressed = kpd.getKey(); // Look for key press
if(keypressed != NO_KEY) // If a key is pressed
{
if(keypressed >= ‘a’) // Convert to a number
keypressed = keypressed - ‘a’ + 10;
else keypressed -= ‘0’;
6 .6 .8 Program Description
At the beginning of the program, header file Keypad .h is included in the program, BUZZER
is assigned to GPIO port 4, and the frequencies of musical notes for one octave are stored
in array Notes (the first element of the array is not used). Then the PWM parameters for
generating musical tones are defined where the duty cycle is set to 50%, resolution to 8
bits, the frequency to 1000 Hz temporarily, and PWM channel 0 is selected.
The keypad is configured having 4 rows and 4 columns. Character array keys define the
characters to be received by the program when a key is pressed on the keypad. For exam-
ple, pressing the key at the top left hand of the keypad (S1) will send the character ‘1’ to
the program. The interface between the GPIO ports and the keypad are defined in array
rowPins for rows 1 to 4, and colPins for columns 1 to 4 respectively. For example, in the
following statement, row 1 is connected to GPIO port 18, row 2 to GPIO port 5 and so on.
Inside the main program we look for a key press by using the statement kpd .getKey.
When a key is pressed remember that what is received by the program is a character be-
tween ‘1’ and ‘9’ or ‘a’ and ‘g’. This character is converted into a numeric value between 1
and 13 and used as an index to array Notes to get the required tone frequency. This tone
● 214
Chapter 6 • Intermediate projects using the Arduino IDE and the ESP32 DevKitC
is then sent to the buzzer, which is set to sound for 250 ms. After this time the duty cycle
is set to 0, which stops the buzzer sounding.
6 .7 .1 Description
In this project a simple integer calculator is designed. The calculator can add, subtract,
multiply, and divide integer numbers and show the results on the LCD. The operation of the
calculator is as follows: when power is applied to the system, the LCD displays text CAL-
CULATOR for 2 seconds. Then the text No1: is displayed in first row of the LCD and the
user is expected to type the first number and then press the ENTER key. Then text No2: is
displayed in the second row of the LCD where the user enters the second number and the
user presses the ENTER key. After this the required operation key should be pressed. The
result will be displayed on the LCD for 5 seconds and then the LCD will be cleared, ready
for the next calculation. The example below shows how numbers 12 and 20 can be added
(characters entered by the user are in bold for clarity):
No1: 15 ENTER
No2: 20 ENTER
Op: +
Res = 35
1 2 3 4
5 6 7 8
9 0 ENTER
+ - X /
6 .7 .2 The Aim
The aim of this project is to show how a keypad and an I2C LCD can be used together in a
project, and also how a simple calculator can be designed.
6 .7 .3 Block diagram:
Figure 6.36 shows the block diagram of the project where the keypad and the I2C LCD are
connected to the ESP32 DevKitC.
● 215
The Complete ESP32 Projects Guide
ESP32 LCD
Devkitc
KEYPAD
6 .7 .4 Circuit Diagram
The circuit diagram of the project is shown in Figure 6.37. The rows and columns of the
keypad are connected as follows (pin 1 is the top pin when the pins are on the left of the
keypad). See Figure 4.2 for the ESP32 DevKitC pin assignments. Notice that the connec-
tions here are different to the ones in the previous project since pins 21 and 22 are used
by the I2C LCD module.
The I2C LCD pins SDA and SCL are connected to GPIO pins 21 and 22 respectively.
● 216
Chapter 6 • Intermediate projects using the Arduino IDE and the ESP32 DevKitC
6 .7 .5 Construction
ESP32 DevKitC is mounted on a breadboard together with the keypad and the I2C LCD as
shown in Figure 6.38.
BEGIN
Include the Keypad and the I2C libraries
Define the keypad and the I2C LCD connections
Initialize the LCD
Initialize the Keypad
Display heading CALCULATOR
DO FOREVER
Display No1:
Read the first number and save in Op1
Display No2:
Read the second number and store in Op2
Display Op:
Read the required operation
Perform the required operation
Display the result on the LCD
ENDDO
END
● 217
The Complete ESP32 Projects Guide
6 .7 .7 Program Listing
Before writing the complete program it is worthwhile to construct the hardware and then
write a program that will test the keypad interface by displaying the key numbers on the
Serial Monitor of the Arduino IDE as the keys are pressed one by one. This program code
is shown in Figure 6.40 (program: TestKeypad2). Run the program and press keys on the
keypad, you should see the key numbers (1 to 9 or a to g) displayed on the Serial Monitor.
/*************************************************************
* CALCULATOR WITH KEYPAD AND LCD
* ==============================
*
* In this project a 4x4 keypad is connected to the ESP32 Devkitc
* boars. In addition, an I2C LCD is connected. The program is a
* simple integer calculator that can perform the arithmetic
* operations of addition, subtraction, multiplication and
* division.
*
* The keypad is configured as follows (the key between 0 and
* ENTER is not used:
*
* 1 2 3 4
* 5 6 7 8
* 9 0 ENTER
* + - X /
*
*
* File: Testkeypad2
* Date: July 2017
* Author: Dogan Ibrahim
*************************************************************/
#include "Keypad.h" // Include Keypad library
//
// Define Keypad parameters
//
const byte Rows = 4; // Number of rows
const byte Cols = 4; // Number of columns
//
// Define the keymap on the keypad
//
char keys[Rows][Cols] =
{
{‘1’, ‘2’, ‘3’, ‘4’},
{‘5’, ‘6’, ‘7’, ‘8’},
{‘9’, ‘0’, ‘ ‘, ‘E’},
{‘+’, ‘-’, ‘X’, ‘/’}
};
● 218
Chapter 6 • Intermediate projects using the Arduino IDE and the ESP32 DevKitC
//
// Define the Keypad connections for the rows and columns
//
byte rowPins[Rows] = {17, 16, 4, 0}; // Rows 1 to 4
byte colPins[Cols] = {5, 18, 19, 23}; // Cols 1 to 4
//
// Initialize the Keypad library with the row and columns defs.
// Here, we have to specify the key map name (keys), row pin
// assignments to GPIO ports (rowPins), and the column pin
// assignments to GPIO ports (colPins)
//
Keypad kpd=Keypad(makeKeymap(keys),rowPins,colPins,Rows,Cols);
void setup()
{
Serial.begin(9600);
}
void loop()
{
char keypressed = kpd.getKey(); // Look for key press
if(keypressed != NO_KEY) // If a key is pressed
{
Serial.print(keypressed); // Display on Serial Monitor
}
}
Figure 6.40 Keypad test program
The complete program listing of the project is shown in Figure 6.41 (program Calculator).
/*************************************************************
* CALCULATOR WITH KEYPAD AND LCD
* ==============================
*
* In this project a 4x4 keypad is connected to the ESP32 Devkitc
* boars. In addition, an I2C LCD is connected. The program is a
* simple integer calculator that can perform the arithmetic
* operations of addition, subtraction, multiplication and
* division.
*
* The keypad is configured as follows (the key between 0 and
* ENTER is not used:
*
* 1 2 3 4
● 219
The Complete ESP32 Projects Guide
* 5 6 7 8
* 9 0 ENTER
* + - X /
*
*
* File: Calculator
* Date: July 2017
* Author: Dogan Ibrahim
*************************************************************/
#include "Keypad.h" // Include Keypad library
#include <Wire.h> // Include I2C library
#include <LiquidCrystal_I2C.h>
//
// Keypad non-numeric keys
//
#define Enter ‘E’
#define Plus ‘+’
#define Minus ‘-’
#define Multiply ‘*’
#define Divide ‘/’
//
// Set the LCD address to 0x27 and the configuration to 16 chars
// by 2 rows display
//
LiquidCrystal_I2C lcd(0x27, 16, 2);
//
// Define Keypad parameters
//
const byte Rows = 4; // Number of rows
const byte Cols = 4; // Number of columns
//
// Define the keymap on the keypad
//
char keys[Rows][Cols] =
{
{‘1’, ‘2’, ‘3’, ‘4’},
{‘5’, ‘6’, ‘7’, ‘8’},
{‘9’, ‘0’, ‘ ‘, ‘E’},
{‘+’, ‘-’, ‘*’, ‘/’}
};
//
// Define the Keypad connections for the rows and columns
//
● 220
Chapter 6 • Intermediate projects using the Arduino IDE and the ESP32 DevKitC
char MyKey;
long Calc, Op1, Op2;
//
// Initialize the I2C LCD, turn ON backlight, clear LCD, display
// heading (CALCULATOR), wait 2 seconds and then clear LCD
//
void setup()
{
lcd.begin();
lcd.backlight();
lcd.clear();
lcd.print("CALCULATOR"); // Display heading
delay(2000);
lcd.clear();
}
//
// Inside the main program, read the first number, the second
// number, and the required operation. The program displays the
// result for 5 seconds and after this time the process is
// repeated
//
void loop()
{
Op1 = 0;
Op2 = 0;
MyKey = 0;
● 221
The Complete ESP32 Projects Guide
lcd.clear();
lcd.setCursor(0,0); // Col 0, row 0
lcd.print("Op: "); // Display Op:
do
MyKey = kpd.getKey();
while(!MyKey);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Res="); // Display "Res="
//
// Calculate the result and display on the LCD
//
switch(MyKey)
{
case Plus:
Calc = Op1 + Op2;
break;
case Minus:
Calc = Op1 - Op2;
break;
case Multiply:
Calc = Op1 * Op2;
break;
case Divide:
Calc = Op1 / Op2;
break;
}
lcd.print(Calc); // Display result
delay(5000); // Wait 5 seconds
● 222
Chapter 6 • Intermediate projects using the Arduino IDE and the ESP32 DevKitC
lcd.clear();
}
Figure 6.41 Program listing
6 .7 .8 Program Description
At the beginning of the program, header files Keypad .h, Wire .h and LiquidCrystal_i2C .h
are included. Then the non-numeric keypad keys are defined. The LCD is configured with
address 0x27, having 16 characters and 2 rows.
The keypad is configured having 4 rows and 4 columns. Character array keys define the
characters to be received by the program when a key is pressed on the keypad. For ex-
ample, pressing the key at the top left hand of the keypad (S1) will send character ‘1’ to
the program. The interface between the GPIO ports and the keypad are defined in array
rowPins for rows 1 to 4, and colPins for columns 1 to 4, respectively. For example, in the
following statement, row 1 is connected to GPIO port 17, row 2 to GPIO port 16, and so on.
Inside the setup routine text CALCULATOR is displayed for 2 seconds. The reminder of the
program code is executed forever inside the main program loop. Here, No1: is displayed
and the user is expected to enter the first integer number. The number read is stored in
variable Op1. Similarly, the second integer number is read and stored in variable Op2. The
program then prompts the user to enter the required operation after displaying text Op:.
The result is calculated using a switch statement and is displayed on the LCD in the form
Res=nn for 5 seconds. After this time the LCD is cleared and the process repeats.
Figure 6.42 shows a typical display where it is required to multiply numbers 12 and 2. The
result is displayed in Figure 6.43 as Res=24.
● 223
The Complete ESP32 Projects Guide
6 .8 .1 Description
This project uses a 4 x 4 keypad and an LCD as in the previous project to implement the
classical High-Low game. For those of you who do not know how to play the game, here are
the rules for this version of the game:
• The computer will generate a secret random number between 1 and 100.
• The top row of the LCD will display "Guess Now..".
• The player will try to guess what the number is by entering a number on the
keypad and then pressing the ENTER key.
• If the guessed number is higher than the secret number the bottom row of the
LCD will display "HIGH – Try Again".
• If the guessed number is lower than the secret number the bottom row of the
LCD will display "LOW – Try Again".
• If the player guesses the number then the bottom row will display "Well Done..".
• The program waits for 5 seconds and the game restarts automatically.
1 2 3 4
5 6 7 8
9 0 NU ENTER
NU NU NU NU
6 .8 .2 The Aim
The aim of this project is to show how a simple game can be created using a keypad and
an LCD.
● 224
Chapter 6 • Intermediate projects using the Arduino IDE and the ESP32 DevKitC
6 .8 .3 Block diagram:
The block diagram is same as in Figure 6.36.
6 .8 .4 Circuit Diagram
The circuit diagram of the project is as in Figure 6.37. The keypad and the LCD are connect-
ed to the ESP32 DevKitC as in the previous project.
6 .8 .5 Construction
ESP32 DevKitC is mounted on a breadboard together with the keypad and the I2C LCD as
shown in Figure 6.38.
BEGIN
Include the Keypad and the I2C libraries
Define the keypad and the I2C LCD connections
Initialize the LCD
Initialize the Keypad
Display heading HIGH-LOW GAME
NewNumber = 1
DO FOREVER
IF NewNumber = 1 THEN
Generate a random number between 1 and 100
NewNumber = 0
ENDIF
Display message "Guess Now"
Read a number
Calculate the difference between the generated and guessed number
IF the difference > 0 THEN
Display "HIGH – TRY AGAIN"
ELSE IF the difference < 0 THEN
Display "LOW –TRY AGAIN"
ELSE IF the difference = 0 THEN
Display "Well done"
Wait 5 seconds
NewNumber = 1
ENDIF
ENDDO
END
● 225
The Complete ESP32 Projects Guide
6 .8 .7 Program Listing
The program listing of the project is shown in Figure 6.45 (program: HighLow).
/*************************************************************
* HIGH-LOW GAME
* =============
*
* In this project a 4x4 keypad is connected to the ESP32 Devkitc
* boars. In addition, an I2C LCD is connected as in the previous
* project. This project is the classical High-Low game. The
* processor generates a random number between 1 and 100. The
* user is required to guess this number. If the number entered
* is smaller or greater than teh generated number then a
* message is displayed to help the user guess the correct number.
* The game continues until the user finds the generated number
*
* The keypad is configured as follows (NU keys are not used):
*
* 1 2 3 4
* 5 6 7 8
* 9 0 NU ENTER
* NU NU NU NU
*
*
* File: HighLow
* Date: July 2017
* Author: Dogan Ibrahim
*************************************************************/
#include "Keypad.h" // Include Keypad library
#include <Wire.h> // Include I2C library
#include <LiquidCrystal_I2C.h>
//
// Keypad non-numeric keys
//
#define Enter ‘E’
//
// Set the LCD address to 0x27 and the configuration to 16 chars
// by 2 rows display
//
LiquidCrystal_I2C lcd(0x27, 16, 2);
//
// Define Keypad parameters
//
const byte Rows = 4; // Number of rows
● 226
Chapter 6 • Intermediate projects using the Arduino IDE and the ESP32 DevKitC
long MyGuess;
char MyKey, NewGame = 1;
int Guess, Diff;
//
// Initialize the I2C LCD, turn ON backlight, clear LCD, display
// heading (HIGH-LOW GAME), wait 2 seconds and then clear LCD
//
void setup()
{
lcd.begin();
lcd.backlight();
lcd.clear();
lcd.print("HIGH-LOW GAME"); // Display heading
delay(2000);
lcd.clear();
randomSeed(10);
}
//
// Inside the main program, generate a random number between 1
// and 100. The user attempts to guess this number and sees
● 227
The Complete ESP32 Projects Guide
● 228
Chapter 6 • Intermediate projects using the Arduino IDE and the ESP32 DevKitC
6 .8 .8 Program Description
At the beginning of the program, header files Keypad .h, Wire .h and LiquidCrystal_i2C .h
are included. Then the non-numeric keypad keys are defined. The LCD is configured with
address 0x27, having 16 characters and 2 rows.
Inside the main program a random integer number is generated between 1 and 100 and
stored in variable Guess. Then, the number entered by the user is stored in variable My-
Guess. The difference between the generated number and the guessed number is stored
in variable Diff. If Diff is greater than zero, i.e. the guessed number is greater than the
generated one, the message HIGH – TRY AGAIN is displayed and the user is prompted to
try again. If Diff is less than zero, i.e. the guessed number is smaller than the generated
one, the message LOW – TRY AGAIN is displayed and the user is prompted to try again.
If on the other hand Diff is equal to zero then the guessed number is found and message
Well Done… is displayed. The game repeats with a new number after 5 seconds.
Figure 6.46, 6.47 and 6.48 show sample displays from the program.
● 229
The Complete ESP32 Projects Guide
6 .9 .1 Description
Most children learn the times tables in primary school before the age of 12. In this program
the times table is displayed on the LCD for a given number, in the following format (assum-
ing the times table for 5 is required):
1X5=5
2 X 5 = 10
3 X 5 = 15
………….
………….
12 X 5 = 60
This project uses a 4 x 4 keypad and an LCD as in the previous project. Each output is dis-
played for one second and the table runs from 1 to 12.
1 2 3 4
5 6 7 8
9 0 NU ENTER
NU NU NU NU
6 .9 .2 The Aim
The aim of this project is to teach the times table to children in a fun way.
6 .9 .3 Block diagram:
The block diagram is same as in Figure 6.36.
6 .9 .4 Circuit Diagram
The circuit diagram of the project is as in Figure 6.37. The keypad and the LCD are connect-
ed to the ESP32 DevKitC as in the previous project.
6 .9 .5 Construction
ESP32 DevKitC is mounted on a breadboard together with the keypad and the I2C LCD as
shown in Figure 6.38.
● 230
Chapter 6 • Intermediate projects using the Arduino IDE and the ESP32 DevKitC
BEGIN
Include the Keypad and the I2C libraries
Define the keypad and the I2C LCD connections
Initialize the LCD
Initialize the Keypad
Display heading TIMES TABLE
NewTable = 1
DO FOREVER
IF NewTable = 1 THEN
Prompt for the required number
NewTable = 0
ENDIF
FOR i=1 to 12
Res = i * required number
Display i, "X", required number, "=", Res
Wait 1 second
ENDFOR
NewTable = 1
ENDDO
END
6 .9 .7 Program Listing
The program listing of the project is shown in Figure 6.50 (program: TimesTable).
/*************************************************************
* LEARNING THE TIMES TABLE
* ========================
*
* In this project a 4x4 keypad is connected to the ESP32 Devkitc
* boars. In addition, an I2C LCD is connected as in the previous
* project. This project displays the times table for a chosen
* number. Each output is displayed for one second.
*
* The keypad is configured as follows (NU keys are not used):
*
* 1 2 3 4
* 5 6 7 8
* 9 0 NU ENTER
* NU NU NU NU
*
*
● 231
The Complete ESP32 Projects Guide
* File: TimesTable
* Date: July 2017
* Author: Dogan Ibrahim
*************************************************************/
#include "Keypad.h" // Include Keypad library
#include <Wire.h> // Include I2C library
#include <LiquidCrystal_I2C.h>
//
// Keypad non-numeric keys
//
#define Enter ‘E’
//
// Set the LCD address to 0x27 and the configuration to 16 chars
// by 2 rows display
//
LiquidCrystal_I2C lcd(0x27, 16, 2);
//
// Define Keypad parameters
//
const byte Rows = 4; // Number of rows
const byte Cols = 4; // Number of columns
//
// Define the keymap on the keypad
//
char keys[Rows][Cols] =
{
{‘1’, ‘2’, ‘3’, ‘4’},
{‘5’, ‘6’, ‘7’, ‘8’},
{‘9’, ‘0’, ‘ ‘, ‘E’},
{‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘}
};
//
// Define the Keypad connections for the rows and columns
//
byte rowPins[Rows] = {17, 16, 4, 0}; // Rows 1 to 4
byte colPins[Cols] = {5, 18, 19, 23}; // Cols 1 to 4
//
// Initialize the Keypad library with the row and columns defs.
// Here, we have to specify the key map name (keys), row pin
// assignments to GPIO ports (rowPins), and the column pin
// assignments to GPIO ports (colPins)
//
Keypad kpd=Keypad(makeKeymap(keys),rowPins,colPins,Rows,Cols);
● 232
Chapter 6 • Intermediate projects using the Arduino IDE and the ESP32 DevKitC
//
// Initialize the I2C LCD, turn ON backlight, clear LCD, display
// heading (TIMES TABLE) for 2 seconds
//
void setup()
{
lcd.begin();
lcd.backlight();
lcd.clear();
lcd.print("TIMES TABLE"); // Display heading
delay(2000); // Wait 2 seconds
}
//
// Inside the main program, read the number whose times table is
// required and then display the times table for this number
//
void loop()
{
if(NewTable == 1) // If new table
{
lcd.clear();
lcd.print("Which Number ?"); // No for the table
NewTable = 0;
}
MyKey = 0;
MyChoice = 0;
lcd.clear();
lcd.print("Timetable for "); // Display heading
lcd.print(MyChoice,10); // Display no
● 233
The Complete ESP32 Projects Guide
6 .9 .8 Program Description
At the beginning of the program header files Keypad .h, Wire .h and LiquidCrystal_i2C .h
are included in the program as in the previous keypad and LCD projects. Then the non-nu-
meric keypad keys are defined. The LCD is configured with address 0x27, having 16 char-
acters and 2 rows. In the setup routine LCD is initialised, backlight turned ON and the text
TIMES TABLE is displayed for 2 seconds.
Inside the main program the user is requested to enter the number of which the times table
is to be displayed and this number is stored in variable MyChoice. Then, a for loop is set
up that runs from 1 to 12 and displays the times table for the required number. When the
times table is complete the LCD is cleared and the new times table flag NewTable is set to
1 so that a new table can be displayed.
● 234
Chapter 6 • Intermediate projects using the Arduino IDE and the ESP32 DevKitC
6 .10 .1 Description
This project aims to teach basic mathematics (multiplication here) to children. Two integer
random numbers are generated between 1 and 100. These numbers are multiplied but the
result is not shown for 30 seconds. The user is expected to find the answer and compare it
with the one displayed by the program after 30 seconds.
Multiplication
26 X 5 = (wait 30 seconds)
26 X 5 = 130
6 .10 .5 Construction
ESP32 DevKitC is mounted on a breadboard together with the I2C LCD as shown in Figure
5.67.
BEGIN
Include the I2C library
Define the I2C LCD connections
Initialize the LCD
Display heading BASIC MATHS
DO FOREVER
Generate two integer random numbers between 1 and 100
Multiply these two numbers
Display the numbers but not the result of the multiplication
Wait 30 seconds
Display the result
ENDDO
END
Figure 6.52 PDL of the project
● 235
The Complete ESP32 Projects Guide
/*************************************************************
* BASIC MATHEMATICS
* =================
*
* In this project an I2C LCD is connected to the ESP32 Devkitc.
* The program generates two integer random numbers between 1 and
* 100 and multiplies these numbers. The result is not shown for
* 30 seconds where the program waits so that the user can
* calculate the result. After 30 seconds the result is displayed
* so that the user can check with his/her own result.
*
* The I2C LCD is conencted to the ESP332 Devkitc as in the
* previous projects, i.e. using the SDA and SCL I2C lines
*
* File: Maths
* Date: July 2017
* Author: Dogan Ibrahim
*************************************************************/
#include <Wire.h> // Include I2C library
#include <LiquidCrystal_I2C.h>
//
// Set the LCD address to 0x27 and the configuration to 16 chars
// by 2 rows display
//
LiquidCrystal_I2C lcd(0x27, 16, 2);
//
// Initialize the I2C LCD, turn ON backlight, clear LCD, display
// heading (MATHS) for 2 seconds
//
void setup()
{
lcd.begin(); // Initialize LCD
lcd.backlight(); // Backlight ON
lcd.clear(); // Clear LCD
lcd.print("BASIC MATHS"); // Display heading
delay(2000); // Wait 2 seconds
randomSeed(10);
}
● 236
Chapter 6 • Intermediate projects using the Arduino IDE and the ESP32 DevKitC
//
// Inside the main program, read the number whose times table is
// required and then display the times table for this number
//
void loop()
{
lcd.clear();
lcd.print("Multiplication"); // Display heading
FirstNumber = random(1, 101); // First number
SecondNumber = random(1, 101); // Second number
Res = FirstNumber * SecondNumber; // Result
lcd.setCursor(0, 1); // Go to col 0, row 1
lcd.print(" ");
lcd.setCursor(0,1);
lcd.print(FirstNumber,DEC); // Display the question
lcd.print(" X ");
lcd.print(SecondNumber, 10);
lcd.print(" = ");
delay(30000); // Wait 30 seconds
lcd.print(Res, 10);
delay(2000); // Wait 2 seconds
}
Figure 6.53 Program listing
Inside the main program two integer random numbers called FirstNumber and Second-
Number are generated and their product is stored in variable Res. The program displays
the numbers in the second row of the LCD but does not display the result for 30 seconds.
During this time the user is expected to calculate the answer. After 30 seconds the result is
displayed so that the user can compare it with their own answer.
6 .10 .9 Suggestions
Although only multiplication is used in this project, the program can be modified to include
all four operations of addition, subtraction, multiplication, and division.
Figure 6.54 shows a typical display.
● 237
The Complete ESP32 Projects Guide
6 .11 .1 Description
This is an electronic door lock project using a keypad and an LCD. A 4 digit secret number
(can be changed) is stored in the system. When power is applied to the system, the mes-
sage Enter code: is displayed. The user will have to enter the correct code in order for the
locked to be opened. In this project a relay is activated when the correct code is entered.
It is assumed that an electrical lock mechanism is connected to the relay. If the correct
code is entered then the message Door Opened will be displayed and the relay will be
activated. If a wrong code is entered then the message Wrong code will be displayed. For
security reasons, one minute delay is introduced into the system after 3 consecutive failed
attempts and the message Failed to open will be displayed. The secret code is chosen as
1234 in this example.
ESP32 LCD
Devkitc
KEYPAD
● 238
Chapter 6 • Intermediate projects using the Arduino IDE and the ESP32 DevKitC
6 .11 .5 Construction
ESP32 DevKitC is mounted on a breadboard together with the keypad, LCD, and the relay
as shown in Figure 6.57.
● 239
The Complete ESP32 Projects Guide
BEGIN
Include the Keypad and the I2C libraries
Define the keypad and the I2C LCD connections
Define the secret number
Initialize the LCD
Initialize the Keypad
Clear attempt number
DO FOREVER
Display Enter code:
Read user code
IF correct code entered THEN
Activate the relay
Wait 10 seconds
Deactivate the relay
Clear attempt number
ELSE IF wrong code entered THEN
IF 3rd attempt THEN
Display failure message
Wait for 1 minute
Clear attempt number
ELSE
Increment attempt number
Display wrong code message
Wait 2 seconds
ENDIF
ENDIF
ENDDO
END
/*************************************************************
* KEYPAD LOCK
* ===========
*
* This is an electronic lock project using a keypad, LCD, and
* a buzzer. A 4 digit secret number is stored in memory. The
* lock mechanism is electrically operated and is connected to
* a relay. The user must enter the correct code in order to
* activate the relay and open the door. If wrong code is entered
● 240
Chapter 6 • Intermediate projects using the Arduino IDE and the ESP32 DevKitC
//
// Keypad non-numeric keys
//
#define Enter ‘E’
//
// Set the LCD address to 0x27 and the configuration to 16 chars
// by 2 rows display
//
LiquidCrystal_I2C lcd(0x27, 16, 2);
//
// Define Keypad parameters
//
const byte Rows = 4; // Number of rows
const byte Cols = 4; // Number of columns
//
// Define the keymap on the keypad
//
char keys[Rows][Cols] =
{
{‘1’, ‘2’, ‘3’, ‘4’},
{‘5’, ‘6’, ‘7’, ‘8’},
● 241
The Complete ESP32 Projects Guide
//
// Define the Keypad connections for the rows and columns
//
byte rowPins[Rows] = {17, 16, 4, 0}; // Rows 1 to 4
byte colPins[Cols] = {5, 18, 19, 23}; // Cols 1 to 4
//
// Initialize the Keypad library with the row and columns defs.
// Here, we have to specify the key map name (keys), row pin
// assignments to GPIO ports (rowPins), and the column pin
// assignments to GPIO ports (colPins)
//
Keypad kpd=Keypad(makeKeymap(keys),rowPins,colPins,Rows,Cols);
//
// Initialize the I2C LCD, turn ON backlight, clear LCD
//
void setup()
{
pinMode(RELAY, OUTPUT); // Relay is output
digitalWrite(RELAY, LOW); // Relay off
lcd.begin(); // Initialize LCD
lcd.backlight(); // Backlight ON
lcd.clear(); // Clear LCD
}
//
// Inside the main program, prompt for the code to be entered.
// If the code is correct then open the door (activate the relay).
// If teh code is wrong, display message to say that it is wrong.
// After three failures stop the system for 1 minute for security.
//
void loop()
{
lcd.clear();
lcd.print("Enter code:"); // Prompt for the code
MyKey = 0;
● 242
Chapter 6 • Intermediate projects using the Arduino IDE and the ESP32 DevKitC
MyNumber = 0;
● 243
The Complete ESP32 Projects Guide
Inside the main program the message Enter code: is displayed and the user is prompted
to enter the secret code, where the user entered code is entered in variable MyNumber.
If correct number is entered then the relay is activated to open the door. If the wrong code
is entered the user has three attempts. After three attempts the system is blocked for one
minute. This is done to increase the security by discouraging the user from keeping on try-
ing different numbers. Figure 6.60 shows a sample display from the project.
6 .11 .9 Suggestions
Try to modify the program by increasing the secret number to 6 digits. Also, add a buzzer
to the system such that the buzzer sounds when a wrong number is entered.
6 .12 .1 Description
In this project an SD card module is connected to the ESP32 DevKitC. The Program gener-
ates integer random numbers every second and writes them to the SD card for 10 seconds
(i.e. 10 numbers are written to the file) with a heading. The data is written to a file called
TEST.TXT under directory NUM.
● 244
Chapter 6 • Intermediate projects using the Arduino IDE and the ESP32 DevKitC
● 245
The Complete ESP32 Projects Guide
In this project an SD card module is used as shown in Figure 6.62. This module has the
following pin layout:
GND
3+3.3 V
+5 V
CS
MOSI
SCK
MISO
GND
The circuit diagram of the project is shown in Figure 6.64. SD card module is connected to
DevKitC through the standard SPI interface. The connections between the SD card module
and the DevKitC GPIO ports are as follows:
● 246
Chapter 6 • Intermediate projects using the Arduino IDE and the ESP32 DevKitC
6 .12 .5 Construction
ESP32 DevKitC is mounted on a breadboard together with the SD card module as shown in
Figure 6.65. Jumper wires are used to connect the SD card module to the DevKitC.
BEGIN
Define SD card CS pin
Initialize SD card library
Enable the serial USB communication to the PC
Create directory NUM on SD card
Create file TEST.TXT under directory NUM
Display message on the PC screen
Write heading to the file
DO 10 times
Generate a random number
Save the generated number in the file
Wait one second
ENDDO
Display message on the PC screen
Close the file
END
● 247
The Complete ESP32 Projects Guide
/****************************************************************
* WRITE TO SD CARD
* ================
*
* In this program a standard SD card module is connected to the
* ESP32 DevKitC. The program generates random numbers every second
* and stored them on the SD card over 10 seconds (i.e. 10 numbers)
* are stored on the SD card. The data is stored in file TEST.TXT
* under directory called NUM
*
* Program: SD-CARD
* Date : October, 2018
* Author : Dogan Ibrahim
**************************************************************/
#include "SD.h"
#define SD_CS 5 // SD card CS pin
void setup()
{
Serial.begin(9600);
Serial.println(""); // New line
if(!SD.begin(SD_CS)) // Initialize SD card
{
Serial.println("Initialization failed");
while(1);
}
else
Serial.println("Initialization done");
}
//
// This is the main program. A file called TEST.TXT is created in
// directory NUM on the SD card. The program stores 10 integer random
// integer numbers in this file on the SD card
//
void loop()
{
File MyFile;
unsigned int RandomNumber;
char k;
if(SD.cardType() == CARD_NONE)
● 248
Chapter 6 • Intermediate projects using the Arduino IDE and the ESP32 DevKitC
{
Serial.println("SD card is not found");
while(1);
}
At the beginning of the program header file SD .h is included in the program and SD card
chip select pin (SD_CS) is assigned to GPIO pin 5. Inside the setup routine the SD card
library is initialised. Notice that the chip select pin must be specified as the argument of
library function SD .begin. The serial PC USB interface (Serial .begin) is also enabled so
that messages can be displayed on the PC screen while the program is running.
● 249
The Complete ESP32 Projects Guide
Inside the main program loop the program checks if there is an SD card in the card module.
The program then creates a directory called NUM on the SD card using library function
SD .mkdir. Function SD .open creates a new file or opens an existing file. This function has
two arguments: the name of the file to be created or opened, and the mode. The mode can
either be FILE_WRITE or FILE_READ. When the FILE_WRITE mode is used data is add-
ed to the end of the file if the file exists, otherwise a new file is created. Mode FILE_READ
opens an existing file in read mode. Full path must be given to the file including its directory
name. In this program the full path to the file was: /NUM/TEST .TXT. Variable MyFile
is set true if a new file has been created or an existing file is opened. Message Random
Numbers with an underline is written to the SD card as the heading. A for loop is then
setup which iterates 10 times. Inside this loop integer random numbers are generated and
are stored in the newly created file on the SD card. The program then waits for one second.
The file is closed at the end of the for loop. Closing the file physically saves the data on the
SD card. Notice that the function SD .flush() can also be used to save the data physically
on the SD card.
Figure 6.68 shows the SD card file structure after the program is run. The data displayed
on the PC screen while the program runs (this data is also stored on the SD card) is shown
in Figure 6.69.
● 250
Chapter 6 • Intermediate projects using the Arduino IDE and the ESP32 DevKitC
Some of the commonly used SD card library functions are (see website: https://www.ardui-
no.cc/en/Reference/SD for full explanation of each function and for additional functions) :
6 .13 .1 Description
In this project an SD card module is connected to the ESP32 DevKitC as in the previous
project. The program opens file TEST .TXT under directory NUM, created in the previous
project, and displays the contents of this file on the PC screen.
BEGIN
Define SD card CS pin
Initialize SD card library
Enable USB PC serial port
Open file TEST.TX in directory NIUM
DO WHILE there are data in file
Read data from file
Display data read on PC screen
ENDDO
Close file
● 251
The Complete ESP32 Projects Guide
END
/****************************************************************
* READ FROM SD CARD
* =================
*
* In this program a standard SD card module is connected to the
* ESP32 DevKitC. The program opens file TEST.TXT in directory NUM
* on the SD card and then reads and displays the contents (random
* numbers) of this file on the PC screen.
*
* Program: SD-READ
* Date : October, 2018
* Author : Dogan Ibrahim
**************************************************************/
#include "SD.h"
#define SD_CS 5 // SD card CS pin
void setup()
{
Serial.begin(9600);
Serial.println(""); // New line
if(!SD.begin(SD_CS)) // Initialize library
{
Serial.println("Initialization failed");
while(1);
}
else
Serial.println("Initialization done");
}
//
// This is the main program. File TEST.TXT is opened in directory
// NUM of the SD card and its contents are displayed on the PC screen
//
void loop()
{
File MyFile;
if(SD.cardType() == CARD_NONE)
{
● 252
Chapter 6 • Intermediate projects using the Arduino IDE and the ESP32 DevKitC
6 .14 .1 Description
Infrared (Ir) communication is usually used in applications such as in television remote
control systems and overhead projectors. This is an easy and inexpensive form of short
distance communication. Ir light is very similar to visible light, except that it has longer
wavelength and therefore it is not detectable to the human eye. Commonly, 38 kHz mod-
● 253
The Complete ESP32 Projects Guide
ulation technique is used in Ir communication (although other frequencies are also used)
where encoded data is sent from the transmitter to the receiver.
• High sensitivity
• Operating voltage +3.3 V to 5 V
• Digital output
• VCC external 3.3 V-5 V voltage (can be directly connected with the a 5 V micro-
controller and 3.3 V microcontroller)
• 10K pull-up resistor on IN pin
The transmitter is a keypad has 21 keys (see Figure 6.74). The receiver module consists
of an Ir receiver chip, two resistors and an LED and it has 3 pins: Vcc, Gnd, and IN. Figure
6.75 shows the circuit diagram of the project. Vcc and Gnd pins are connected to the +3.3
V and Gnd pins of the ESP32 respectively. IN pin is connected to GPIO pin 15 of the ESP32
DevKitC. A small relay is connected to GPIO pin 5 of the development board and is activated
when the pin is at logic HIGH.
● 254
Chapter 6 • Intermediate projects using the Arduino IDE and the ESP32 DevKitC
BEGIN
Define Ir receiver module and Relay connections
Configure relay as output and de-activate it
Enable the Ir receiver module
DO FOREVER
Receive key-code from Ir transmitter keypad
IF key code is 16753245 THEN
Activate the relay
ELSE IF key code is 16720605 THEN
De-activate the relay
ENDIF
ENDDO
END
Figure 6.76 PDL of the project
● 255
The Complete ESP32 Projects Guide
https://randomnerdtutorials.com/arduino-ir-remote-control/
• Open the Arduino IDE and copy the program given in this project.
Before developing the main program we shall be writing a program to display the key codes
returned by the library when the keys on the infrared transmitter keypad are pressed. The
program given in Figure 6.77 (program: IR) displays the key codes received by the receiver
module when a key is pressed on the transmitter keypad.
/****************************************************************
* INFRARED TRANSMITTER KEY CODES
* ==============================
*
* In this program an infrared receiver module is connected to the
* DevKitC. The program displays the key codes received by the
* module when a key is pressed on the transmitter keypad
*
* Program: IR
* Date : October, 2018
* Author : Dogan Ibrahim
**************************************************************/
#include "IRremote.h"
int IN_Pin = 15; // IN connected to GPIO15
IRrecv Receiver(IN_Pin);
decode_results results;
void setup()
{
Serial.begin(9600);
Receiver.enableIRIn(); // Enable the receiver
}
void loop()
● 256
Chapter 6 • Intermediate projects using the Arduino IDE and the ESP32 DevKitC
{
if(Receiver.decode(&results)) // Decode teh results
{
Serial.println(results.value); // Display in hexadecimal
Receiver.resume(); // Next
}
delay(200);
}
Figure 6.77 Program to display the key codes
Figure 6.78 shows the key codes for each key pressed on the transmitter keypad.
In this project pressing the top left button on the transmitter keypad activates the relay.
Similarly pressing the second button at the top left de-activates the relay (see Figure 6.79).
These buttons have the key codes 16753245 and 16720605 respectively.
● 257
The Complete ESP32 Projects Guide
The main program of the project is shown in Figure 6.80 (program: IR-RELAY). At the
beginning of the program header file IRremote.h is included in the program, Ir receiver
module and relay connections to the DevKitC are defined. Inside the setup routine the relay
is configured as an output and is de-activated at the beginning of the program, and the Ir
module is enabled. The remainder of the program runs in an endless loop waiting to receive
key codes from the Ir transmitter keypad. If the key code 16753245 is received then the
relay is activated. If, on the other hand, key code 16720605 is received, then the relay is
de-activated.
/****************************************************************
* INFRARED RELAY CONTROL
* ======================
*
* In this program an infrared receiver module is connected to the
* DevKitC. Additionally a relay is connected to GPIO port 5. The
* relay is activated and de-activated by pressing buttons on the
* transmiter keypad
*
* Program: IR-RELAY
* Date : October, 2018
* Author : Dogan Ibrahim
**************************************************************/
#include "IRremote.h"
int IN_Pin = 15; // IN connected to GPIO15
#define Relay 5 // Relay on port 5
#define ON HIGH
#define OFF LOW
IRrecv Receiver(IN_Pin);
decode_results results;
void setup()
{
pinMode(Relay, OUTPUT); // Relay is output
digitalWrite(Relay, LOW); // Relay OFF at start
Receiver.enableIRIn(); // Enable the receiver
}
//
// This is the main program loop. Read the received Ir code and then
// control the relay accordingly. Pressing the top left red button
// activates the relay, and pressing the second button from the top
// left de-activates the relay
//
void loop()
{
● 258
Chapter 6 • Intermediate projects using the Arduino IDE and the ESP32 DevKitC
Receiver.resume(); // Next
}
delay(200);
}
Figure 6.80 Program listing
switch(results.value)
{
case 16753245:
digitalWrite(Relay, ON);
break;
case 16720605:
digitalWrite(Relay, OFF);
break;
case 16769055
……….
● 259
The Complete ESP32 Projects Guide
break;
case 16738455:
…………
break;
………………..
……………….
}
Another modification could be to assign names to the keys on the transmitter keypad and
then use these names in the program as shown below. Assuming the top 3 keys at the top
are labelled from left to right as A B C:
#define A 16753245
#define B 16769565
#define C 16736925
……………………..
……………………..
switch(results.value)
{
case A:
digitalWrite(Relay, ON);
break;
case B:
digitalWrite(Relay, OFF);
break;
………………………………….
………………………………….
}
Before looking at the low power modes of the ESP32 chip, it is worthwhile to review the
basic on-chip modules of the chip. The ESP32 chip consists of the following:
● 260
Chapter 6 • Intermediate projects using the Arduino IDE and the ESP32 DevKitC
The RTC module is of interest during low power operation of chip. This module consists of
the following:
The CPU, Wi-Fi, and the Bluetooth modules require large amounts of power and they should
be disabled to conserve power. As described below briefly, the ESP32 chip can be config-
ured in 5 modes as far as the power usage is concerned:
Active mode: This is the normal working mode of the chip, in which all modules
of the chip are active. The chip consumes the maximum amount of power in this
mode.
Modem Sleep mode: In this mode the Wi-Fi and the Bluetooth modules are
OFF; other modules operate normally. This mode is used when it is not required to
transmit or receive data via the Wi-Fi or Bluetooth communications.
Light Sleep mode: In this mode the Wi-Fi and the Bluetooth are OFF, and the CPU
is in gated pause state.
Deep Sleep mode: This is the most commonly used mode when it is required
to conserve power. In this mode the CPU, Wi-Fi, Bluetooth, and the peripheral
modules are all OFF. The RTC module and the ULP processor are in ON state (the
ULP processor can be shut if desired). In this mode the CPU can be woken up by
external or internal timer events to resume operation.
Hibernation mode: In this mode all modules of the chip are in OFF state.
Even more power can be conserved if the ULP processor is programmed correctly in deep
sleep mode. This however requires assembly language programming which is beyond the
scope of this book. Interested readers can refer to an excellent article by Tam Hanna, en-
titled ESP32 Low Power - Programming the ULP coprocessor, which appeared in the
March 7 April 2018 issue of the Elektor magazine (pages 32-38).
In this section we are only interested in the Deep Sleep mode. Interested readers can ob-
tain further details on power saving modes from the following document:
● 261
The Complete ESP32 Projects Guide
When the chip is in deep sleep mode, it can be woken up by one of the following 5 trigger
signals or events:
Remember that in deep sleep mode the CPU core, main memory, Wi-Fi module, Bluetooth
module, and the peripherals are all disabled and so everything stored in the main memory
are lost. The only module that works is the RTC module and its memory. Therefore, if we
want to save data to survive the deep sleep mode then this data must be saved in the RTC
memory. Some example projects are given in the next sections to show how the deep sleep
mode can be used.
6 .16 .1 Description
In this project an LED is connected to one of the GPIO ports of ESP32 DevKitC through a
current limiting resistor. ESP32 is put into deep sleep mode for 15 seconds and when it
wakes up a counter in the RTC memory is incremented by one. The LED is then flashed at
a rate of one second where the number of flashes depends on the value of this variable.
Therefore, every time the ESP32 wakes up it flashes one more time.
● 262
Chapter 6 • Intermediate projects using the Arduino IDE and the ESP32 DevKitC
BEGIN
Define variable BootCount in RTC memory
Define LED at port 23
Configure LED as output
Set BootCount to 0
Increment BootCount
DO FOR BootCount
Turn ON LED
Wait one second
Turn OFF LED
Wait for one second
ENDDO
Configure Deep Sleep wake up time as 15 seconds
Start Deep Sleep mode
END
/****************************************************************
* DEEP SLEEP WITH LED
* ===================
*
* In this program an LED is connected to GPIO port 23 of the ESP32
* DevKitC through a 330 ohm resistor. The processor is put
* into deep sleep mode for 15 seconds and is woken up by the timer.
* The LED then flashes at a rate of one second where the
* number of flashes depends on the number of times the processor
* is woken up. For example, the LED flashes once initially, 2 times
* after 15 seconds, 3 times after 30 seconds, 4 times after 45
* seconds and so on.
*
* Program: DSLEEP
* Date : November, 2018
* Author : Dogan Ibrahim
**************************************************************/
#define us_TO_Seconds 1000000 // us to seconds
#define TIME_TO_SLEEP 15 // 15 seconds
RTC_DATA_ATTR int BootCount = 0; // BootCount
void setup()
{
● 263
The Complete ESP32 Projects Guide
//
// We never execute the following code
//
void loop()
{
}
Figure 6.83 Program listing
An ammeter was placed in series with the USB power cable (by breaking up the cable) and
the following current measurements were taken during the program execution:
● 264
Chapter 6 • Intermediate projects using the Arduino IDE and the ESP32 DevKitC
In some applications we may want to disable just the Bluetooth module. This can be done
by including the following header files and the program statements:
#include "esp_bt.h"
#include "esp_bt_main.h"
esp_bt_controller_disable();
esp_bluedroid_disable();
Similarly, the Wi-Fi module can be disabled by the following program statements:
#include "esp_wifi.h"
esp_wifi_stop();
Additionally, all of the RTC peripherals can be turned OFF by the following program state-
ments:
#include "esp_deep_sleep.h"
esp_deep_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH,ESP_PD_OPTION_OFF);
/****************************************************************
* DEEP SLEEP AND DISPLAY THE REASON FOR WAKE UP
* =============================================
*
* This program is same as program DSLEEP but here the reason for wake
* up is displayed on the PC screen
*
* Program: SREASON
* Date : November, 2018
* Author : Dogan Ibrahim
**************************************************************/
● 265
The Complete ESP32 Projects Guide
void Display_Wake_Up_Reason()
{
esp_sleep_wakeup_cause_t Reason_For_Wakeup;
Reason_For_Wakeup = esp_sleep_get_wakeup_cause();
switch(Reason_For_Wakeup)
{
case 1:
Serial.println("Wakeup cause: RTC_IO");
break;
case 2:
Serial.println("Wakeup cause: RTC_CNTL");
break;
case 3:
Serial.println("Wakeup cause: Timer");
break;
case 4:
Serial.println("Wakeup cause: Touchpad");
break;
case 5:
Serial.println("Wakeup cause: ULP program");
}
}
void setup()
{
Serial.begin(9600);
pinMode(LED, OUTPUT); // LED is output
BootCount++; // Increment count
Display_Wake_Up_Reason();
● 266
Chapter 6 • Intermediate projects using the Arduino IDE and the ESP32 DevKitC
//
// We never execute the following code
//
void loop()
{
}
Figure 6.84 Displaying the reason for wake up
6 .17 .1 Description
In this project an LED is connected to one of the GPIO ports of ESP32 DevKitC through a
current limiting resistor as in the previous example. ESP32 is put into deep sleep mode and
is woken up when touch is detected on touchpad input T0, i.e. GPIO 4 (see Section 5.15
on how the touchpad works). The LED is then flashed at a rate of one second where the
number of flashes depends on the value of this variable. Therefore, every time the ESP32
wakes up it flashes one more time.
BEGIN
Define variable BootCount in RTC memory
Define LED at port 23
Configure LED as output
Set BootCount to 0
Increment BootCount
● 267
The Complete ESP32 Projects Guide
DO FOR BootCount
Turn ON LED
Wait one second
Turn OFF LED
Wait for one second
ENDDO
Attach T0 (GPIO pin 4) to interrupt callback
Configure Deep Sleep with touchpad
Start Deep Sleep mode
END
/****************************************************************
* DEEP SLEEP AND WAKE UP BY TOUCH
* ===============================
*
* This program is same as program DSLEEP but here touchpad GPIO input
* 4 is used to wake uo the processor. On wake up, variable BootCount
* is incremented by one and the LED flashes where the number fo flashes
* is equal to the value of BootCount.
*
* Program: STOUCH
* Date : November, 2018
* Author : Dogan Ibrahim
**************************************************************/
RTC_DATA_ATTR int BootCount = 0; // BootCount
void Callback()
{
//not used
}
void setup()
{
pinMode(LED, OUTPUT); // LED is output
BootCount++; // Increment count
● 268
Chapter 6 • Intermediate projects using the Arduino IDE and the ESP32 DevKitC
//
// We never execute the following code
//
void loop()
{
}
Figure 6.86 Program listing
touch_pad_t PinTouched;
……………………………
PinTouched = esp_sleep_get_touchpad_wakeup_status();
switch(PinTouched)
{
case 0:
Serial.println("T0, GPIO 4 is touched");
break;
case 1:
Serial.println("T1, GPIO 0 is touched");
● 269
The Complete ESP32 Projects Guide
break;
…………………………………………….
…………………………………………….
case 9:
Serial.println("T9, GPIO 32 is touched");
break;
}
6 .18 .1 Description
In this project an LED is connected to one of the GPIO ports of ESP32 DevKitC through a
current limiting resistor as in the previous two examples. ESP32 is put into deep sleep mode
and is woken up when GPIO pin 4 is pulled LOW. The LED is then flashed at a rate of one
second where the number of flashes depends on the value of this variable. Therefore, every
time the ESP32 wakes up it flashes one more time.
Notice that when using external trigger to wake up from deep sleep only the RTC input-out-
put pins can be used. These are: 0, 2, 4, 12, 13, 14, 15, 25, 26, 27, 32, 33, 34, 35, 36,
37, 38, 39.
● 270
Chapter 6 • Intermediate projects using the Arduino IDE and the ESP32 DevKitC
BEGIN
Initiaize variable BootCount in RTC memory
Assign GPIO port 23 to LED
Increment BootCount
DO FOR BootCount
Turn ON LED
Wait one second
Turn OFF LED
Wait one second
ENDDO
Configure Deep Sleep with external trigger
Start Deep Sleep
END
Figure 6.89 PDL of the project
/****************************************************************
* DEEP SLEEP AND WAKE UP BY EXTERNAL TRIGGER
* ==========================================
*
* In this program an LED is conencted to GPIo pin 23 as in the
* previous two examples. Additionally, a push button switch is
* connected to GPIO pin 4 where this pin is normally at logic LOW.
* Pushing the button forces pin 4 to logic HIGH and as a result
* the processor wakes up
*
* Program: TSLEEP
* Date : November, 2018
● 271
The Complete ESP32 Projects Guide
void setup()
{
pinMode(LED, OUTPUT); // LED is output
BootCount++; // Increment count
//
// We never execute the following code
//
void loop()
{
}
Figure 6.90 Program listing
● 272
Chapter 6 • Intermediate projects using the Arduino IDE and the ESP32 DevKitC
Notice that there are two types of external triggers: ext0 and ext1. ext0 uses the RTC
peripherals and therefore requires these peripherals to be kept powered during deep sleep.
Because RTC peripherals are enabled in this mode, internal pull-up or pull-down resistors
can be used. These resistors can be configured by calling functions rtc_gpio_pullup_en
or rtc_gpio_pulldown_en.
ext1 uses the RTC controller and therefore does not need the peripherals to be powered
on. The wake up source is implemented by the RTC controller and therefore the RTC periph-
erals and the RTC memory can be powered down to conserve more power, but the internal
pull-up or pull-down resistors will be disabled. The selected pin can be used as a trigger by
specifying the following options in function esp_sleep_enable_ext1_wakeup:
In order to use the internal pull-up or pull-down resistors, we have to keep power to the
RTC peripherals during sleep. This can be done using the following function:
esp-sleep-pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON)
gpio_pullup_dis(GPIO_NUM)
gpio_pulldown_en(GPIO_NUM)
In ext1 mode the following function is used to enable deep sleep (assuming wake up is
requested when any pin is HIGH):
esp_sleep_enable_ext1_wakeup(Bitmask, ESP_EXT1_WAKEUP_ANY_HIGH)
where Bitmask is defined as the power of the pin with base 2. e.g. if GPIO pin 4 is used then
Bitmask will be 0x10 (i.e. 24). Similarly, for for GPIO 32, Bitmask will be 0x100000000
(i.e. 232).
Figure 6.91 shows the program listing (program: TSLEEP-2) using the ext1 mode of ex-
ternal trigger.
● 273
The Complete ESP32 Projects Guide
/****************************************************************
* DEEP SLEEP AND WAKE UP BY EXTERNAL TRIGGER
* ==========================================
*
* In this program ext1 mode of RTC_IO wake up is used
*
* Program: TSLEEP-2
* Date : November, 2018
* Author : Dogan Ibrahim
**************************************************************/
RTC_DATA_ATTR int BootCount = 0; // BootCount
#define Bitmask 0x10 // GPIO pin 4
void setup()
{
pinMode(LED, OUTPUT); // LED is output
BootCount++; // Increment count
//
// We never execute the following code
//
void loop()
{
}
Figure 6.91 Using ext1 mode of external trigger
● 274
Chapter 6 • Intermediate projects using the Arduino IDE and the ESP32 DevKitC
6 .19 Summary
In this chapter we have looked at the design of more complex projects using the ESP32
DevKitC with the Arduino IDE programming environment. In the next chapter we shall be
looking at the design of network-based applications again using the Arduino IDE environ-
ment for the ESP32 DevKitC.
● 275
The Complete ESP32 Projects Guide
7 .1 Overview
In last chapter we have seen the development of more complex ESP32 Devkit projects
using the Arduino IDE as the programming environment.
Wi-Fi capability is one of the powerful features and advantages of the ESP32 processor. In
this chapter we shall be looking at the Wi-Fi network applications of the ESP32 DevKitC,
again using the Arduino IDE environment.
Figure 7.1 shows a program (program: SCAN) that scans the surrounding Wi-Fi networks
and returns the various network parameters.
/*************************************************************
* SCAN WI-FI NETWORK
* ==================
*
* This program does a scan and displays the surrounding Wi-Fi
* networks. The following parameters of the found networks
* are displayed: Network name (SSID), signal strength (RSSI),
* and MAC address (BSSIDstr).
*
* File: SCAN
* Author: Dogan Ibrahim
* Date: November, 2018
*
**************************************************************/
#include "WiFi.h"
//
// Set mode to station, scan the surrounding Wi-Fi networks and
// display their details on the Serial Monitor
//
● 276
Chapter 7 • ESP32 DevKitC network programming using the Arduino IDE
void setup()
{
Serial.begin(9600);
WiFi.mode(WIFI_STA); // Mode station
void loop()
{
// no code
}
Figure 7.1 Wi-Fi network scan program
In the above program the returned data is displayed on the Serial Monitor. A sample output
is shown in Figure 7.2 (only part of the output is shown here).
● 277
The Complete ESP32 Projects Guide
Figure 7.3 shows a program (program: CONNECT) that connects to the local Wi-Fi network
with the name BTHomeSpot-XNH. In this program the connection status is displayed on the
Serial Monitor as shown in Figure 7.4.
/*************************************************************
* CONNECT TO A WI-FI NETWORK
* ==========================
*
* This program connect to the local Wi-Fi network with the
* name BTHomeSpot-XNH. The conenction status is displayed on
* the Serial Monitor.
*
*
* File: CONNECT
* Author: Dogan Ibrahim
* Date: November, 2018
*
**************************************************************/
#include "WiFi.h"
const char* ssid = "BTHomeSpot-XNH";
const char* password = "49315abseb";
//
// Set mode to station, scan the surrounding Wi-Fi networks and
// display their details on the Serial Monitor
//
● 278
Chapter 7 • ESP32 DevKitC network programming using the Arduino IDE
void setup()
{
Serial.begin(9600);
Serial.println("");
WiFi.begin(ssid, password);
while(WiFi.status() != WL_CONNECTED)
{
Serial.println("Attempting to connect...");
delay(1000);
}
Serial.println("Connected to Wi-Fi network");
}
void loop()
{
// no code
}
Figure 7.3 Connecting to a Wi-Fi network
The local IP address and the MAC address can easily be obtained after a connection is made
to a Wi-Fi network. Function WiFi.localIP() returns the local IP address. Similarly, function
WiFi.macAddress() returns the MAC address a shown in the program (CONNECT2) in Figure
7.5. Figure 7.6 shows a sample output from the program.
/*************************************************************
* CONNECT TO A WI-FI NETWORK
* ==========================
*
* This program connect to the local Wi-Fi network with the
* name BTHomeSpot-XNH. The connection status is displayed on
* the Serial Monitor. In addition, the local IP address and the
* MAC address aee displayed. The program disconnects from the
* network before stopping
*
*
* File: CONNECT2
* Author: Dogan Ibrahim
* Date: November, 2018
● 279
The Complete ESP32 Projects Guide
*
**************************************************************/
#include "WiFi.h"
const char* ssid = "BTHomeSpot-XNH";
const char* password = "49341abseb";
//
// Set mode to station, scan the surrounding Wi-Fi networks and
// display their details on the Serial Monitor
//
void setup()
{
Serial.begin(9600);
Serial.println("");
WiFi.begin(ssid, password);
while(WiFi.status() != WL_CONNECTED)
{
Serial.println("Attempting to connect...");
delay(1000);
}
Serial.println("Connected to Wi-Fi network");
//
// Display the local IP address and the MAC address, and then
// disconnect from the Wi-Fi
//
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
Serial.print("Mac address: ");
Serial.println(WiFi.macAddress());
WiFi.disconnect(true);
}
void loop()
{
// no code
}
Figure 7.5 Program to return the IP address and the MAC address
● 280
Chapter 7 • ESP32 DevKitC network programming using the Arduino IDE
Figure 7.7 shows a program (program: HTTPGet) that retrieves information from the web-
site http://httpbin.org/ip. This website returns the local IP address of the caller. At the
beginning of the program the Wi-Fi and the HTTP libraries are included in the program. The
program then connects to the local WiFi in the setup routine. Inside the main program, the
object HTTPClient is declared. Then the URL of the website is specified using the http.begin
statement. The return code of the HTTP GET request is stored in variable HttpRetCode.
Returned data is stored in variable Contents and is then displayed on the Serial Monitor
together with the HTTP return code.
/*************************************************************
* HTTP GET EXAMPLE
* ================
*
* This is an example of using the HTTP GET service to retrieve
* information from a web site. In this example the web site:
* http://httpbin.org/ip is used as an example, where this URL
* returns the local IP address. The retrieved information is
* displayed on the Serial Monitor together with the HTTP return
* code
*
* File: HTTPGet
* Author: Dogan Ibrahim
* Date: November, 2018
*
**************************************************************/
#include "WiFi.h"
#include <HTTPClient.h>
//
// Set mode to station, and connect to teh local Wi-Fi
//
void setup()
{
Serial.begin(9600);
WiFi.begin(ssid, password);
while(WiFi.status() != WL_CONNECTED)
● 281
The Complete ESP32 Projects Guide
{
Serial.println("Attempting to connect...");
delay(1000);
}
Serial.println("Connected to local Wi-Fi");
//
// Retrieve infrmation from site:
// http://httpbin.org/ip and display on the Serial Monitor
//
void loop()
{
HTTPClient http;
http.begin("http://httpbin.org/ip"); // Specify site
int HttpRetCode = http.GET(); // HTTP GET request
Figure 7.8 shows the output on the Serial Monitor. Notice that in this example the return
code is 200 which corresponds to success. Some of the other important return codes are:
200: Success
202: The request has been accepted but the processing is not complete yet
206: The request must include a range header field to indicate the desired
range
301: The requested resource has been assigned a new permanent URL and any
future
references should use the returned URL
404: No matching URL
408: Request timeout
409: There is a conflict with the resource
414: The URL is too long
500: Internal server error
505: The HTTP version is not supported
● 282
Chapter 7 • ESP32 DevKitC network programming using the Arduino IDE
Table 7.1 shows a comparison of the UDP and TCP/IP type communications.
TCP/IP UDP
Slow Fast
Used in HTTP, HTTPS, FTP etc Used in DNS, DHCP, TFTP etc
UDP and TCP/IP protocol based programs are server-client based where one node sends
data and the other node receives it and vice-versa. Data is transferred through ports where
the server and the clients must use the same port numbers.
In the next sections we shall be looking at how UDP and TCP/IP protocol based programs
can be written using for the ESP32 DevKitC, using the Arduino IDE as the program devel-
opment environment.
● 283
The Complete ESP32 Projects Guide
7 .5 .1 UDP Programs
UDP is a connectionless protocol and thus there is no need to make a connection to the
destination node before a packet can be sent to it. The communication between a server
and a client are basically as follows:
Server
Client
Notice that both the server and the client can send and receive data packets from each
other. An example is given below to show how data can be sent and received by a UDP
program.
Example 7 .1
Write a UDP program to receive a text message from a UDP client and display the message
on the Serial Monitor. Then, send the message Hello From the Server to the client. Assume
the following IP addresses and port numbers for the server and the client:
In this example, the ESP32 DevKitC is the UDP Server and the PC is the UDP Client. The
local port number is set to 5000.
Solution 7 .1
Figure 7.9 shows the test system setup with the IP addresses and the port numbers. No-
tice that we need another program to test our program. Instead of writing another ESP32
program, we can use a UDP packet program available for the PC that can send and receive
UDP and TCP/IP packets. One such program is the Packet Sender (available free of charge
at the link: https://packetsender.com/download).
● 284
Chapter 7 • ESP32 DevKitC network programming using the Arduino IDE
We will now use the Packet Sender program to send and receive UDP packets from our
ESP32 DevKitC program.
To use the program, download and extract it to a folder, then double click on file Pack-
etSender to start the program. Give a name to your test (e.g. Test packet), enter the
message to be sent to our DevKitC server program (e.g. Hello from the client), enter the
destination (DevKitC here) IP address, enter the port number, select UDP as the protocol
(see Figure 7.10).
The ESSP32 DevKitC UDP program is shown in Figure 7.11 (program: UDP). At the begin-
ning of the program libraries WiFi and WiFiUDP are included in the program, the network
name and the password of the local Wi-Fi router are specified, and the local port number
and the remote IP address are specified. Inside the setup routine connection is made to the
local network and the program is set to listen for a connection.
Inside the main program the received packet is parsed and the parameters such as the
packet length, remote IP address, and remote port number are extracted and displayed on
the Serial Monitor. The program then reads and displays the contents of the received data
packet (Hello from the client). Then the udp .printf is used to send the message Hello
from the server to the client. The program then closes the connection.
● 285
The Complete ESP32 Projects Guide
/*************************************************************
* UDP SERVER EXAMPLE
* ==================
*
* This is an UDP server example. The program sends the message
* "Hello from the Server" to an UDP client. The IP addresses
* and port numbers of the server and the client are:
*
* Server (ESP32 Devkitc) IP address: 192.168.1.156 Port: 5000
* Client (PC) IP address: 192.168.1.71
*
*
* File: UDP
* Author: Dogan Ibrahim
* Date: November, 2018
*
**************************************************************/
#include "WiFi.h"
#include <WiFiUDP.h>
//
// Set mode to station, and connect to the local Wi-Fi. Display
// the local IP address
//
void setup()
{
Serial.begin(9600);
WiFi.begin(ssid, password);
while(WiFi.status() != WL_CONNECTED)
{
Serial.println("Attempting to connect...");
delay(1000);
}
Serial.println("Connected to local Wi-Fi");
Serial.print("Local IP address is: ");
Serial.println(WiFi.localIP());
udp.begin(UDPPort); ` // listen to incoming packets
}
● 286
Chapter 7 • ESP32 DevKitC network programming using the Arduino IDE
//
// Parse the received packet and get its details, such as the
// packet size, remote IP address, and remote port number. Then
// display the contents of the received packet which is stored
// in variable Buffer
//
void loop()
{
udp.beginPacket(DestUDPAddress, UDPPort);
int packetSize=udp.parsePacket();
if(packetSize)
{
Serial.print("Received packet size is: ");
Serial.print(packetSize);
Serial.println(" characters");
Serial.print("Packet received from: ");
Serial.println(udp.remoteIP());
Serial.print("Port address is: ");
Serial.println(udp.remotePort());
}
int len = udp.read(Buffer, 80);
if(len > 0)
{
Serial.println(Buffer);
}
udp.printf("Hello from the Server");
delay(2000);
udp.endPacket();
}
Figure 7.11 Program listing
Clicking the Send button on the Packet Sender program will send the packet to the ESP32
DevKitC. Figure 7.12 shows the data received and displayed on the Serial Monitor by the
ESP32 DevKitC. Figure 7.13 shows the Packet Sender program with the UDP packet re-
ceived and sent to the ESP32 DevKitC.
● 287
The Complete ESP32 Projects Guide
7 .5 .2 TCP/IP Programs
TCP/IP is a connection based reliable protocol. An example is given in this section to show
how this protocol can be used for data exchange using the ESP32 DevKitC.
Example 7 .2
Write a TCP/IP program to receive a text message from a TCP/IP client and display the mes-
sage on the Serial Monitor. Then, send the message Hello From the Server to the client.
Assume the following IP addresses and port numbers for the server and the client:
In this example, the ESP32 DevKitC is the TCP/IP Server and the PC is the TCP/IP Client.
The local port number is set to 5000.
Solution 7 .2
The test system setup is as in Figure 7.9, but here TCP/IP is used instead of UDP. Figure
7.14 shows the program listing (program: TCP). Again, the packet sender is used to test
the program, but the protocol is set to TCP and a full-stop is inserted at the end of the
message, i.e. the message is "Hello from the client .". At the beginning of the program
the server port address is defined. Inside the setup routine connection is made to the lo-
cal Wi-Fi router, the local IP address is displayed, and the server is set to listen for client
connections. Inside the main program a packet is read from the client until the full-stop
character is detected. Then a message is sent to the client.
/*************************************************************
* TCP/IP SERVER EXAMPLE
* =====================
*
* This is a TCP/IP server example. The program sends the message
* "Hello from the Server" to a TCP/IP client. The IP addresses
* and port numbers of the server and the client are:
*
* Server (ESP32 Devkitc) IP address: 192.168.1.156 Port: 5000
* Client (PC) IP address: 192.168.1.71
*
*
* File: TCP
● 288
Chapter 7 • ESP32 DevKitC network programming using the Arduino IDE
//
// Set mode to station, and connect to the local Wi-Fi. Display
// the local IP address, and begin listening for clients
//
void setup()
{
Serial.begin(9600);
WiFi.begin(ssid, password);
while(WiFi.status() != WL_CONNECTED)
{
Serial.println("Attempting to connect...");
delay(1000);
}
Serial.println("Connected to local Wi-Fi");
Serial.print("Local IP address is: ");
Serial.println(WiFi.localIP());
server.begin(); // Begin listening for
clients
}
//
// Read the packet from the client until character "." detected,
// and then send the message "Hello from teh Server" to the
// client
//
void loop()
{
WiFiClient client = server.available(); // A client connected?
while(client.connected() && !client.available())
{ delay(1);
}
String line=client.readStringUntil(‘.’);
Serial.println(line);
● 289
The Complete ESP32 Projects Guide
}
Figure 7.14 Program listing
Clicking the Send button on the Packet Sender program will send the packet to the ESP32
DevKitC. Figure 7.15 shows the data received and displayed on the Serial Monitor by the
ESP32 DevKitC. Figure 7.16 shows the Packet Sender program with the TCP packet re-
ceived and sent to the ESP32 DevKitC.
In this program we will read the time from the NTP Client and display it every second on
the PC screen. You should install the NTP Client library (by Fabrice Weinberg, V3.1.0) as
follows before compiling the program:
• Click Sketch and then Install Library and then Manage Libraries.
• Search for NTP CLIENT and click to Install NTP Client by Fabrice Weinberg.
• Make sure that the folder NTPClient is included in directory Libraries under
your Arduino top directory.
● 290
Chapter 7 • ESP32 DevKitC network programming using the Arduino IDE
The program listing (program: NTPTIME) is shown in Figure 7.17. At the beginning of the
program the header files WiFi .h, NTPClient .h and WiFiUdp .h are included in the pro-
gram. Inside the setup routine the program connects to the local Wi-Fi and also to the NTP
Client. The remainder of the program runs continuously inside the program loop. Time is
received by calling function getFormattedTime and is stored in variable TimeNow, and
is displayed on the PC screen. Figure 7.18 shows an output from the program.
/****************************************************************
* CONNECT TO NTC CLIENT
* =====================
*
* This program connects to the local NTP Client and reads and
* displays the time in the following format: hh:mm:ss
*
* File: NTPTIME
* Author: Dogan Ibrahim
* Date: November, 2018
***************************************************************/
#include "WiFi.h"
#include "NTPClient.h"
#include "WiFiUdp.h"
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP); // NTP Client
String TimeNow;
//
// Connect to local Wi-Fi router and to the NTP Client
//
void setup()
{
Serial.begin(9600);
WiFi.begin(ssid, password);
while(WiFi.status() != WL_CONNECTED)
{
delay(1000);
}
Serial.println("");
Serial.println("Connected to Wi-Fi network");
timeClient.begin();
}
● 291
The Complete ESP32 Projects Guide
void loop()
{
timeClient.update();
TimeNow = timeClient.getFormattedTime(); // Get time
Serial.println(TimeNow); // Display time
7 .7 Summary
In this chapter we have seen network programming of the ESP32 DevKitC development
board using the Arduino IDE as the programming environment. In the next few chapters we
shall be designing projects using the DevKitC in the Arduino IDE environment.
● 292
Chapter 8 • Project – The temperature and humidity on the cloud
8 .1 Overview
In the last chapter we have seen how to write network programs for the ESP32 DevKitC
development board.
In this chapter we will be developing an interesting network based application. Here, the
system will get the ambient temperature and humidity using a sensor and will then store
this data on the cloud every 30 seconds so that it can be accessed from anywhere.
The circuit diagram of the project is as in Figure 5.12. The data output of DHT11 is con-
nected to GPIO port 23 of the ESP32 DevKitC development board. The circuit is built on a
breadboard as shown in Figure 5.13.
8 .3 The Cloud
There are several cloud services that can be used to store data (for example SparkFun,
Thingspeak, Cloudino, Bluemix etc). In this project the Thingspeak is used. This is a free
cloud service where sensor data can be stored and retrieved using simple HTTP requests.
Before using the Thingspeak we have to create an account from their website and then
log in to this account. Create a new account by entering your email address and choose a
password by opening the following link:
https://thingspeak.com/users/sign_up
You should get an email to verify and activate your account. After this, click Continue and
you should get a successful sign-up notice as shown in Figure 8.2 and you should agree to
the conditions.
● 293
The Complete ESP32 Projects Guide
Then, create a New Channel by clicking on New Channel. Fill in the form as shown in
Figure 8.3. Give the name MyWeather to the application and create two channels called
Temperature and Humidity, tick to make the channels public.
Figure 8.3 Create a New Channel (only part of the form shown)
Click Save Channel at the bottom of the form. Your channel is now ready to be used with
your data. You will now see tabs with the following names. You can click at these tabs and
see the contents to make corrections if necessary:
• Private View: This tab displays private information about your channel that only
you can see.
• Public View: If your channel is public, use this tab to display selected fields and
channel visualisations.
• Channel Settings: This tab shows all the channel options you set at creation.
You can edit, clear, or delete the channel from this tab.
• API Keys: This tab displays your channel API keys. Use the keys to read from
and write to your channel.
• Data Import/Export: This tab enables you to import and export channel data.
● 294
Chapter 8 • Project – The temperature and humidity on the cloud
You should click the API Keys tab and save your Write API and Read API keys and the
Channel ID in a safe place. The API Key and the Channel Number in this project were:
8 .4 Program Listing
At the time of writing this book, Arduino IDE supported the Thingspeak library. Using this
library makes the programming very easy. But unfortunately, the support was for only for
the Arduino hardware family and the ESP8266 processor. There was no library support for
the ESP32 processor. Because of this, we have to program from the first principles, where
the data is sent to the cloud using TCP/IP data packets.
Figure 8.4 shows the complete program listing of the project (program: CLOUD). At the
beginning of the program, library headers for the Wi_Fi and the DHT11 sensor are included.
Local Wi-Fi name and password are specified, the API key and Thingspeak host name are
defined.
Function Connect_WiFi makes connection to the local Wi-fi router. Function TempHum
reads the ambient temperature and humidity and stores in variables T and H respectively.
Inside the setup routine the DHT11 is initialised, function Connect_WiFi is called and a
connection is made to the HTTP via port 80.
The main program runs in an endless loop in which the code is executed every 30 seconds.
Here, the ambient temperature and humidity are read by calling to function TempHum,
and then the following code is used to send an HTTP GET request to the Thingspeak web-
site:
client.print("GET /update?api_key=QAAHT5XIK3ZB8736&field1=");
client.print(String(T));
client.print("&field2=");
client.print(String(H));
client.print(" HTTP/1.0\r\nHost: api.thingspeak.com\r\n\r\n");
The API key and the latest readings of the temperature and humidity are converted into
strings and are included in the HTTP GET request. Notice that field1 and field2 expect the
temperature and the humidity values to be supplied respectively. The actual string is:
GET /update?api_key=QAAHT5XIK3ZB8736&field1=String(T)&field2=String(H)
HTTP/1.0\r\nHost: api.thingspeak.com\r\n\r\n
The data is plotted automatically by the Thingspeak website. The following link can be used
to see the plotted data:
https://api.thingspeak.com/channels/YOUR_CHANNEL_ID
● 295
The Complete ESP32 Projects Guide
In this project, for example the channel ID is 265433. Therefore, the link to the data is:
https://api.thingspeak.com/channels/265433
/*************************************************************
* TEMPERATURE AND HUMIDITY ON THE CLOUD
* =====================================
*
* In this project a DHT11 type temperature and humidity sensor
* chip is connected to GPIO port 23 of the ESP32 Devkitc. The
* program reads the ambient temperature and humidity and sends
* this data to the cloud every 60 seconds where it can be
* accessed from anywhere on Earth. In addition, change of the
* temperature and the humidity can be plotted using the cloud
* services.
*
* The program uses the Thingspeak cloud service. The ESP32
* must be connected to the Wi-Fi network before we can send
* data to the cloud
*
*
* File: CLOUD
* Author: Dogan Ibrahim
* Date: November, 2018
*
**************************************************************/
#include “WiFi.h”
//
// DHT11 sensor library includes
//
#include <Adafruit_Sensor.h>
#include “DHT.h”
#define DHT11_PIN 23
#define DHTTYPE DHT11
//
// Local Wi-Fi name and password
//
const char* ssid = “BTHomeSpot-XNH”;
const char* password = “49341abseb”;
//
// Thingspeak API key, channel number, and host name
//
unsigned long myChannelNumber = 265433;
String APIKEY = “QAAHT5XIK3ZB8736”;
● 296
Chapter 8 • Project – The temperature and humidity on the cloud
int T, H;
DHT dht(DHT11_PIN, DHTTYPE);
WiFiClient client;
//
// This function connects the ESP32 Devkitc to the local Wi-Fi
// network. The network name and passwors are specifed earlier
void Connect_WiFi()
{
WiFi.begin(ssid, password);
while(WiFi.status() != WL_CONNECTED)
{
delay(1000);
}
}
//
// This function reads the ambient temperature and humidity and
// stores in variables T and H respectively
//
void TempHum()
{
H = dht.readHumidity(); // Read humidity
T = dht.readTemperature(); // Read temperature
}
//
// Initialize DHT11, connect to local Wi-Fi, connect to HTTP
//
void setup()
{
dht.begin();
Connect_WiFi();
client.connect(host, 80);
}
//
// This is the main program. Read the ambient temperature and
// humidity and send the data to Thingspeak every 30 seconds
● 297
The Complete ESP32 Projects Guide
//
void loop()
{
client.connect(host,80);
TempHum();
client.print(“GET /update?api_key=QAAHT5XIK3ZB8736&field1=”);
client.print(String(T));
client.print(“&field2=”);
client.print(String(H));
client.print(“ HTTP/1.0\r\nHost: api.thingspeak.com\r\n\r\n”);
delay(30000);
}
Figure 8.4 Program listing of the project
At the time of writing this book it was not possible to configure the graphs for example
to change the vertical or the horizontal axes, the starting date of the graphs etc. A sepa-
rate graph with the required starting date (and time) can, however, be plotted using the
following web link where the channel number and the starting date are specified (see the
Thingspeak website for more details):
HTTP://pi.thingspeak.com/channels/265433/charts/1?start=2017-07-31
It is also an option to export the graph data into a spreadsheet program like Excel and then
plot a graph of the data. This option gives more control over the configuration of the graph
type, axes, labels, etc. For example, we can export the data to Excel by clicking Data Export
and selecting file type as CSV.
8 .5 Summary
In this chapter we have developed an interesting application which gets the ambient tem-
perature and humidity using the DHT11 sensor chip, and then sends this data to the cloud
so that it can be accessed at anytime and anywhere on Earth.
● 298
Chapter 8 • Project – The temperature and humidity on the cloud
In the next chapter we will be developing a Web Server application in which two LEDs are
connected to the ESP32 DevKitC development board and they are controlled remotely from
a web application.
● 299
The Complete ESP32 Projects Guide
9 .1 Overview
In the last chapter we have seen the design and development of an interesting Wi-Fi appli-
cation which gets the ambient temperature and humidity and stores on the cloud.
In this chapter we will be developing another interesting application. Here, the system
will control remotely two LEDs connected to an ESP32 DevKitC development board using
an HTTP Web Server application. Although in this example two LEDs are used, relays can
generally be connected to DevKitC and any type of electrical equipment can be controlled
remotely.
● 300
Chapter 9 • Remote Web Based Control – Web Server
Figure 9.3 shows the structure of a web server/client setup. In this figure, the ESP32
DevKitC is the web server and the PC (or a laptop, tablet or a mobile phone) is the web
client. The device to be controlled is connected to the web server processor. In this example
we have two LEDs connected to the ESP32 DevKitC development board. The operation of
the system is as follows:
• The web server is in the listen mode, listening for requests from the web client.
• The web client makes a request to the web server by sending an HTTP request.
• In response, the web server sends an HTTP code to the web client which is acti-
vated by the web browser by the user on the web client and is shown as a form
on the web client screen.
• The user sends a command (e.g. ticks a button on the web client form to turn
ON an LED) and this sends a code to the web server so that the web server can
carry out the required operation.
● 301
The Complete ESP32 Projects Guide
In this program a laptop with IP address 192.168.1.71 is used as the web client and the
ESP32 DevKitC with the IP address 192.168.1.156 is used as the web server.
The program then defines the HTML code that is to be sent to the web client when a request
comes from it. This code is stored in variable html. When executed by the web browser
(e.g. Internet Explorer) on the web client, the display in Figure 9.5 is shown on the client
screen.
A heading is displayed at the centre of the screen and buttons are displayed at the left hand
side. Two pairs of buttons are displayed: one pair to turn ON/OFF LED0 and another pair to
turn ON/OFF LED1. The ON buttons are green, and the OFF buttons are red.
The web server program sends the html file (statement client .print(html)) to the client
and waits for a command from the client. When a button is clicked on the client, a com-
mand is sent to the web server in addition to some other data. Here, we are only interested
in the actual command sent. The following commands are sent to the web server for each
button pressed:
The web server program on the ESP32 DevKitC makes a TCP connection and reads the com-
mand from the web client as a string (String request = client .readStringUntil(‘\r’)).
The program then searches the received command to see if any of the above commands
are present in the received data. If the sub-string is not found then a -1 is returned. For
example, consider the following statement:
● 302
Chapter 9 • Remote Web Based Control – Web Server
Figure 9.5 The screen when the HTML code is executed by the client
In this project, the IP address of the web server was 192.168.1.156. The procedure to test
the system is as follows:
Figure 9.6 and Figure 9.7 show the commands sent to the web server when LED0 ON but-
ton is clicked, and also when LED0 OFF button is clicked.
/*************************************************************
* WEB SERVER TO CONTROL 2 LEDs
* ============================
*
* This is a simple web server program. 2 LEDs are connected to
* GPIO ports 23 and 22 of the ESP32 devkitc board. The project
* controls these LEDs (turns ON or OFF) from a web server
* application. For example, teh LEDs can be controlled from any
* device that is on the web, for example, a PC, tablet, mobile
* phone etc. when activated, a form will appear on the device
* with buttons and clicking these buttons will control the
* LEDs. The LEDs are named LED0 and LED1, connected to GPIO
* ports 23 and 22 respectively.
*
*
* File: WEBSERVER
* Author: Dogan Ibrahim
● 303
The Complete ESP32 Projects Guide
//
// Local Wi-Fi name and password
//
const char* ssid = "BTHomeSpot-XNH";
const char* password = "49345abseb";
WiFiServer server(80);
//
// The HTML code. This code will display two buttons on user’s
// device which can be clicked to control the LEDs
//
String html ="<!DOCTYPE html> \
<html> \
<body> \
<center><h1>ESP32 Devkitc LED ON/OFF</h1></center> \
<center><h2>Web Server Example with 2 LEDs</h2></center> \
<form> \
<button name=\"LED0\" button style=\"color:green\" value=\"ON\"
type=\"submit\">LED0 ON</button> \
<button name=\"LED0\" button style=\"color=red\" value=\"OFF\"
type=\"submit\">LED0 OFF</button><br><br> \
<button name=\"LED1\" button style=\"color:green\" value=\"ON\"
type=\"submit\">LED1 ON</button> \
<button name=\"LED1\" button style=\"color:red\" value=\"OFF\"
type=\"submit\">LED1 OFF</button> \
</form> \
</body> \
</html>";
//
// This function connects the ESP32 DevKitC to the local Wi-Fi
// network. The network name and passwors are as specifed earlier
void Connect_WiFi()
{
WiFi.begin(ssid, password);
while(WiFi.status() != WL_CONNECTED)
{
delay(1000);
}
● 304
Chapter 9 • Remote Web Based Control – Web Server
//
// Configure LEDs as outputs, turn OFF the LEDs to start with,
// Connect to the local Wi-Fi, start the server
//
void setup()
{
pinMode(LED0, OUTPUT);
pinMode(LED1, OUTPUT);
digitalWrite(LED0, LOW);
digitalWrite(LED1, LOW);
Connect_WiFi();
server.begin();
}
//
// This is teh main program loop. Inside the main program we
// check for the client connection and send the HTML file so
// that it is displayed on user’s device. The user clicks the
// buttons to control the LEDs.
//
void loop()
{
WiFiClient client=server.available();
String request = client.readStringUntil(‘\r’);
client.flush();
//
// We control the LEDs depending upon the key click. Variable
// request holds the request and we search this string to see
// which LED should be turned ON/OFF. The contents of request
// is of the form (for example, to turn OFF LED0):
// "/?LED0=OFF", or similarly, to turn LED 1: "/?LED1=ON"
//
if(request.indexOf("LED0=ON") != -1)digitalWrite(LED0, HIGH);
if(request.indexOf("LED0=OFF") != -1)digitalWrite(LED0, LOW);
if(request.indexOf("LED1=ON") != -1)digitalWrite(LED1, HIGH);
if(request.indexOf("LED1=OFF") != -1)digitalWrite(LED1, LOW);
//
// The HTML page to be displayed on user’s device
//
client.print(html);
}
Figure 9.4 Program listing of the project
● 305
The Complete ESP32 Projects Guide
We will be using a free service called ngrok in order to create a tunnel to our ESP32 so that
we can access it from anywhere in the world. First of all we have to change our default port
number from 80 to something else, e.g. 8888, since for some reason ngrok does not work
with port number 80.
• Click Auth link at the left hand side to get your unique Tunnel token as shown in
Figure 9.9. In this example author’s tunnel token is: gqudoMhDuJeXnLqVGH-
qv_7jm25SyUTtbYpnQzTk3Eb
• Click the Download tab at the top of the screen and install ngrok
● 306
Chapter 9 • Remote Web Based Control – Web Server
• Unzip file to a folder and run the ngrok .exe application. You should see a window
as in Figure 9.10.
• Enter the following command by replacing the code in < > with your own IP ad-
dress and ngrok Token:
• You should now see that your tunnel is online and a Forwarding URL will be given
as shown in Figure 9.12. In this example the Forwarding URL is: tcp://0 .tcp .
ngrok .io:17386
● 307
The Complete ESP32 Projects Guide
In order to access your web server anywhere in the world you should enter your unique URL
in a browser, which in this example is:
http://0.tcp.ngrok.io:17386
Notice that your PC must be up and running ngrok while you access your web server. You
will be asked to enter your username and password in order to open your web server.
9 .6 Summary
In this chapter we have seen an interesting web server application in which two LEDs are
controlled remotely from the web. Although in this project LEDs are used, in general relays
can be used and any electrical equipment can be controlled remotely. The chapter has also
explained how to access the web server from anywhere in the world using the free service
ngrok.
In the next chapter we will see how to control equipment remotely by sending UDP packets
from a mobile phone.
● 308
Chapter 10 • Remote control using mobile phone
10 .1 Overview
In the last chapter we have seen the design and development of an interesting Wi-Fi ap-
plication which controls two LEDs from a web server application. Although in that simple
example LEDs are used, there is no reason why relays cannot be connected instead of the
LEDs to control any kind of electrical equipment remotely.
In this chapter we will be developing another interesting application. Here, the system will
control remotely two LEDs connected to an ESP32 DevKitC development board using a mo-
bile phone. The idea here is that the DevKitC will be configured as an UDP client. Then, UDP
packets will be sent from a mobile phone to control these LEDs. As mentioned earlier, these
LEDs can be replaced by relays and the project can be used to control any kind of electrical
equipment connected to the ESP32 DevKitC.
Valid commands are as follows (any other commands are ignored by the program):
● 309
The Complete ESP32 Projects Guide
Inside the setup routine the LED ports are configured as outputs and both LEDs are turned
OFF to start with. Then function Connect_WiFi is called to connect to local Wi-Fi and UDP is
started on the local port.
● 310
Chapter 10 • Remote control using mobile phone
The remainder of the program is executed in an endless loop. Inside this loop the program
waits to receive a packet (command) from the UDP server (mobile phone here). The re-
ceived packet is stored in character array Packet and the program checks the command and
if this is a valid command, turns ON/OFF the LEDs as required.
if(Packet[1] == ‘=’)
{
if(Packet[0] == ‘0’)
{
if(Packet[2] == ‘O’ && Packet[3] == ‘N’)
{
digitalWrite(LED0, HIGH);
}
else if(Packet[2] == ‘O’ && Packet[3] == ‘F’ && Packet[4] == ‘F’)
{
digitalWrite(LED0, LOW);
}
}
else if(Packet[0] == ‘1’)
{
if(Packet[2] == ‘O’ && Packet[3] == ‘N’)
{
digitalWrite(LED1, HIGH);
}
else if(Packet[2] == ‘O’ && Packet[3] == ‘F’ && Packet[4] == ‘F’)
{
digitalWrite(LED1, LOW);
}
}
/***************************************************************
* UDP BASED CONTROL FROM MOBILE PHONE
* ===================================
*
* This is an UDP based control program where 2 LEDs are connected
* to GPIO ports 23 and 22 of the ESP32 devkitc board, and named
* as LED0 and LED1. Commands are sent from an Android type
* mobile phone to turn the LEDs ON/OFF. The ESP32 DevKitC is
* configured as an UDP client in this application. The format of
* the commands are as follows:
*
* 0=ON turn ON LED0
* 0=OFF turn OFF LED0
* 1=ON turn ON LED1
● 311
The Complete ESP32 Projects Guide
//
// LED assignments
//
#define LED0 23
#define LED1 22
WiFiUDP udp;
//
// Use local port 5000
//
const int Port = 5000;
char Packet[80];
//
// Local Wi-Fi name and password
//
const char* ssid = "BTHomeSpot-XNH";
const char* password = "49345abseb";
//
// This function connects the ESP32 Devkitc to the local Wi-Fi
// network. The network name and passwors are as specifed earlier
void Connect_WiFi()
{
WiFi.begin(ssid, password);
while(WiFi.status() != WL_CONNECTED)
{
delay(1000);
}
}
//
// Configure LEDs as outputs, turn OFF the LEDs to start with,
// Connect to the local Wi-Fi. Also, UDP is started in local port
● 312
Chapter 10 • Remote control using mobile phone
//
void setup()
{
pinMode(LED0, OUTPUT);
pinMode(LED1, OUTPUT);
digitalWrite(LED0, LOW);
digitalWrite(LED1, LOW);
Connect_WiFi();
udp.begin(Port);
}
//
// This is the main program loop. Inside the main program we read
// UDP packets and then control the LEDs as requested. The format
// of the control commands are:
//
// 0=ON or 0=OFF for LED0
// 1=ON or 1=OFF for LED1
//
// Any other commands are simply ignored by the program
//
void loop()
{
int PacketSize = udp.parsePacket();
if(PacketSize)
{
udp.read(Packet, PacketSize);
if(Packet[1]==’=’)
{
if(Packet[0]==’0’)
{
if(Packet[2]==’O’ && Packet[3]==’N’)
{
digitalWrite(LED0, HIGH);
}
else if(Packet[2]==’O’ && Packet[3]==’F’ && Packet[4]==’F’)
{
digitalWrite(LED0, LOW);
}
}
else if(Packet[0]==’1’)
{
if(Packet[2]==’O’ && Packet[3]==’N’)
{
● 313
The Complete ESP32 Projects Guide
digitalWrite(LED1, HIGH);
}
else if(Packet[2]==’O’ && Packet[3]==’F’ && Packet[4]==’F’)
{
digitalWrite(LED1, LOW);
}
}
}
}
}
Figure 10.3 Program listing
As an example, Figure 10.4 shows the command sent from the mobile phone application to
turn on LED1 (command: 1=ON).
10 .5 Summary
In this chapter we have seen an interesting web server application where two LEDs are
controlled remotely from a mobile phone using UDP packets. Although in this project LEDs
are used, in general relays can be used and any electrical equipment can be controlled
remotely.
In the next chapter we will see how to send the temperature and humidity readings to a
mobile phone, again using UDP packets.
● 314
Chapter 11 •Send temperature and humidity to a mobile phone
11 .1 Overview
In the last chapter we have seen the design and development of an interesting Wi-Fi appli-
cation which controls two LEDs from an Android mobile phone.
In this chapter we will be developing another interesting application. Here, we will read the
ambient temperature and humidity and then send this data to a mobile phone whenever a
request is made. In this program data is exchanged using UDP packets.
The data will be sent in the following format, where T and H are the temperature and hu-
midity readings:
T = nn H = nn
A request for data is made by the mobile phone when it sends the character S to the ESP32
DevKitC.
This project uses two way UDP communications to receive and send data.
● 315
The Complete ESP32 Projects Guide
The ESP32 DevKitC and the mobile phone IP addresses are 192.168.1.156 and
192.168.1.125 respectively. Notice that the IP address of the mobile phone can be seen on
the screen when the UDP apps is started.
Inside the setup routine function Connect_WiFi is called to connect to local Wi-Fi and UDP
and DHT11 are started.
The remainder of the program is executed in an endless loop, in which the program waits
to receive a packet (command to return the temperature and humidity readings) from the
UDP server (mobile phone here). The request is identified by character S and when this
character is received, the temperature and humidity are read and a packet is formed using
character array Packet. This array stores the temperature and humidity readings in the
required format. The packet is then sent to the mobile phone over port 5000.
/*************************************************************
* SEND TEMPERATURE AND HUMIDITY TO A MOBILE PHONE
* ================================================
*
* This is an UDP based monitoring program where a DHT11 type
* temperatrue and humidity sensor chip is connected to GPIO
● 316
Chapter 11 •Send temperature and humidity to a mobile phone
WiFiUDP udp;
//
// Use local port 5000
//
const int Port = 5000;
char Packet[20];
//
// Local Wi-Fi name and password
//
const char* ssid = "BTHomeSpot-XNH";
const char* password = "49345abseb";
int T, H;
//
● 317
The Complete ESP32 Projects Guide
//
// This function connects the ESP32 Devkitc to the local Wi-Fi
// network. The network name and passwors are as specifed earlier
void Connect_WiFi()
{
WiFi.begin(ssid, password);
while(WiFi.status() != WL_CONNECTED)
{
delay(1000);
}
}
//
// Connect to the local Wi-Fi. Also, UDP is started in local
// port and DHT11 is started
//
void setup()
{
Connect_WiFi();
udp.begin(Port);
dht.begin();
}
//
// This is the main program loop. Inside the main program we read
// the temperatrue and humidity an send them as a packet to the
// mobile phone when a request is made by the mobile phone.
// A request is made when character S is sent by the mobile
// phone.
//
// The packet format is:
//
// T=nn H=nn
//
● 318
Chapter 11 •Send temperature and humidity to a mobile phone
void loop()
{
int PacketSize = udp.parsePacket();
if(PacketSize)
{
udp.read(Packet, PacketSize);
if(Packet[0] == ‘S’)
{
TempHum();
Packet[0] = ‘T’;
Packet[1] = ‘=’;
int msd = T/10;
int lsd = T - msd*10;
Packet[2] = msd + ‘0’;
Packet[3] = lsd + ‘0’;
Packet[4] = ‘ ‘;
Packet[5] = ‘ ‘;
Packet[6] = ‘H’;
Packet[7] = ‘=’;
msd = H/10;
lsd = H - msd*10;
Packet[8] = msd + ‘0’;
Packet[9] = lsd + ‘0’;
Packet[10] = 0;
udp.beginPacket(udp.remoteIP(), Port);
udp.print(Packet);
udp.endPacket();
}
}
}
Figure 11.2 Program listing
As an example, Figure 11.3 shows the request S sent from the mobile phone application.
The returned temperature and humidity data are shown in the lower part of the screen.
● 319
The Complete ESP32 Projects Guide
11 .5 Summary
In this chapter we have seen an interesting web server application where the ambient
temperature and humidity readings are sent from the ESP32 DevKitC to an Android mobile
phone using UDP packets. This project shows how two-way communication can be estab-
lished using UDP packets.
In the next chapter we will be installing the microPython software onto our ESP32 DevKitC
and see how microPython programs can be developed and uploaded to the DevKitC.
● 320
Chapter 12 • Web server with relay
12 .1 Overview
In the previous chapter we have seen how to read and send the ambient temperature and
humidity readings to a mobile phone.
In this chapter we shall be looking at the design of a web server project in which a 4-chan-
nel relay board is connected to the ESP32 DevkitC and is controlled through a web server
interface. Using this project we can connect high voltage devices such as a microwave,
dish washer or washing machine to the relay outputs and control them over a web server
interface from our PC or mobile phone.
12 .2 The Aim
The aim of this project is to show how a 4-channel relay board can be connected to the
ESP32 DevKitC and also how it can be controlled over a web server interface.
12 .4 Circuit Diagram
In this project a 4-channel relay board (see Figure 12.2) from Elegoo (www.elegoo.com)
is used. This is an opto-coupled relay board with 4 inputs; one for each channel. The relay
inputs are at the bottom right hand side of the board while the relay outputs are located at
the top. The middle position of each relay is the common point, the connection to its left
● 321
The Complete ESP32 Projects Guide
is the normally closed (NC) contact, while the connection to the right is the normally open
(NO) contact. The relay contacts support AC250V at 10A and DC30V 10A. IN1, IN2, IN3
and IN4 are the active LOW inputs, which means that a relay is activated when a logic
LOW signal is applied to its input pin. Relay contacts are normally closed (NC). Activating
the relay changes the active contacts such that the common pin and NC pin become the
two relay contacts and at the same time the LED at the input circuit of the relay board cor-
responding to the activated relay is turned ON. The VCC can be connected to either +3.3
V or to +5 V. Jumper JD is used to select the voltage for the relay. Because the current
drawn by a relay can be in excess of 80 mA, you must remove this jumper and
connect an external power supply (e .g . +5 V) to pin JD-VCC.
Figure 12.3 shows the circuit diagram of the project. IN1, IN2, IN3 and IN4 inputs of the
relay board are connected to GPIO pins 5, 17, 16, and 4 respectively. Also, GND and +3.3
V pins of the development board are connected to GND and VCC pins of the relay board.
You must make sure that jumper JD is removed from the board. Connect an external +5 V
power supply to the JD-VCC pin of the relay board.
● 322
Chapter 12 • Web server with relay
12 .5 The Construction
As shown in Figure 12.4, the ESP32 DevkitC was mounted on a breadboard and connec-
tions to the relay board were made using jumper wires.
● 323
The Complete ESP32 Projects Guide
12 .6 Program Listing
The program listing (program: WebRelay) is shown in Figure 12.5.
/*****************************************************************
* WEB SERVER TO CONTROL 2 LEDs
* ============================
*
* This is a web server program. A 4-channel relay board is
* connected to the ESP32 DevKitC.2 The project controls the relays
* from any device that is on the web, for example a PC, tablet, or
* mobile phone etc. When the IP address of ESP32 is entered on the
* browser the user will be presented with buttons to control the
* relays.
*
* File: WebRelay
* Author: Dogan Ibrahim
* Date: November, 2018
*
****************************************************************/
#include "WiFi.h"
byte RelayArray[] = {5, 17, 16, 4}; // Relay interface
//
// Local Wi-Fi name and password
//
const char* ssid = "BTHomeSpot-XNH"; // SSID
const char* password = "49345abseb"; // Password
WiFiServer server(80);
//
// The HTML code. This code will display 4 buttons on user’s
// device which can be clicked to control the 4 Relays ON or OFF
//
String html ="<!DOCTYPE html> \
<html> \
<body> \
<h1>ESP32 DevKitC RELAY CONTROL</h1>\
<h2>Web Server Example with 4-Channel Relays</h2> \
<form> \
<button name=\"RELAY1\" button style=\"background:green\", value=\"ON\"
type=\"submit\"><b>RELAY1 ON</b></button> \
<button name=\"RELAY1\" button style=\"background:red\", value=\"OFF\"
type=\"submit\"><b>RELAY1 OFF</b></button><br><br> \
<button name=\"RELAY2\" button style=\"background:green\", value=\"ON\"
type=\"submit\"><b>RELAY2 ON</b></button> \
<button name=\"RELAY2\" button style=\"background:red\", value=\"OFF\"
● 324
Chapter 12 • Web server with relay
type=\"submit\"><b>RELAY2 OFF</b></button><br><br> \
<button name=\"RELAY3\" button style=\"background:green\", value=\"ON\"
type=\"submit\"><b>RELAY3 ON</b></button> \
<button name=\"RELAY3\" button style=\"background:red\", value=\"OFF\"
type=\"submit\"><b>RELAY3 OFF</b></button><br><br> \
<button name=\"RELAY4\" button style=\"background:green\", value=\"ON\"
type=\"submit\"><b>RELAY4 ON</b></button> \
<button name=\"RELAY4\" button style=\"background:red\", value=\"OFF\"
type=\"submit\"><b>RELAY4 OFF</b></button> \
</form> \
</body> \
</html>";
//
// This function connects the ESP32 Devkitc to the local Wi-Fi
// network. The network name and passwors are as specifed earlier
//
void Connect_WiFi()
{
WiFi.begin(ssid, password);
while(WiFi.status() != WL_CONNECTED)
{
delay(1000);
}
}
//
// Configure Relays as outputs, turn OFF the Relays to start with,
// Connect to the local Wi-Fi, start the server. Notice that a relay
// is turned OFF when logic HIGH is applied to its input
//
void setup()
{
for(int k = 0; k < 4; k++)
{
pinMode(RelayArray[k], OUTPUT);
digitalWrite(RelayArray[k], HIGH);
}
Connect_WiFi();
server.begin();
}
//
● 325
The Complete ESP32 Projects Guide
12 .7 Program Description
At the beginning of the program array RelayArray defines the pins used to connect the
ESP32 to the relay board. The SSID name and password of the local Wi-Fi router are then
specified. String HTML displays 4 buttons corresponding to the 4 relays when activated
from a web browser. The user can click the ON or OFF buttons to activate or deactivate a
relay. Inside the setup routine the relay inputs are configured as outputs and are deactivat-
ed as their default states at the beginning of the program. The program then connects to
the Wi-Fi router and starts the server.
The web server program sends the html file (statement client .print(html)) to the client
and waits for a command from the client. When a button is clicked on the client, a com-
mand is sent to the web server in addition to some other data. Here, we are only interested
in the actual command sent. The following commands are sent to the web server for each
button pressed:
● 326
Chapter 12 • Web server with relay
The web server program on the ESP32 DevKitC makes a TCP connection and reads the com-
mand from the web client as a string (String request = client .readStringUntil(‘\r’)).
The program then searches the received command to see if any of the above commands
are present in the received data. If the sub-string is not found then a -1 is returned. For
example, consider the following statement:
In this project, the IP address of the web server was 192.168.1.156. The procedure to test
the system is as follows:
• Open your web browser on your PC and enter the website address 192.168.1.156.
• The form shown in Figure 12.6 will be displayed by the web browser e.g. on your
PC screen. The ON buttons are displayed in green and the OFF button in red.
● 327
The Complete ESP32 Projects Guide
Figure 12.7 show the command sent to the web server when RELAY2 OFF button is clicked.
12 .8 Summary
In this chapter we have seen the development of a web server project with a 4-channel
relay. The output contacts of the relay can be connected to high voltage devices such as a
microwave, dish washer, washing machine, microwave, etc., so that they can be controlled
remotely over a web server interface from a PC or a mobile phone.
In the next project we shall be looking at the development of projects using the Bluetooth
module of the ESP32 DevKitC.
● 328
Chapter 13 • ESP32 DevKitC Bluetooth programming
13 .1 Overview
In the previous chapter we have seen an example web server program controlling a 4-chan-
nel relay board.
In this chapter we will be seeing how to program the ESP32 DevKitC for Bluetooth commu-
nications by developing projects. Before going into the details of the projects it is worth-
while to look at the features of the Bluetooth briefly.
ESP32 supports the classic Bluetooth as well as the latest Bluetooth Low Energy (BLE) 4.2,
thus enabling communication with both old and new Bluetooth phones, tablets, and PCs.
Table 13.1 shows a comparison of the classical Bluetooth and the Bluetooth BLE. Classical
Bluetooth has the following features:
• Multi connections
• Up to 3 Mb/s data rate
• Up to 79 channels
• Continuous data streaming
• Device discovery
• Asynchronous data communication
• Master/slave Switch
• Adaptive frequency hopping
• Authentication and encryption
• Secure pairing
• Sniff mode
• Point-to-point network topology
• Multiple connections
• Up to 2 Mb/s data rate
• Up to 40 channels
• Short burst data transmission
• Scanning
• Asynchronous data communication
• Data length extension
• Connection parameter update
• Point-to-point, broadcast, and mesh network topologies
● 329
The Complete ESP32 Projects Guide
Table 13.1 Comparison of classical Bluetooth and Bluetooth BLE (Source: Bluetooth.com)
13 .2 Bluetooth BLE
Bluetooth Low Energy (BLE) has mainly been developed for battery-operated short distance
communications and it consumes less power than the classical Bluetooth. BLE is normally
in sleep mode except when a connection is initiated. As a result of this feature, it is suitable
for applications that require exchanging small amounts of data at regular intervals, such
as in sending/receiving the weather data, in healthcare, security, in home automation, in
IoT applications etc.
In Bluetooth BLE applications we have a server and a client. In applications that we are
interested in here, ESP32 acts as the server and the PC or a mobile phone act as clients,
although this can be changed if required.
The server-client communication is normally done using a point-to-point protocol where the
data exchange takes place as follows:
• The server makes itself known to nearby Bluetooth BLE client devices.
• The client devices scan their surroundings and when they find the server that
they are looking for they establish connection to the server.
• The client device listens for incoming data from the server.
Other modes of Bluetooth BLE communication are Broadcast, and Mesh. In Broadcast mode
the server broadcasts data to a number of connected client devices. In Mesh mode all the
BLE devices are connected to each other and they can exchange data. In this chapter we
will be developing projects using the point-to-point protocol.
● 330
Chapter 13 • ESP32 DevKitC Bluetooth programming
Every Service, Characteristic, and Descriptor in a Profile have unique 16 byte (128-bits)
Universally Unique identifiers (UUID) which identifies a particular service provided by a
BLE device. The Bluetooth Special Interest Group (https://www.bluetooth.com/specifica-
tions/gatt/services) gives lists of shortened UUIDs. For example, the Battery Service
(used in portable battery operated BLE devices to indicate the current battery level) has
the Uniform Type Identifier: org .bluetooth .service .battery_service and its assigned
number is 0x180F. Using unique identifiers, any BLE device can find out the battery level,
regardless of the manufacturer. Looking at the Battery Service we can see that Battery
Level is a characteristic of this service and its UUID is 0x2A19 (see website: org .blue-
tooth .characteristic .battery_level). The Characteristic Descriptor and Characteris-
tic Presentation Format are the descriptors of this service and their UUIDs are 0x2902
and 0x2904 respectively. As an example, Figure 13.2 shows the GATT data structure for
the Battery Service. If your application requires its own UUID, you can generate it from
the following website:
https://www.uuidgenerator.net/
● 331
The Complete ESP32 Projects Guide
13 .3 .1 Description
In this project a counter is incremented by one every 3 seconds and its value is sent to a
Bluetooth BLE compatible Android mobile phone where it is displayed with an app.
13 .3 .2 Program Listing
The program listing is shown in Figure 13.3 (program: BLUECNT).
/*****************************************************************
* SEND DATA TO A BLUETOOTH BLE DEVICE
* ===================================
*
* In this program a counter is incremented by one in the main
* program loop every 3 seconds. The counter value is sent to a
* Bluetooth BLE compatible device, e.g. to a mobile phone.
*
* Notice: This program is based on Neil Kolban example for IDF:
* https://github.com/nkolban/esp32-snippets/blob/master/
* cpp_utils/tests/BLE%20Tests/SampleNotify.cpp, Ported to Arduino
* ESP32 by Evandro Copercini
*
* File: BLUECNT
* Author: Dogan Ibrahim
* Date: November, 2018
******************************************************************/
//
// Import the necessary BLE libraries
//
#include "BLEDevice.h"
#include "BLEServer.h"
#include "BLEUtils.h"
//
● 332
Chapter 13 • ESP32 DevKitC Bluetooth programming
//
// Define the callback class with the DeviceConnected status such
// that the status is set true when a connection is established
//
class MyServerCallbacks: public BLEServerCallbacks
{
void onConnect(BLEServer* pServer)
{
DeviceConnected = true;
};
};
};
void setup()
{
// Define our BLE name as ESP_CNT (can be changed if required)
BLEDevice::init("ESP_CNT");
● 333
The Complete ESP32 Projects Guide
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_NOTIFY);
// Start advertising
pServer->getAdvertising()->start();
}
//
// This is the main program loop. If the Bluetooth BLE compatible
// device is connected then increment Count and send its value to
// the connected device. This loop is repeated every 3 seconds
//
void loop()
{
if(DeviceConnected) // If connected...
{
Count++; // Increment Count
itoa(Count,strcnt,10); // Convert to string
pCharacteristic->setValue(strcnt); // Set its value
pCharacteristic->notify(); // Notify it
}
delay(3000); // Wait 3 seconds
}
Figure 13.3 Program listing
13 .3 .3 Program PDL
Figure 13.4 shows the operation of the program as a PDL.
BEGIN
Define Service and Characteristic UUIDs
Initialize Count to 0
Create a BLE server
Define a BLE callback function
Create a BLE service
Create the BLE Characteristics and its Descriptor
Start the BLE service
Advertise the BLE
DO FOREVER
IF connected to a BLE device THEN
Increment Count
Convert Count into a string
Set value to this string
Notify the connected BLE
● 334
Chapter 13 • ESP32 DevKitC Bluetooth programming
ENDIF
ENDDO
END
13 .3 .4 Program Description
At the beginning of the program the header files used by the BLE are included in the pro-
gram. The Service UUID and Characteristic UUID are then defined (you can generate
new UUIDs as described in Section 13.2.1). Variable Count is initialised to 0. Inside the
setup routine the BLE name is set to ESP_CNT, BLE is created, the server callback func-
tion is set, and the BLE service is created. The BLE Characteristic is configured by spec-
ifying its UUID, and the properties are set to NOTIFY, READ and WRITE. Lastly the BLE
service is started and is then advertised.
The remainder of the program runs inside the main program loop. Here, the program
checks to see if a Bluetooth BLE device is connected, and if so, the Count is incremented by
one, it is converted into a string, and is stored in character array strcnt using function itoa.
strcnt is then set as a value and then sent as a notification to the connected BLE device.
Figure 13.5 shows the installation screen of the Bluetooth Monitor. The steps to test the
program are given below:
● 335
The Complete ESP32 Projects Guide
● 336
Chapter 13 • ESP32 DevKitC Bluetooth programming
13 .4 .1 Description
In this project a 4-channel relay board is connected to the ESP32 DevKitC and the relay is
controlled by sending commands from a Bluetooth BLE apps running on an Arduino mobile
phone. The following commands can be sent from the mobile phone:
13 .4 .2 The Aim
The aim of this project is to show how a 4-channel relay board can be connected to the
ESP32 DevKitC and also how it can be controlled using the Bluetooth BLE communication
with a mobile phone.
13 .4 .4 Circuit Diagram
The circuit diagram of the project is as in Figure 12.3 where the 4-channel relay inputs IN1,
IN2, IN3 and IN4 are connected to GPIO pins 5, 17, 16 and 4, respectively.
● 337
The Complete ESP32 Projects Guide
13 .4 .5 Program PDL
Figure 13.8 shows the operation of the program as a PDL.
BEGIN
Define Service and Characteristic UUIDs
Initialize RelayArray as outputs
De-activate all 4 relays
Create a BLE server
Define a BLE callback function
Create a BLE service
Create the BLE Characteristics and its Descriptor
Start the BLE service
Advertise the BLE
DO FOREVER
IF command received THEN
IF the command is n=ON THEN
Activate Relay n
ELSE IF command is n=OFF THEN
De-activate Relay n
ENDIF
ENDIF
ENDDO
END
Figure 13.8 Program PDL
13 .4 .6 Program Listing
The program listing is shown in Figure 13.9 (program: BLERELAY).
/***********************************************************************
* BLUETOOTH BLE 4-CHANNEL RELAY CONTROL
* ======================================
*
* In this program a 4-channel relay board is connected to input pins
* 5,17,16, and 4 of the ESp32 DevKitC. The program receives commands from
* a Bluettoth BLE compatible device (e.g. mobile phone) and then
* controls the relays as requested.
*
* This program is based on Neil Kolban example for IDF:
* https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests
* /BLE%20Tests/SampleNotify.cpp, Ported to Arduino ESP32 by
* Evandro Copercini
*
* Program: BLERELAY
* Date : November, 2018
* Author : Dogan Ibrahim
**********************************************************************/
● 338
Chapter 13 • ESP32 DevKitC Bluetooth programming
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
//
// Define Service UUID and Characteristic UUID
//
#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
//
// This routine is called when data is received from the connected
// BLE device. The data is in the following format: n=ON or n=OFF
// where n=1,2,3,4 corresponding to the relay number. RXholds the
// received data
//
class MyCallbacks: public BLECharacteristicCallbacks
{
void onWrite(BLECharacteristic *pCharacteristic)
{
std::string RX = pCharacteristic->getValue();
if (RX.length() >= 4)
{
if(RX[1] == ‘=’ && RX[2] == ‘O’ && RX[3] == ‘N’)
{
for(int i = 0; i < 4; i++)
{
if(RX[0] == i+1+’0’)digitalWrite(RelayArray[i], LOW);
}
}
else if(RX[1] == ‘=’ && RX[2] == ‘O’ && RX[3] == ‘F’ && RX[4] ==
‘F’)
{
for(int i = 0; i < 4; i++)
{
if(RX[0] == i+1+’0’)digitalWrite(RelayArray[i], HIGH);
}
}
}
}
};
● 339
The Complete ESP32 Projects Guide
//
// Configure Relays as outputs, turn OFF the Relays to start with.
// Notice that a relay is turned OFF when logic HIGH is applied to its input
//
void setup()
{
for(int k = 0; k < 4; k++)
{
pinMode(RelayArray[k], OUTPUT); // Relays are outputs
digitalWrite(RelayArray[k], HIGH); // De-activate relays
}
pCharacteristic->setCallbacks(new MyCallbacks());
// Start advertising
pServer->getAdvertising()->start();
}
void loop()
{
}
Figure 13.9 Program listing
● 340
Chapter 13 • ESP32 DevKitC Bluetooth programming
13 .4 .7 Program Description
At the beginning of the program, the Bluetooth BLE header files used by the program are
included and array RelayArray defines the pins used to connect the ESP32 to the relay
board. The Service UUID and Characteristic UUID are then defined. Inside the setup
routine the relay inputs are configured as outputs and the relays are deactivated at the be-
ginning of the program. Then our Bluetooth BLE device is given the name BLE_RELAY, BLE
server is created, BLE service is created, and the BLE Characteristics are defined. The BLE
service is started and advertised. The program then waits to receive data from a connected
BLE device. When data is received the program executes the code inside the MyCallbacks
routine. Here, the correct relay is controlled based on the received data. For example, re-
ceiving data 1=ON activates Relay1 and so on.
• Install apps nRF Connect for Mobile on your Android mobile phone.
• Start the apps on your mobile phone. You should see ESP32 DevKitC displayed
as device BLE_RELAY, as shown in Figure 13.11. Click CONNECT to connect to
your device. You should see the CONNECTED message displayed.
● 341
The Complete ESP32 Projects Guide
• Click on Unknown Service and then click on the up arrow to send data to the
ESP32.
/*****************************************************************
* SERIAL COMMUNICATION OVER BLUETOOTH
* ===================================
*
* In this program the message Hello from DevKitC is sent over
* Bluetooth serial link every 3 seconds
*
* File: SERIALBLUE
* Author: Dogan Ibrahim
* Date: November, 2018
*
****************************************************************/
#include"BluetoothSerial.h"
● 342
Chapter 13 • ESP32 DevKitC Bluetooth programming
BluetoothSerial BT;
void setup()
{
BT.begin("MyESP");
}
void loop()
{
BT.println("Hello from ESP32 DevKitC");
delay(3000);
}
Figure 13.12 Testing the program
13 .5 .1 Description
In this project data is sent using serial communication over Bluetooth classic. The message
Hello from ESP32 DevKitC is sent every three seconds.
13 .5 .2 The Aim
The aim of this project is to show how data can be sent via serial communication operating
over Bluetooth classic.
13 .5 .3 Program Listing
The program listing is shown in Figure 13.13 (program: SERIALBLUE).
/*****************************************************************
* SERIAL COMMUNICATION OVER BLUETOOTH
* ===================================
*
* In this program the message Hello from DevKitC is sent over
* Bluetooth serial link every 3 seconds
*
* File: SERIALBLUE
* Author: Dogan Ibrahim
* Date: November, 2018
*
****************************************************************/
#include"BluetoothSerial.h"
BluetoothSerial BT;
void setup()
{
BT.begin("MyESP");
● 343
The Complete ESP32 Projects Guide
void loop()
{
BT.println("Hello from ESP32 DevKitC");
delay(3000);
}
Figure 13.13 Program listing
13 .5 .4 Program Description
At the beginning of the program the header file BluetoothSerial .h is included in the pro-
gram. Make sure that you have the latest version of the ESP32 software for Arduino since
the Bluetooth Serial library has been added recently to the ESP32 Arduino IDE. Inside the
setup routine the Bluetooth device is initialised with the name MyESP. The remainder of
the program runs in an endless loop where the message Hello from ESP32 DevKitC is
sent every 3 seconds.
Notice that we can use function BT .read() to read data from the serial port. Function
BT .available() can be used to check if data is available in the input buffer before attempt-
ing to read.
• Open Bluetooth settings on your PC and click to display the COM Ports (see Fig-
ure 13.14).
● 344
Chapter 13 • ESP32 DevKitC Bluetooth programming
• Notice the Outgoing COM port number for our device (COM59 in our example).
• Start the Putty terminal emulation program, select Serial, Serial line: COM59,
Speed: 9600 . Alternatively open the Serial Monitor with the correct COM port
number.
• You should see the message Hello from ESP32 DevKitC displayed every 3 sec-
onds (see Figure 13.15).
• Add a Bluetooth classic app to your Android mobile phone. In this project the
free of charge app called Serial Bluetooth Terminal (by Kai Morich) shown in
Figure 13.16 is used.
• Connect your ESP32 DevKitC to a power supply (e.g. PC USB port or a portable
power supply).
● 345
The Complete ESP32 Projects Guide
• Open the Bluetooth folder on your mobile phone and pair with MyESP if request-
ed. Delete any older pairings if not needed.
• Install and open the Serial Bluetooth Terminal on your mobile phone.
• Click Devices from the menu and then click on device MyESP. You should see
the Connected message displayed.
• You should now see the message Hello from ESP32 DevKitC displayed on your
mobile phone every 3 seconds as shown in Figure 13.17.
13 .6 .1 Description
In this project a 4-channel relay board is connected to the ESP32 DevKitC as in Section
13.4 and the relay is controlled by sending commands from a Bluetooth classic app running
on an Arduino mobile phone. The following commands can be sent from the mobile phone
(# character is the command terminator):
● 346
Chapter 13 • ESP32 DevKitC Bluetooth programming
13 .6 .2 The Aim
The aim of this project is to show how a 4-channel relay board can be connected to the
ESP32 DevKitC and also how it can be controlled using the Bluetooth classic communication
with a mobile phone.
13 .6 .4 Circuit Diagram
The circuit diagram of the project is as in Figure 12.3, where the 4-channel relay inputs IN1,
IN2, IN3 and IN4 are connected to GPIO pins 5, 17, 16 and 4 respectively.
13 .6 .5 Program Listing
The program listing is shown in Figure 13.18 (program: BTRELAY).
/***********************************************************************
* BLUETOOTH CLASSIC 4-CHANNEL RELAY CONTROL
* =========================================
*
* In this program a 4-channel relay board is connected to input pins
* 5,17,16, and 4 of the ESp32 DevKitC. The program receives commands from
* a Bluetooth classic compatible mobile phone and controls the relays
*
* Program: BTRELAY
* Date : November, 2018
* Author : Dogan Ibrahim
**********************************************************************/
#include"BluetoothSerial.h"
BluetoothSerial BT;
//
// This function activates or de-activates the relays depending on
// received command in character array rcv. Command n=ON# activates
// Relayn, command n=OFF# de-activates Relayn. # is the terminator
● 347
The Complete ESP32 Projects Guide
//
void RelayControl()
{
if(rcv[1] == ‘=’ && rcv[2] == ‘O’ && rcv[3] == ‘N’)
{
for(int i = 0; i < 4; i++)
{
if(rcv[0] == i+1+’0’)
{
digitalWrite(RelayArray[i], LOW);
BT.printf("Relay%d is activated\n\r", i+1);
}
}
}
else if(rcv[1] == ‘=’ && rcv[2] == ‘O’ && rcv[3] == ‘F’ && rcv[4] == ‘F’)
{
for(int i = 0; i < 4; i++)
{
if(rcv[0] == i+1+’0’)
{
digitalWrite(RelayArray[i], HIGH);
BT.printf("Relay%d is de-activated\n\r", i+1);
}
}
}
}
//
// Configure Relays as outputs, turn OFF the Relays to start with.
// Notice that a relay is turned OFF when logic HIGH is applied to its input
//
void setup()
{
for(int k = 0; k < 4; k++)
{
pinMode(RelayArray[k], OUTPUT); // Relays are outputs
digitalWrite(RelayArray[k], HIGH); // De-activate relays
}
BT.begin("ESPRelays"); // Initialize
}
void loop()
{
int dummy, k = 0, flag = 0;
● 348
Chapter 13 • ESP32 DevKitC Bluetooth programming
while(1)
{
while(flag == 0) // while not terminator
{
if(BT.available()) // If data available
{
rcv[k] = BT.read(); // Read byte
if(rcv[k] == ‘#’)flag = 1; // If terminator
k++; // Increment buffer count
}
}
k = 0; // Zero for next command
if(flag == 1)
{
while(BT.available())dummy = BT.read(); // Flush receive buffer
flag = 0; // Ready for next command
RelayControl(); // Decode command
}
}
}
Figure 13.18 Program listing
13 .6 .6 Program Description
At the beginning of the program header file BluetoothSerial .h is included in the program,
receive buffer rcv is defined, and connections between the relay board and ESP32 DevKitC
are defined in byte array RelayArray. Inside the setup routine all the relays are config-
ured as outputs and they are de-activated. The serial Bluetooth is then initialised to the
name ESPRelays. Inside the main program loop the program reads data from the mobile
phone until the terminator character # is detected. The input buffer is then flashed so that
any remaining characters in the input buffer are deleted. The program then calls function
RelayControl to activate or deactivate the relays based on the received command in buffer
rcv. Every valid command is confirmed by sending a message to the mobile phone. For
example, if the received command is 1=ON# then Relay1 is activated and message Re-
lay1 is activated is sent to the mobile phone. Similarly, command 1=OFF# de-activated
Relay1 and so on for all the other relays. The main program loop then repeats, waiting for
a new command from the mobile phone.
• Open the Bluetooth folder on your mobile phone and pair with ESPRelay if re-
quested. Delete any older pairings if not needed.
• Install and open the Serial Bluetooth Terminal on your mobile phone.
● 349
The Complete ESP32 Projects Guide
• Click Devices from the menu and then click on device ESPRelays. You should
see the Connected message displayed.
• Press and hold button M1 to save a command on the mobile phone. Enter the
command, e.g. 1=ON# as shown in Figure 13.19 and click the tick at the top
right hand side of the screen. Repeat to save other commands in M2, M3, M4 etc.
• Click button M1 to send command 1=ON# to the ESP32 DevKitC. Notice that a
confirmation message is displayed on the mobile phone screen for every com-
mand sent.
• Figure 13.20 shows some example commands sent to the ESP32 DevKitC.
● 350
Chapter 13 • ESP32 DevKitC Bluetooth programming
13 .7 .1 Description
In this project the ambient temperature and humidity are read from a sensor and are then
sent to a mobile phone using Bluetooth classic every 5 seconds.
13 .7 .2 The Aim
The aim of this project is to show how the temperature and humidity readings can be sent
to a mobile phone using Bluetooth classic.
13 .7 .4 Circuit Diagram
The circuit diagram of the project is as in Figure 5.12, where the output of sensor DHT11
is connected to GPIO port 23.
13 .7 .5 Program Listing
The program listing is shown in Figure 13.22 (program: BTDHT11).
/***************************************************************************
* SENDING TEMPERATURE & HUMIDITY TO MOBILE PHONE USING BLUETOOTH CLASSIC
* ======================================================================
*
* In this program a DHT11 type temperature and humidity sensor chip
* is connected to the ESP32 DevKitC. The program sends the temperature
* and humidity readinsg to a Bluetooth classic compatible mobile phone
* every 5 seconds
*
* Program: BTDHT11
* Date : November, 2018
* Author : Dogan Ibrahim
**************************************************************************/
#include "Adafruit_Sensor.h"
● 351
The Complete ESP32 Projects Guide
#include "DHT.h"
#define DHT11_PIN 23 // DHT11 on pin 23
#define DHTTYPE DHT11
#include"BluetoothSerial.h"
BluetoothSerial BT;
DHT dht(DHT11_PIN, DHTTYPE);
//
// Initialize the DHT11 and BluetoothSerial
//
void setup()
{
dht.begin(); // Initialize DHT11
BT.begin("ESPDHT11"); // Initialize
}
void loop()
{
while(1)
{
float humidity = dht.readHumidity(); // Read humidity
float temperature = dht.readTemperature(); // Read temperature
BT.printf("Temperature=%5.2f\n\r", temperature); // Send temperature
BT.printf("Humidity=%5.2f\n\r", humidity); // Send humidity
delay(5000); // Wait 5 seconds
}
}
Figure 13.22 Program listing
13 .7 .6 Program Description
The DHT11 temperature and humidity sensor chip used in the project (see Section 5.3,
Project 2). At the beginning of the program DHT and BluetoothSerial header files are
included in the program (see Section 5.3 on how to install the DHT libraries). Inside the
setup routine the DHT11 and BluetoothSerial are initialised where the ESP32 is given the
name ESPDHT11. The main program runs in an endless loop where the temperature and
humidity readings are read from the DHT11 sensor chip every 5 seconds and are then sent
to the mobile phone over a Bluetooth classic link using printf statements.
• The Android app installed in the previous project can also be used in this project.
• Connect your ESP32 DevKitC to a power supply (e.g. PC USB port or a portable
power supply).
● 352
Chapter 13 • ESP32 DevKitC Bluetooth programming
• Open the Bluetooth folder on your mobile phone and pair with ESPDHT11 if
requested. Delete any older pairings if not needed.
• Install and open the Serial Bluetooth Terminal on your mobile phone.
• Click Devices from the menu and then click on device ESPDHT11 You should
see the Connected message displayed.
• Select Terminal from the menu in your app. You should see the temperature and
humidity displayed every 5 seconds as shown in Figure 13.23.
13 .8 Summary
The Bluetooth module is one of the nicest features of the ESP32 processor. In this chapter
we have developed projects using both the Bluetooth Low Energy (BLE) programming ando
the Bluetooth classical programming.
In the next chapter we will be installing the microPython to our ESP32 DevKitC and develop
some projects using this powerful and popular programming language.
● 353
The Complete ESP32 Projects Guide
14 .1 Overview
Up to now we have been developing programs for our ESP32 DevKitC using the Arduino IDE
environment. The ESP32 processor can also be programmed with:
ESP – IDF: This is the native development environment from Espressif Systems,
developed for the ESP32 processors. This development environment is based on
FreeRTOS and enables the user to access all modules of the ESP32 processor, in-
cluding the Bluetooth. Although the ESP – IDF is very powerful it is rather difficult
to write programs using this environment.
Mongoose OS: This is an open source operating system supporting the ESP32,
ESP8266, STM32 etc., developed for the Internet of Things applications
Arduino IDE: We have seen using this development environment with the ESP32
processor
In this chapter we will be installing the MicroPython on our ESP32 DevKitC and also develop
some simple projects using the MicroPython.
• Download and install Python 2.7 on your PC from the following website (see Fig-
ure 14.1 and Figure 14.2). The Python files will be loaded into folder C:\Python27
https://www.python.org/downloads/
● 354
Chapter 14 • Using Micropython with the ESP32 DevKitC
• Make Python accessible from anywhere on the PC by configuring the PATH en-
vironment variable. Click Control Panel -> System and then click Advanced
system settings as shown in Figure 14.3.
● 355
The Complete ESP32 Projects Guide
• Click Edit and add the following statement to the end of the line: ;Python27 as
shown in Figure 14.6. Click OK to save and exit the Environment settings.
● 356
Chapter 14 • Using Micropython with the ESP32 DevKitC
• Python should now accessible from anywhere on your PC. Start the command
line on your PC by clicking Start and then enter cmd. Type Python to start the
Python interpreter and you should see a screen similar to the one shown in Figure
14.7.
• Enter the statement print ("Hello there") and you should see the string Hello
there displayed on your screen. Exit from Python by entering Cntl-Z followed
by Enter.
• This shows that the Python has been successfully installed on your PC. Now we
have to continue with the steps to install the ESP32 into Arduino IDE.
We also need a software called esptool on our PC so that we can flash the ESP32 with the
MicroPython binaries. The steps to install esptool to our PC are given below:
• Start the command line on your PC and go to the root directory by entering CD\
(see Figure 14.8)
• Enter the following command to install the latest version of the esptool on your
PC (see Figure 14.9). Note that it must be at least version 2.0 since version 1.x
of esptool does not support the ESP32 processor. You should see the message
Successfully installed esptool at the end of the installation.
● 357
The Complete ESP32 Projects Guide
• It is recommended to erase the entire flash memory of the ESP32 before up-
loading new firmware. To do this, connect the ESP32 DevKitC to the PC using the
mini USB cable. Find out the serial port number where the DevKitC is connected
to from the Device Manager, and enter the following command. In this example
it is assumed that the DevKitC is connected to serial port COM61. Figure 14.10
shows the command being executed to erase the flash memory. The erasure
processes should take about 10 seconds. Make sure that you keep pressing the
BOOT button while the erasure process continues.
Figure 14.10 Erase the entire flash memory of the ESP32 DevKitC
• We will now need to copy the latest MicroPython binary file for ESP32 to a folder.
At the time of writing this book the latest version was called: esp32-20181112-
v1.9.4-683-gd94aa577a.bin. Click on the file and save it to a folder on your PC.
This file can be found at the following link. In this example we have copied it to
folder C:\ESP32 (see Figure 14.11).
•
● 358
Chapter 14 • Using Micropython with the ESP32 DevKitC
www.micropython.org/download
• We are now ready to upload the MicroPython firmware to our ESP32 DevKitC
development board. Make sure that you press the BOOT button while the copy
process continues. Also, make sure that the DevKitC is still connected to the USB
port and enter the following command (see Figure 14.12). The flash memory size
will be detected automatically and the MicroPython firmware will be uploaded to
the ESP32 DevKitC:
C:\> esptool.py --port COM61 --baud 460800 write_flash –fm dio 0x1000
C:\ESP32\esp32-20170803-v1.9.1-394-g79feb956.bin
or,
C:\> python c:\python27\lib\site-packages\esptool.py --port
COM61 --baud 460800 write_flash –fm dio 0x1000 C:\ ESP32\esp32-
20170803-v1.9.1- 394-g79feb956.bin
Note that in Figure 14.12 it is assumed that the flash memory size is 4 MB and this is why
parameter dio is specified. This parameter should be qio for 512 kB modules. The size of
the flash memory can be found by the following command:
● 359
The Complete ESP32 Projects Guide
• After the uploading is finished, press the RESET button on the ESP32 DevKitC.
It is not the intention of this book to teach the MicroPython programming language since
there are many books (e.g ESP8266 AND MICROPYTHON from Elektor), tutorials, projects,
and application notes on this topic. In the next sections some projects of using MicroPython
on the ESP32 DevKitC are given to show how MicroPython can be used in projects.
14 .3 Flashing LED
This project is same as Project 1 in Chapter 4.2 where an LED is connected to GPIO port 23
through a 330 ohm current limiting resistor and the LED is flashed every second.
● 360
Chapter 14 • Using Micropython with the ESP32 DevKitC
The program is written interactively using the Putty terminal emulator to connect to the
ESP32 DevKitC. Figure 14.15 shows the program listing.
Figure 14.16 shows the circuit diagram of the project. The project listing is shown in Fig-
ure 14.17. GPIO port 22 is configured as an input and it is pulled up so that the pin is at
normally logic 1 and the LED is OFF. Pressing the button changes the button input state to
logic 0 and turns ON the LED.
● 361
The Complete ESP32 Projects Guide
Figure 14.18 shows the MicroPython program listing which is entered interactively through
Putty. Notice libraries dht, Pin, and time are included at the beginning of the program.
14 .6 Connecting to a Wi-Fi
Before communicating with other nodes on a network we first have to establish ourselves
as a node on the network and have an IP address assigned to us. The MicroPython library
called network provides network related functions such as connecting to a network, finding
the IP address, and so on. This library must be imported into our MicroPython programs
before we can use the network functions.
The network library has a class called WLAN. Some of the commonly used methods of this
class are:
An example is shown in Figure 14.19 using interactive command mode which establishes
connection to a Wi-Fi network by specifying the ssid (in this example BTHomeSpot-XNH)
and password (in this example 49345abaeb), and then displays the assigned IP address
which happens to be 192.168.1.156.
● 362
Chapter 14 • Using Micropython with the ESP32 DevKitC
The following MicroPython function can be called from a program to connect to a Wi-Fi net-
work. The assigned IP address is displayed at the end of the function:
def Connect_WiFi():
import network
net = network.WLAN(network.STA_IF)
if not net.isconnected():
net.active(True)
net.connect("ssid", "password")
print (net.ifconfig())
An example program is given in this section where the temperature and humidity readings
are sent to an Android mobile phone as described in Chapter 11, using UDP packets. The
operation of the program is as follows:
• The mobile phone requests data by sending character S to the ESP32 DevKitC.
• DevKitC reads the temperature and humidity from chip DHT11 and sends to the
mobile phone.
Figure 14.20 shows the program listing for this example, entered interactively using the
Putty terminal emulator. At the beginning of the program the socket library, the DHT11 and
Pin libraries are imported into the program. Function Connect_WiFi connects to the local
Wi-Fi. Function tempHum reads the ambient temperature and humidity and returns in
variables T and H respectively. The program then creates an UDP socket and binds to this
socket. The remainder of the program is executes inside the while loop. Here, the program
● 363
The Complete ESP32 Projects Guide
waits to receive the request S from the mobile phone. After the request is received, func-
tion tempHum is called and the temperature and humidity readings are sent to the mobile
phone as in Figure 11.3.
#---------------------------------------------------------------------------
#
# SEND TEMPERATURE AND HUMIDITY TO A MOBILE PHONE
# -----------------------------------------------
#
# In this program a DHT11 sensor chip is connected to GPIO port 23 of the
# ESP32 Devkitc. The MicroPython program reads the ambient temperature and
# humidity from the sensor chip and sends to the mobile phone when
requested.
# A request is made by the mobile phone it sends character S. The data is
# displayed on the mobile phone in the following format:
#
# T=nn H=nn
#
# Author: Dogan Ibrahim
# Date : August 2017
#--------------------------------------------------------------------------
---
#
# Import libraries used in the program
● 364
Chapter 14 • Using Micropython with the ESP32 DevKitC
#
import socket
import dht
from machine import Pin
#
# Function to connect to Wi-Fi
#
def Connect_WiFi():
import network
net = network.WLAN(network.STA_IF)
if not net.isconnected():
net.active(True)
net.connect("BTHomeSpot-XNH", "49345abaeb")
#
# Function returns the temperature and humidity
#
def tempHum():
d = dht.DHT11(Pin(23))
d.measure()
t = d.temperature()
h = d.humidity()
return t,h
#
# Start of main program. Define port number, create a socket, and bind to it
#
Connect_WiFi()
port = 5000
UDP = ("", port)
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(UDP)
#
# This part of the program runs in an endless loop, sending the temperature
# and humidity readings to the mobile phone when it receives a request (S)
#
while True:
data, addr = sock.recvfrom(80)
if(data.decode() == ‘S’):
T,H = TempHum()
dat = str(T) + " " + str(H)
tup = (addr[0], port)
sock.sendto(dat, tup)
Figure 14.21 Program listing with comments
● 365
The Complete ESP32 Projects Guide
The readings are stored on the Thingspeak cloud as in Chapter 8. You should create an
account with the Thingspeak and have an API key and a channel number as described in
Chapter 8. In this section only the MicroPython program is given, and the same API key and
channel number as in Chapter 8 are used here.
Figure 14.22 shows the MicroPython program entered interactively using the Putty terminal
emulator. The program basically makes an HTTP GET request to upload the temperature
and the humidity values.
The program listing with comments is shown in Figure 14.23. At the beginning of the pro-
gram the network libraries, time library, DHT11 library and the Pin library are imported to
the program. Function Connect_WiFi connects to the local Wi-Fi. Function TempHum
returns the temperature and the humidity. The main program loop start with the while
statement. Inside this loop the IP address of the Thingspeak website is extracted and a
connection is made to this site. Then the temperature and humidity readings are obtained
and are included in the path statement. The sock .send statement sends an HTTP GET
request to the Thingspeak site and uploads the temperature and humidity values. This
process is repeated every 30 seconds.
As in Chapter 8, the link to view the data graphs in the cloud is:
https://api.thingspeak.com/channels/265433
● 366
Chapter 14 • Using Micropython with the ESP32 DevKitC
#---------------------------------------------------------------------------
# TEMPERATURE AND HUMIDITY ON THE CLOUD
# =====================================
#
# In this project temperature and humidity sensor is connected to
# GPIO port 23 of the ESP32 Devkitc board. The project reads the
# temperature and humidity and sends to the cloud where it can be accessed
# from anywhere. In addition, change of the temperature and the humidity
# can be plotted in the cloud.
#
# The DHT11 sensor chip is used to get the ambient temperature and the
# humidity.
#
# The program uses the Thingspeak cloud service. The ESP32 Devkitc must be
# conencted to the Wi-Fi router before we can send data to the cloud.
#
#
# Date : May, 2017
# Programmer: Dogan Ibrahim
#--------------------------------------------------------------------------
----
import network
import socket
import time
import dht
from machine import Pin
APIKEY = "QAAHT5XIK3ZB8736"
#
# This function connects to the Wi-Fi
#
def Connect_WiFi():
net = network.WLAN(network.STA_IF)
if not net.isconnected():
net.active(True)
net.connect(ìBTHomeSpot-XNHî, ì49345abaebî)
print(net.ifconfig())
#
# This function returns the temperature and humidity
#
def TempHun():
d = dht.DHT11(Pin(0))
d.measure()
● 367
The Complete ESP32 Projects Guide
t = d.temperature()
h = d.humidity()
return t, h
#
# Send data to Thingspeak. This function sends the temperature and
# humidity data to the cloud every 30 seconds
#
while True:
Connect_WiFi()
sock = socket.socket()
addr = socket.getaddrinfo("api.thingspeak.com",80)[0][-1]
sock.connect(addr)
(t, h) = TempHun()
host = "api.thingspeak.com"
path = "api_key="+APIKEY+"&field1="+str(t)+"&field2="+str(h)
sock.send(bytes("GET /update?%s HTTP/1.0\r\nHost: %s\r\n\r\n"
%(path,host),"utf8"))
sock.close()
time.sleep(30)
Valid commands are as follows (any other commands are ignored by the program):
The block diagram and the circuit diagram of this project are as in Figure 10.1 and Figure
9.2 respectively where the LEDs are connected to GPIO ports 23 (LED0) and 22 (LED1)
through 330 ohm current limiting resistors. The LEDs are turned ON when the port output
is at logic 1 (high), and turned OFF when the port output is at logic 0 (low).
In this project an Android based mobile phone loaded with the UDP apps called UDP RE-
CEIVE and SEND by Wezzi Studios (version 4.0) is used to send commands to the ESP32
DevKitC. Clicking the SEND UDP MESSAGE button will send the packet to its destination.
● 368
Chapter 14 • Using Micropython with the ESP32 DevKitC
In the Receiver part the local IP address is given The user must specify the required port
number. Received packets will then be displayed on the screen (see Chapter 10 for more
details).
#---------------------------------------------------------------------------
# WEB SERVER TO CONTROL 2 LEDs
# ============================
#
# This is a simple web server program. 2 LEDs are conencted to GPIO ports 23
# 22 of the ESP32 Devkitc development board. The project controls these LEDs
# (turns ON or OFF) from a web server application. For example, the LEDs can be
# controlled from any device that is on the web, for example a PC, tablet,
# mobile phone etc. When activated, a form will appear on the device with
# buttons and clicking these button will control the LEDs.The LEDs are named as
# LED0 and LED1, connected to ports 23 and 22 respectively.
#
#
# Date : May, 2017
# Programmer: Dogan Ibrahim
#--------------------------------------------------------------------------
----
import network
import socket
from machine import Pin
#
# Configure the pins as outputs
#
LED0 = Pin(23, Pin.OUT)
LED1 = Pin(22, Pin.OUT)
#
# Turn OFF the LEDs to start with
#
LED0.low()
LED1.low()
#
# The HTML code
#
html = """<!DOCTYPE html>
<html>
<body>
<center><h1>ESP32 DECKITC LED ON/OFF</h1></center>
<center><h2>MicroPython Web Server Example with 2 LEDs</h2></center>
<form>
● 369
The Complete ESP32 Projects Guide
#
# This function connects to the Wi-Fi
#
def Connect_WiFi():
net = network.WLAN(network.STA_IF)
if not net.isconnected():
net.active(True)
net.connect(ìBTHomeSpot-XNHî, ì49345abaebî)
#
#
#
Connect_WiFi()
addr=socket.getaddrinfo("0.0.0.0",80)[0][-1]
s = socket.socket()
s.bind(addr)
s.listen(1)
while True:
conn, address = s.accept()
request = conn.recv(1024)
request = str(request)
LEDON0 = request.find("/?LED0=ON")
LEDOFF0 = request.find("/?LED0=OFF")
LEDON1 = request.find("/?LED1=ON")
LEDOFF1 = request.find("/?LED1=OFF")
if LEDON0 != -1:
LED0.high()
if LEDOFF0 != -1:
LED0.low()
if LEDON1 != -1:
● 370
Chapter 14 • Using Micropython with the ESP32 DevKitC
LED1.high()
if LEDOFF1 != -1:
LED1.low()
resp = html
conn.send(resp)
conn.close()
At the beginning of the program, the network libraries and the Pin library are included in
the program, LED0 and LED1 are assigned to GPIO ports 23 and 22 respectively, these
ports are configured as outputs, and the LEDs are turned OFF to start with. The program
then defines the HTML code that is to be sent to the web client when a request comes from
it. This code is stored in variable html.
The web server program sends the html file (statements resp=html and conn.send(resp))
to the client and waits for a command from the client. When a button is clicked on the
client, a command is sent to the web server in addition to some other data. Here, we are
only interested in the actual command sent. The following commands are sent to the web
server for each button pressed:
The web server program on the ESP32 DevKitC makes a TCP connection and reads the
command from the web client (request = conn.recv(1024)). The program then searches
the received command to see if any of the above commands are present in the received
data. Remember that find searches a string for a sub-string and returns the starting posi-
tion of the sub-string in the string. If the sub-string is not found then a -1 is returned. For
example, consider the following statement:
LEDON0 = request.find("/?LED0=ON")
Here, sub-string /?LED0=ON is searched in string request and if found, the starting position
of the sub-string in the string is given. A -1 is returned if the sub-string /?LED0=ON does
not exist in string request. The program looks for a match for all the 4 commands and if a
command is found then the corresponding LED is turned ON or OFF accordingly:
LEDON0 = request.find("/?LED0=ON")
LEDOFF0 = request.find("/?LED0=OFF")
● 371
The Complete ESP32 Projects Guide
LEDON2 = request.find("/?LED2=ON")
LEDOFF2 = request.find("/?LED2=OFF")
if LEDON0 != -1: # If ON0 command found
LED0.high() # Turn ON LED0
if LEDOFF0 != -1: # If OFF0 command found
LED0.low() # Turn OFF LED0
if LEDON2 != -1: # If ON2 command found
LED2.high() #Turn ON LED2
if LEDOFF2 != -1: #If OFF2 command found
LED2.low() #Turn OFF LED2
In this project, the IP address of the web server was 192.168.1.156. The procedure to test
the system is as follows:
• Open your web browser on your PC and enter the website address 192.168.1.156.
• Click a button (e.g. LED0 ON) to turn ON (or OFF) an LED (e.g. LED0).
ampy should be installed on the PC before it can be used. This requires Python 2.7.x or
3.x to be already installed on your PC. In this section we are assuming that Python 2.7 has
● 372
Chapter 14 • Using Micropython with the ESP32 DevKitC
To install ampy, enter the following command from the command line on your PC (see
Figure 14.25):
C:\> cd python27\scripts
You can check whether or not ampy has been installed successfully by entering the follow-
ing help command (see Figure 14.26):
An example of using ampy is given below. Before using these commands you should con-
nect your ESP32 DevKitC development board to the PC and find out the serial port number
assigned to your board (COM47 in the examples below).
An example is given in Figure 14.27 which lists the files on the MicroPython board:
● 373
The Complete ESP32 Projects Guide
#-----------------------------------------------------------------
#
# TRIGONOMETRIC SINE TABLE
# ========================
#
# This program tabulates the trigonometric sine of angles from 0
# to 90 degrees in steps of 5 degrees
#
#
# Program: sinetables.py
# Date : August, 2017
# Author : Dogan Ibrahim
#----------------------------------------------------------------
import math
print("End of program")
● 374
Chapter 14 • Using Micropython with the ESP32 DevKitC
The output of the program is shown in Figure 14.29. Notice that any output from the pro-
gram will be displayed on the PC screen. By default, the run command waits for the pro-
gram to finish running on the board before displaying its output. In many microcontroller
based applications the program is executed in an endless loop and never finishes. In such
applications you must use the --no-output option in the run command. Choosing this op-
tion tells ampy not to wait for any output and to just start running the program and return.
It is also important to realise that any keyboard input cannot be sent to the program.
When the MicroPython installed board is powered up it automatically executes the firmware
file called boot .py. This file should not normally be modified unless if you want to custom-
ise the boot process. You can use the ampy get command to see the contents of the boot.
py file. When boot .py completes it calls to MicroPython program named main .py which
may or may not be resident on the board. If main .py is not resident, we should rename
our program to main .py and upload it to our board. This way, our program will run auto-
matically as soon as the board boots up. The steps are given below.
• Upload the file to the board using the following ampy command:
● 375
The Complete ESP32 Projects Guide
• Make sure that file main.py has been uploaded. Enter the following ampy com-
mand and you should see files boot.py and main.py listed:
• Restart the board and you should see the output displayed on the terminal em-
ulator window.
An example is given here where the small low-cost servo motor Tower Pro SG90 (see Fig-
ure 14.29) is controlled such that it rotates fully left and right with 3 seconds between each
turn.
Black: GND
Red: +3.3 V
Brown: Signal
• Dimension: 22 mm x 12 mm x 31 mm
• Operating speed: 0.3 s/60 degree
• Weight: 9 g
• Operating voltage:4.2 – 6 V
● 376
Chapter 14 • Using Micropython with the ESP32 DevKitC
Even though the minimum operating voltage of the servo is specified as 4.2 V, it will work
at +3.3 V. In this project the signal pin of the servo is connected to GPIO pin 23 and the
other pins to the ground and +3.3 V.
The servo is operated by applying a 50 Hz (period = 20 ms) PWM waveform to it. When the
pulse width is approximately 2 ms the servo rotates fully in one direction. Similarly, when
the pulse width is 1 ms the servo rotates fully in the opposite direction. We can find the
required PWM duty cyles for 2 ms and 1 ms pulses as follows:
For 2 ms pulse:
Because the PWM resolution is 10-bits, the full-scale (100%) duty cycle is obtained when
1024 is loaded into the duty cycle. Therefore, 10% and 5% duty cycles correspond to 102
and 51 respectively. In practice, however, it was found that the servo was fully in one di-
rection when the duty cycle was 126%, and then fully in the other direction when the duty
cycle was set to 15%.
Figure 14.31 shows the program listing. GPIO pin 23 is configured as a PWM channel, the
frequency is set to 50 Hz, and the duty cycle is varied inside a while loop so that the servo
rotates in both directions. 3 seconds of delay is inserted between each rotation.
#----------------------------------------------------------
# SERVO CONTROL
# -------------
#
# In this program a small servo motor is conencted to GPIO
# port 23 of the ESP32 Devkitc. Teh program sends PWM pulses
# to the servo to rotate it fully in one direction, and after
# 3 seconds in the opposite direction. This process is repeated
# until stopped manually.
#
#
# File : main.py
# Author: Dogan Ibrahim
# Date : August, 2017
#----------------------------------------------------------
● 377
The Complete ESP32 Projects Guide
import machine
import time
p23 = machine.Pin(23)
pwm23 = machine.PWM(p23)
pwm23.freq(50) # set frequency to 50 Hz
while True: # Do Forever
pwm23.duty(20) # Turn in one direction
time.sleep(3) # Wait 3 seconds
pwm23.duty(128) # Turn in opposite direction
time.sleep(3) # Wait 3 seconds
Create the program using the Notepad and save it with the name main .py in folder C:\
Python27\Scripts. Then copy the program to your ESP32 DevKitC with the following
command. Restart your ESP32 DevKitC and you should see the servo rotating as expected.
You can remove the program from the root directory of your ESP32 DevKitC with the fol-
lowing command to stop it running at boot time:
In this section we shall be looking at how to use the built-in RTC to load the current date
and time and then how to read this data at a later time.
The RTC can be accessed by the following functions in MicroPython command mode:
● 378
Chapter 14 • Using Micropython with the ESP32 DevKitC
The date and time are displayed as an 8-tuple with the following format:
The date and time can be set using the datetime function. For example the following com-
mand sets the date to 12 November 2018, and the time to 17:55:30, and the Weekday to 1:
We can extract the fields of date and time. In the following example the date fields are
extracted:
● 379
The Complete ESP32 Projects Guide
14 .11 .2 Summary
In this chapter we have seen how to install the MicroPython interpreter on an ESP32
DevKitC. In addition, several examples and projects are also given to show how a MicroPy-
thon program can be developed and run on the ESP32 DevKitC.
● 380
Chapter 15 • Using esp-idF for programming the esp32 DevKitC
15 .1 Overview
Up to now we have been developing programs for our ESP32 DevKitC using the Arduino IDE
and MicroPython. ESP-IDF is the native development environment from Espressif Systems,
developed for the ESP32 processors. This development environment is based on FreeRTOS
and enables users to access all modules of the ESP32 processor. Although the ESP-IDF is
very powerful, it is more difficult to learn to program than Arduino and MicroPython.
In this chapter we shall be looking at how to install the ESP-IDF development environment
to a Windows PC. Some examples will be given to show how an ESP-IDF based program
can be developed and uploaded to the ESP32 DevKitC.
• A Windows, Linux, or Mac operating system (in this chapter we shall be using
Windows).
• A Toolchain to build applications for ESP32.
• An API to operate the Toolchain.
• A text editor to write programs in C (Notepad, Eclipse etc).
• The ESP32 processor board (ESP32 DevKitC is used in this chapter) and a USB
cable.
The application development process consists of writing the code, compiling and linking the
code, uploading the code to the ESP32 processor, and finally testing/debugging the code.
https://dl.espressif.com/dl/esp32_win32_msys2_environment_and_toolchain-20181001.zip
• Unzip the file to C:\ (recommended, but some other location could also be used)
and wait until the unzip process finishes. A directory called msys32 will be cre-
ated under C:\ with many files in it (see Figure 15.1).
● 381
The Complete ESP32 Projects Guide
mkdir esp
15 .2 .2 Getting ESP-IDF
The Toolchain includes the programs to compile and build your applications. In addition to
these, we need ESP32 specific API and libraries which are provided by the ESP-IDF repos-
itory. The steps to get the ESP-IDF are given below (see website: https://docs.espressif.
com/projects/esp-idf/en/latest/get-started/index.html#get-started-get-esp-idf). Here, we
will be installing ESP-IDF into directory esp/esp-idf.
● 382
Chapter 15 • Using esp-idF for programming the esp32 DevKitC
cd c:\msys32
c:/esp/esp-idf/tools/windows/windows_install_prerequisites.sh
15 .2 .3 Path to ESP-IDF
The Toolchain programs use IDF_PATH environment variable to access ESP-IDF. You can set
this path on your PC user profile permanently so that it is available each time PC is re-start-
ed. Alternatively, you can specify the path before building programs.
export IDF_PATH="c:\esp\esp-idf"
https://docs.espressif.com/projects/esp-idf/en/latest/get-started/add-idf_path-to-profile.html
cd esp
python2.7 -m pip install --user -r $IDF_PATH/requirements.txt
● 383
The Complete ESP32 Projects Guide
We should now download a project template. Download and extract it from the following
link. This will create an example template in the blink directory under esp . This template
can be used in our programs, as we shall see later.cd esp
We are now ready to develop our ESP-IDF based projects. Some example projects will be
given to show the steps to write and upload a program to our ESP32 DevKitC. Some useful
examples can be found at the following links:
https://github.com/espressif/esp-idf/tree/master/examples
http://docs.platformio.org/en/latest/platforms/espressif32.html#examples
There are also many examples in the examples directory under esp/esp-idf.
15 .3 .1 Description
This is perhaps the easiest project we can develop using the ESP-IDF. In this project an
LED is connected to GPIO port 23 of the ESP32 DevkitC and the LED is flashed every three
seconds.
15 .3 .2 Aim
The aim of this project is to show how a program can be developed and uploaded to the
ESP32 DevKitC using the ESP-IDF programming environment.
cp –r c:/main.c main/main.c
/*------------------------------------------------------------
FLASHING LED
============
● 384
Chapter 15 • Using esp-idF for programming the esp32 DevKitC
#define LED 23
void app_main()
{
xTaskCreate(&LED_Flash, "LED_Flash", configMINIMAL_STACK_SIZE,NULL,5,NULL);
}
Figure 15.4 Program listing
Notice that you can edit the file using the vim editor if required. Enter vim main .c, then
type "i" (without the quotation) and do the required changes. Then press ESC, followed by
:wq to save and exit from the editor.
Go to directory /esp/blink, and connect your ESP32 DevtKitC to your PC and start the
project configuration utility menuconfig. Here, we will have to define the communication
details between our ESP32 DevKitC and the PC:
make menuconfig
You should see a window as in Figure 15.5. Select option Serial flasher config.
● 385
The Complete ESP32 Projects Guide
Set the Default serial port to COM47 as shown in Figure 15.6 (notice that your COM port
number may be different. Check the correct number in the Hardware Manager). Click OK.
Select Save at the bottom, and then select EXIT to close the window.
We are now ready to compile and upload our program to the ESP32 DevKitC. Make sure
that you are in directory /esp/blink and that the ESP32 DevKitC is connected to your PC.
Enter the following command:
make flash
The first time you use these commands it will take a while for all the necessary files to be
compiled. Wait until you see the success message as in Figure 15.7. Your program should
now start working and the LED will flash every 3 seconds.
● 386
Chapter 15 • Using esp-idF for programming the esp32 DevKitC
We can also use the following commands instead of the make flash command:
We can also start the IDF Monitor by issuing the command make monitor. The IDF Mon-
itor tool is a serial terminal Python program which can be used for debugging purposes to
display and read data from the serial port. More information on IDF Monitor can be obtained
from the following site:
https://docs.espressif.com/projects/esp-idf/en/latest/get-started/idf-monitor.html
LED is assigned to GPIO port 23. The task that is to run is the function LED_Flash. pvPa-
rameter is the pointer that will be used as the parameter for the task being created. LED is
configured as an output and then it is set to logic HIGH and LOW in a loop using statements
gpio_set_level. Function vTaskDelay delays a task for a given number of ticks. Using
constant portTICK_PERIOD_MS enables the delay to be set in milliseconds. Here, the
delay is set to 3000 ms (three seconds).
● 387
The Complete ESP32 Projects Guide
15 .3 .5 Project Files
A project consists of the following files (e.g. in directory /esp/blink):
makefile: This file sets the PROJECT_NAME variable. It includes the $(IDF_PATH)/
make/project .mk makefile
sdkconfig: This is the project configuration file created/updated when make menuconfig
runs.
main: This is a directory that contains the source code for the project. The default name
of the source code is main .c
build: This is a directory where the build output is created after the make command runs.
CMakeLists .txt: This file includes the name of the main source file (e.g. main .c)
15 .4 .1 Description
In this project three LEDs are connected to GPIO pins 23, 5 and 17 through current limiting
resistors. These LEDs are named as NORMAL_LED, FAST_LED, and VERYFAST_LED respec-
tively. This is a multi-tasking project where the LEDs are flashed at the following rates:
15 .4 .2 Aim
The aim of this project is to show how a simple multi-tasking project can be developed
using just three LEDs.
15 .4 .3 Circuit Diagram
Figure 15.8 shows the circuit diagram of the project.
● 388
Chapter 15 • Using esp-idF for programming the esp32 DevKitC
/*-----------------------------------------------------------------------
MULTI-TASKING WITH 3 LEDS
=========================
In this program 3 LEDs are connected to pins 23, 5 and 17 of the ESP32
DevKitC and these LEDs are named as NORMAL_LED, FAST_LED,and VERYFAST_LED
respectively. The LEDs flash at the following rates: NORMAL_LED every 2
seconds, FAST_LED every second, and VERYFAST_LED every 0.5 seconds.
while(1)
{
gpio_set_level(NORMAL_LED, 0); // LED OFF
vTaskDelay(2000 / portTICK_PERIOD_MS); // Wait 2 secs
gpio_set_level(NORMAL_LED, 1); // LED ON
vTaskDelay(2000 / portTICK_PERIOD_MS); // Wait 2 secs
}
}
● 389
The Complete ESP32 Projects Guide
gpio_pad_select_gpio(FAST_LED);
gpio_set_direction(FAST_LED, GPIO_MODE_OUTPUT);
while(1)
{
gpio_set_level(FAST_LED, 0); // LED OFF
vTaskDelay(1000 / portTICK_PERIOD_MS); // Wait 1 sec
gpio_set_level(FAST_LED, 1); // LED ON
vTaskDelay(1000 / portTICK_PERIOD_MS); // Wait 1 sec
}
}
while(1)
{
gpio_set_level(VERYFAST_LED, 0); // LED OFF
vTaskDelay(500 / portTICK_PERIOD_MS); // Wait 0.5 secs
gpio_set_level(VERYFAST_LED, 1); // LED ON
vTaskDelay(500 / portTICK_PERIOD_MS); // Wait 0.5 secs
}
}
//
// Start of main program. The main program starts task LED_FLASH
//
void app_main()
{
xTaskCreate(&NORMAL_LED_Flash, "NORMAL_LED_Flash",
configMINIMAL_STACK_SIZE,NULL,5,NULL);
xTaskCreate(&FAST_LED_Flash, "FAST_LED_Flash",
configMINIMAL_STACK_SIZE,NULL,5,NULL);
xTaskCreate(&VERYFAST_LED_Flash, "VERYFAST_LED_Flash",
configMINIMAL_STACK_SIZE,NULL,5,NULL);
}
Figure 15.9 Program listing
We are now ready to compile and upload our program to the ESP32 DevKitC. Make sure
that the IDF_PATH is set correctly. Enter the following command (note that there is no need
to enter the menuconfig command again):
● 390
Chapter 15 • Using esp-idF for programming the esp32 DevKitC
make flash
Wait until you see the success message. Your program should now start working and the 3
LEDs will flash at different rates.
15 .5 Summary
In this chapter we have briefly looked at how to install the ESP-IDF environment. We have
also developed two simple projects using the ESP-IDF.
The next chapter is about the interesting and useful security features of the ESP32 pro-
cessor.
● 391
The Complete ESP32 Projects Guide
16 .1 Overview
The ESP32 processor has two interesting and useful security features: Flash Encryption
and Secure Boot. The flash encryption and secure boot protect the processor from un-
wanted access. Flash encryption is separate from Secure Boot and we can for example use
flash encryption without secure boot. For the highest security it is recommended to both
encrypt the flash and secure the boot process. In this chapter we shall briefly look at both
of these features.
16 .2 Flash Encryption
The flash is external to the SoC chip and when the device is shipped, any firmware is actual-
ly stored on the SPI flash. It is possible that people with sufficient knowledge of the internal
architecture of the processor can read and/or modify the contents of the flash where the
firmware is stored in plain text form. By encrypting the flash, we can disable its contents
to be read or modified.
The ESP32 has a 1024-bit internal eFUSE which is basically a one-time programmable
memory and this memory is important in managing the security features. The eFUSE is
divided into 4 blocks with 256-bits each block. Blocks 0 and 3 are reserved. The contents
of flash are encrypted using AES-256 and Block 1 stores the 256-bit encryption key for
flash encryption. Encryption is applied by flashing the ESP32 with plaintext data, and when
enabled, the bootloader encrypts the data on first boot. The encryption key is read- and
write-protected so that software cannot access it. Similarly, Block 2 stores the encryption
keys for secure boot. Once the encryption keys are stored in the eFUSE, we can ensure
that no software running on the ESP32 can read or modify these keys. Therefore, these
keys are protected from software access, only the hardware can decrypt the contents of
flash. The flash controller uses the AES keys stored in the eFUSE to perform the encryp-
tion. Any memory-mapped write operations to the flash are first encrypted before being
written to flash. Similarly, all memory-mapped read operations are transparently decrypted
at run time. Every 32 byte block in flash is encrypted with a unique key derived from the
flash encryption key. Once flash encryption is enabled on first boot, the hardware allows a
maximum of three subsequent flash updates. During program development, we can use a
pregenerated flash encryption key to allow re-flashing unlimited number of times.
Flash encryption can be enabled in make menuconfig (see Chapter 14), by selecting
YES for Enable flash encryption on boot under Security Features. Secure Boot can also
be enabled at the same time under Secure Boot Configuration in make menuconfig.
On first boot, the bootloader sees FLASH_CRYPT_CNT eFUSE is set to 0 (which is the
factory default) so it generates a flash encryption key using the hardware random number
generator. This key is stored in eFUSE. All of the encrypted partitions are then encrypted
in-place by the bootloader and the processor should not be interrupted while the first boot
encryption takes place, otherwise the flash could be corrupted (this process can take up
to several minutes). The FLASH_CRYPT_CNT is then set to 1 and this eFUSE limits the
number of subsequent re-flashes. When even number of bits (0,2,4,6,8) are set in FLASH_
CRYPT_CNT, it means that the flash has just been written with plaintext and needs en-
● 392
Chapter 16 • Security features of ESP32
crypting. When odd number of bits (1,3,5,7) are set in FLASH_CRYPT_CNT it means that
flash encryption is enabled and is functional. After the re-encryption process completes, a
"1" is added to FLASH_CRYPT_CNT and the eFUSE is re-burned.
Further details on flash encryption can be obtained from the following website:
https://docs.espressif.com/projects/esp-idf/en/
latest/security/flash-encryption.html
16 .3 Secure Boot
Secure Boot ensures that only trusted and known software runs on your device. This fea-
ture can be used, for example, to ensure that only your code runs on the device. Secure
Boot encryption key is stored in Block 2 of eFUSE. A single eFUSE bit is burned to perma-
nently enable secure boot on the chip. The bootloader generates this key from the internal
hardware random number generator. Secure Boot can be enabled from make menuconfig.
After a reset, the BootROM uses the secure boot key in eFUSE to verify the Software Boot-
loader. Once this is verified, then the BootROM executes the Software Bootloader to load
the application firmware.
If flash encryption is used without secure boot, it is possible to load unauthorised code
using serial re-flashing, and this unauthorised code can then read all encrypted partitions
(in decrypted form), thus making flash-encryption ineffective. This can be avoided by write
protecting FLASH_CRYPT_INC (or by enabling secure boot).
Further details on Secure Boot can be obtained from the following website:
https://docs.espressif.com/projects/esp-idf/en/latest/security/secure-boot.html
espefuse.py should be available on your PC if you have already installed V2.0 (or newer)
version of esptool.py.
Some examples of using espefuse.py are given in the following sections. Here, it is as-
sumed that your ESP32 DevKitC is connected to serial port COM47. The default baud rate
is 115200.
16 .4 .1 eFUSE Summary
The following command displays a summary of the eFUSEs (assuming espefuse.py is not
in the path).
c:\> cd \msys32\esptool
c:\msys32\esptool> python espefuse.py –port COM47 summary
● 393
The Complete ESP32 Projects Guide
Notice that the eFUSEs are set to 0 since they are unburned. There are 32 byte blocks of
eFUSEs where BLK1 and BLK2 hold the flash encryption and secure boot keys respectively.
By default, the flash encryption process will burn eFUSEs DISABLE_DL_ENCRYPT, DISA-
BLE_DL_DECRYPT and DISABLE_DL_CACHE on first boot, where:
DISABLE_DL_CACHE disables the entire MMU flash cache when running in UART boot-
loader mode.
● 394
Chapter 16 • Security features of ESP32
Notice that the display also shows the chip ID (MAC address), chip version etc. Users should
refer to the ESP32 Technical Manual for further information.
Further information on other espefuse.py commands are available at the following web-
sites:
https://github.com/espressif/esptool/wiki/espefuse
https://github.com/espressif/esptool
16 .5 Summary
Security and encryption are important issues when we develop applications software that
we wish to market. In this chapter we had briefly looked at the basic features of the ESP32
security and encryption processes. Interested readers should refer to the given websites for
further detailed information on these topics.
● 395
The Complete ESP32 Projects Guide
APPENDIX A
A list of all the components used in the book is given in this Appendix:
1 x ESP32 DevKitC
8 x LEDs (RED)
1 x LED (GREEN)
8 x 330 ohm resistors
2 x push-button
1 x Buzzer
1 x RGB LED
1 x 4-channel Relay Board
1 x SD card module
1 x Infrared Receiver module
1 x TMP36 temperature sensor chip
1 x DHT11 temperature and humidity chip
1 x MCP4921
1 x MCP23017
1 x LDR
1 x BC108 (or any other PNP) transistor
1 x 7 segment LED
1 x Small Microphone Module
1 x I2C LCD
1 x SG90 servo
1 x 4x4 Keypad
8 x Female-Male jumpers
4 x Male-Male jumpers
1 x Small breadboard
● 396
APPENDIX B
APPENDIX B
● 397
The Complete ESP32 Projects Guide
9
10
11
12
Bluetooth BLE 1 13.3
2 13.4
Bluetooth Classic 3 13.5
4 13.6
5 13.7
Python 14
ESP-IDF 1 15.3
2 15.4
Security 16
Encryption 16
● 398
59 Experiments with Arduino IDE and Python
● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEA
IGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● D
HARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN
N ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEA
SIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● D