0% found this document useful (0 votes)
26 views121 pages

ebook-esp32-part-1

1) The document is a compilation of texts about the ESP32 microcontroller, the successor to the ESP8266, aimed at helping beginners take their first steps with the device; 2) The first text summarizes the main technical characteristics of the ESP32 such as integrated WiFi and Bluetooth, faster processors, more RAM, among others; 3) The other texts provide guides for setting up the ESP32 development environment on Windows, both using the Arduino IDE and using.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
26 views121 pages

ebook-esp32-part-1

1) The document is a compilation of texts about the ESP32 microcontroller, the successor to the ESP8266, aimed at helping beginners take their first steps with the device; 2) The first text summarizes the main technical characteristics of the ESP32 such as integrated WiFi and Bluetooth, faster processors, more RAM, among others; 3) The other texts provide guides for setting up the ESP32 development environment on Windows, both using the Arduino IDE and using.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Ebook - Part 1

Hello,

Thank you for downloading our ebook: Introduction to the ESP32 - Part 1. This ebook brings a
collection of texts already published in Embarcados, written by various authors.

We compiled a collection of texts that we consider important for the first


steps with the ESP-32. I hope you enjoy this material and it helps you in your
journey

We continue with the mission of publishing new texts daily on the site.

A big hug.

Embedded Team.

1
Summary

ESP32: the successor of the ESP8266 7

Setting up the ESP32 development environment on Windows 10

Setting up the Eclipse environment for the ESP32 20

ESP32 - understanding the Strapping pins 43

ESP32 - Analyzing and correcting the internal ADC 53

ESP32 - Security and protection of the flash 72

Controlling ESP32 via WiFi with MAC address validation 89

Espressif announces support for graphic libraries on the ESP32 106

NORVI IIOT - ESP32 for industrial projects 113

Maixduino: a super board with RISC-V AI and ESP32 118

2
ESP32: the successor of the ESP8266
Author:Fábio Souza

AEspressif Systemsreleased today anote on Twitterabout the arrival of the ESP32 for
beta tests. The ESP32 will be the successor of theESP8266and will bring new features and improvements,
for example, WiFi and Bluetooth connection in the same module.

3
Figure 1 - Module with the new SoC

The following features will be available in the new SoC:

● Faster WiFi: The new WiFi has been improved to support HT40 speed.
(144.4 Mbps).
● Bluetooth and Bluetooth Low Energy;
● 2 processorsTensilicaL108 working at 160 MHz;
● Low Power: various operating modes for low consumption;
● Peripheral varieties: Capacitive touch, ADCs, DACs, I2C, UART, SPI, SDIO.
I2S, RMII, PWM, but it will not have USB yet;
● More RAM: ~400 KB;
● Improved security: Hardware accelerators for AES and SSL, with various
improvements
● Simplified APIs: the API is being improved. The development is still in progress.
progress is on the way and will be available soon.

4
Figure 2 - Block diagram of the ESP32

The testing program will begin soon, according to the statement from Espressif System.
Boards will be sent to selected developers in the next two weeks.
However, there will initially be only 200 plates.

In the announcement, they also extended an invitation to developers from around the world.
send your interest in working together with them, whether in Shanghai or wherever you are,
because the company is always in search of new talents for the team.

Originally published on Embarcados, on 11/05/2015:linkfor the original article,


under the LicenseCreative Commons Attribution-ShareAlike 4.0 International.

5
Setting up the environment of
development of the ESP32 in
Windows
Author:Gabriel Almeida

TheESP32it is a new microcontroller, successor to the ESP8266, created and developed by


Espressif Systems, launched in September 2016. Its main innovation, just like
its predecessor, consists of the use of wireless connectivity modules for projects of
IoT. The new device comes with WiFi, Bluetooth, and a host of peripherals that it
superior to Arduino in terms of memory, processing, among others.

6
The purpose of this article is to assist the reader in installing and configuring the environment for
the development of works and projects that will use the ESP32.

The main application development platforms for the ESP32 are:

● ESP-IDF: framework developed by ESPRESSIF itself for the ESP32. It is a


a more robust environment, but complicated to use;
● Arduino IDE: it is possible to configure the Arduino environment to manipulate
the ESP32. Because it is a more familiar environment, it becomes a simpler means and
accessible for beginners.

Installation of the ESP32 module in the IDE


Arduino

In the case of Windows, the installation procedure is divided into the following steps:

Download and install Python (version 2.7 or higher);


Download and install Git;
Clone the repository;
Run the application [Link].

7
Python and Git can be downloaded from the following sites, respectively:

● [Link]
● [Link]

To clone the repository, run the Git graphical interface:

Figure 1: Git graphical interface.

Select the option 'Clone Existing Repository'. In the 'Source location' field, enter the
following link:

[Link]

In the 'Target Directory' field, select the location where the Arduino IDE was installed. It should
be something like:

8
C:/Users/[YOUR_USERNAME]/Documents/Arduino/hardware/espressif/esp32

Figure 2: Menu to clone a repository.

After installation, in the tools folder, run the file [Link] and wait for the programs
be downloaded and configured. After this procedure, the command prompt will be
automatically closed.

This concludes the installation of the ESP32 module. Now, to carry out projects with this
board, just program normally in the Arduino IDE, but instead of selecting
an Arduino board, select your version of the ESP32.

9
Installation of the ESP32 module with the
ESP-IDF
Continuing with Windows, to develop applications for the ESP32, you will need:

● Toolchain, which is a set of compilation tools;


● Do ESP-IDF, which contains the API for the ESP32 and scripts to operate the Toolchain;
● A text editor for writing programs;
● The ESP32 board and a cable to connect it to the computer.

The preparation of the development environment consists of 3 steps:

● Configure the Toolchain;


● Download the ESP-IDF from GitHub;
● Install and configure Eclipse.

Once the environment is set up, let's go to the application. The process of configuring
the application can be divided into 4 stages:

● Set up the project and write the code;


● Compile the project and attach it to the application;
● Run the project on the ESP32;
● Monitor and correct the application's errors.

Following the first step, let's configure the Toolchain. The quickest way to
the procedure is to install a predefined one, which can be downloadedhere.

10
Extract the zip file to C: and then open the MINGW32 terminal, located at
C:[Link]. Create a folder named esp, with the following command:

mkdir -p ~/esp

This folder will be the default location to develop ESP32 applications.

Obtaining the ESP-IDF


In addition to the Toolchain, you will also need the specific libraries for the ESP32. For
to obtain them, type the following in the same terminal used previously:

cd ~/esp
git clone --recursive [Link]

The Toolchain accesses the ESP-IDF using the environment variable IDF_PATH. If this
if the variable is not defined, the projects are not properly executed. This variable
must be configured every time the computer is started, or permanently, in
user profile. To do this, follow the instructions below:

● Create a new script file in the folder: C:/msys32/etc/profile.d/ with the name of
export_idf_path.sh;
● Identify the path to the ESP-IDF directory. It should be something like
C:msys32homeuser-nameespesp-idf;
● Add the export command to the script as follows: export
IDF_PATH="C:/msys32/home/user-name/esp/esp-idf"

11
● If you do not want the variable IDF_PATH to be set permanently, just
open o terminal MSYS2 etype command:
o export
IDF_PATH="C:/msys32/home/user-name/esp/esp-idf"

Setting up the project


To exemplify the process of creating and manipulating a project on the ESP32, let's
use a pre-defined code, which can be found in the examples directory, in
ESP-IDF. First, we will copy the hello_world project to the esp directory.
typing the following command in the terminal:

cd ~/esp
cp -r $IDF_PATH/examples/get-started/hello_world

Now, in the terminal window, go to the hello_world directory by typing:

cd /esp/hello_world

Start the project configuration menu by typing:

make menuconfig
The following menu will be presented after a few moments:

12
Figure 3: ESP-IDF configuration menu.

Once in the menu, navigate to Serial flasher config > Default serial port and type the port
serial that will be used by the ESP32:

Figure 4: Flasher configuration menu.

13
As soon as the settings are properly updated, it is possible to compile the
application and all the components of the ESP-IDF. To do this, type in the terminal:

make flash

And, if there are no problems, you will see messages describing the process of
loading.

Monitor
To see if the application 'hello_world' is actually working, type:

make monitor

A few lines below, you should see the message 'Hello world!' appearing in
terminal.

This concludes the process of setting up a project using the ESP-IDF. Now that the
the environment is properly configured, the applications of the ESP32 can be worked on.

14
References
[Link] provided link is a URL to a GitHub repository containing information about installing the Arduino core for the ESP32 microcontroller.
structions
2.[Link]

Originally published on Embarcados on 08/16/2018:linkfor the original article,


under the LicenseCreative Commons Attribution-ShareAlike 4.0 International.

15
Setting up the environment
Eclipse for ESP32
Author:Muriel Costa

Eclipse is a very complete and beloved open-source IDE among developers.


in addition to being very flexible allowing for various types of customizations. In this article I show
how to use it to create a development environment for the ESP32, so that
issue the command line to compile and save the project. We will do everything
graphically.

It is important to note that this post does not cover the part of the ESP IDF configuration.
Therefore, you should already have the environment set up to proceed. You can
see how to configure the ESP IDFnextarticle by Gabriel Almeida. It is also worth remembering
that this article takes place in a Windows environment on my machine and perhaps some
steps do not apply to Linux users.

16
Download and installation of Eclipse
First, you need to download the tool onsiteofficial. In the window that
It will open, you must choose the installation of 'Eclipse IDE for C/C++ Developers'.
according to the figure below.

Figure 1: Installing eclipse

After choosing the package, the next steps will be to select the installation directory and
wait for the completion. If you have any questions about the installation of the tool, you can
check theguia de instalação official.

17
Importing and configuring the project
Now it is time to port a project to Eclipse! Be careful when following the steps of this
tutorial literally, since there may be some small divergences between yours
environment and my installation and project folder.

Recognizing the folder structure of


project
Navigate to the msys32 folder and go into the folder you created to allocate the esp-idf folder.
In my case, it's the ESP32 folder and that's where the folders for my projects are also located.

Figure 2: Structure of the project folder

Now it is time to create a new project, let's import a project example "hello
world" located in the esp-idf folder. Enter the esp-idf folder -> examples -> get-started. In

18
in the 'get-started' folder you will find a folder named 'hello_world', copy it to
folder 'ESP32' (your project folder) next to the esp-idf folder.

The result should look like the figure below.

Figure 3: Project 'hello_world' pasted in the projects folder

Let's start Eclipse to begin the import and configuration of our project!

Open Eclipse and in the top bar click on file -> import. Note: If on startup it
ask to select a default address for projects, select the ESP32 folder.

19
Figure 4: Importing project.

In the import window, select C/C++ -> Existing Code as Makefile Project.

20
Figure 5: Parameters for project import.

In the Project Name field, enter the name of your project. In our case, as
we import Hello World, I will keep it. In Existing Code Location we need to point
the address where our project is, this directory should be the one that contains the file
Makefile of our project.

Select the Cross GCC Toolchain and click Finish.

21
Figure 6: Naming project and choosing Toolchain.

Well, our project is already in eclipse and the result should be like the figure below. Now the
People need to set it up, let's go!

22
Figure 7: Appearance of the eclipse with the project open

Your project is open in the Project Explorer field, right-click on it and


click on properties.

23
Figura 8: Acessando menu de configuração do projeto.

● Click on C/C++ Build -> Environment and in the window we will add some
variables and modify another.
● Click on Add and fill in the name field with 'BATCH_BUILD' and value 1.
● Click on Add again and fill in the name field with 'IDF_PATH' and the value
it must be the path of the esp-idf folder, in my case the value is
C:\msys32\ESP32\esp-idf
● Double-click the "PATH" variable to edit it, in the value field, add to
final os following values
;C:\msys32\mingw32\bin;C:\msys32\opt\xtensa-esp32-elf\bin;C:\msys32\usr\bin

24
Attention: do not delete the value field of the PATH, simply add it.
in the end.

Figure 9: Changing environment variables.

Click on C/C++ Build and in the Builder Settings tab uncheck the option 'use default build'
command", put the following value in the Build command field: python
${IDF_PATH}/tools/windows/eclipse_make.py

25
Figure 10: Changing the build command.

In the Behavior tab, enable the Enable parallel build field to increase speed.
build process.

26
Figure 11: Enabling parallelism.

Go to "C/C++ General -> Preprocessor Include Paths, Macros...". In the Providers tab
select CDT Cross GCC Built-in Compiler Settings and change the 'Command to get
compiler specs for xtensa-esp32-elf-gcc ${FLAGS} -std=c++11 -E -P -v -dD
${INPUTS}

27
Figure 12: Modifying 'Command to get compiler specs'.

Now select the 'CDT GCC Build Output Parser' and change the 'Compiler command
pattern for xtensa-esp32-elf-(gcc|g++|c++|cc|cpp|clang)

28
Figure 13: Modifying 'Compiler command pattern'.

Go to C/C++ General -> Indexer, enable the field 'Enable project specific settings' and
disable the 'Allow heuristic resolution of includes' field.

29
Figure 14: Configuring indexer.

Everything is fine with the properties of our project, now let's click on 'Apply and
Close. Now it's time to add the build targets, we use them for build, flash, and rebuild.

Right-click on the project folder and click on 'Build Targets -> Create...'.

30
Figure 15: Creating targets.

In the Target name field, fill in with 'all' and press OK. Repeat the process again.
para os seguintes nomes: "clean" e "flash".

31
Figure 16: Creating target.

The expected result should be as shown in the figure below.

Figure 17: List of targets.

32
Go to the root folder of the ESP IDF environment installation, the msys32 folder, and execute the
mingw32 application. Now use the cd command to enter the directory of our folder
of the project:

$ cd /c/msys32/ESP32/hello_world

Execute the command:

$ make menuconfig

Figure 18: Accessing MENUCONFIG through mingw32.

The result should be as shown in the figure below. Use the navigation menu to go to the serial
flasher config.

33
Figure 19: Accessing the serial configuration menu.

Fill in the default serial port field with the port that your ESP32 device is on,
In my case, it's COM5. Save and exit the menu.

34
Figure 20: Configuring the serial port of the ESP32.

Go back to the eclipse and in the build targets we created, click on all twice. The first
Execution may take a little while, but soon your project will be compiled! Note
the errors that previously appeared in main.c have now disappeared.

To upload the code to the board, click the flash button twice.

35
Figure 21: Project compiled without errors.

Resolving possible errors at the time of


compile in eclipse:

Maybe you experienced the following problem when compiling:

File "C:/msys32/sdk/esp-idf/components/esptool_py/esptool/[Link]", line 24, in import


serialImportError: No module named serialmake[1]: ***
[/sdk/esp-idf/components/esptool_py/[Link][Link]
/sdk/esp-idf/myexamples-01092016/02_blink/build/bootloader/[Link]] Error 1make:
*** [/sdk/esp-idf/components/bootloader/[Link][Link]
/sdk/esp-idf/myexamples-01092016/02_blink/build/bootloader/[Link]] Error 2

36
This may be related to the version of python you have installed or the way it is.
called. A solution that worked in my case was to change the name of the interpreter
python from python to python2.

Figure 23: Modifying the call name of the Python interpreter.

37
Figure 24: Modified Python interpreter call name.

Well, that's it guys! I hope you liked it.

References
1.[Link]
2.[Link]

Originally published on Embarcados, on 05/28/2019:linkfor the original article,


under the LicenseCreative Commons Attribution-ShareAlike 4.0 International.

38
ESP32 - getting to know the pins of
Strapping
Autor: Alexandre Fernandes dos Anjos

Projects with this powerful microcontroller from Espressif have been becoming very
frequent, offering wireless connectivity, Wi-Fi and Bluetooth, at very low costs.
competitive, allowing for the creation of various applications for IoT. I will bring here in this article,
details about the strapping pins of theESP32, para evitar problemas nos seus projetos
based on this platform.

What are strapping pins?


The strapping pins define some configurations of the ESP32. During the short
processo de inicialização da CPU, é lido o estado lógico presente na entrada de cada um

39
these special pins and these states (0 or 1) are in turn written in a register
called 'GPIO_STRAPPING'.

After the initialization process, these pins return to functioning with their normal function.

The bits of this register configure the boot mode, the voltage present on the pin
VDD_SDIO and other initial functions that we see in the table below:

Figure 1 - Table of strapping pin functions

The ESP32 has five strapping pins: GPIO_12, GPIO_0, GPIO_2, GPIO_15, and GPIO_5.

40
Figure 2 - Highlight of the pins on the ESP32-WROOM-32 module

Each strapping pin is internally connected to a pull-up or pull-down resistor.


internal during chip initialization (see the "Default" column in the table of Fig.01).
Consequently, if the pin is disconnected or the external circuit connected is of
high impedance, the internal pull-up/pull-down determines the default input level of
strapping pins. To change the default values, the user can apply the resistors
externally to change the logical state of the input.

41
Understanding the functions of the pins of
strapping
Let's understand what exactly each strapping pin does, following the table of
Fig.01:

GPIO_12:Tensão do LDO interno do chip: Se este pino estiver desconectado (pull-down


internal) or with a logical level 0 at its input during initialization, the pin
VDD_SDIO, which is an external power supply voltage output of the chip, used for
Peripheral power supply will have a voltage of 3.3V at its output. Now, if it has a level
logic 1, your output will be 1V8.

GPIO_0 and GPIO_2: Boot Mode: If both pins are disconnected or


GPIO_0 at logical level 1 on its input, the ESP32 will execute the firmware written in
FLASH memory via the SPI bus. To enter the writing mode of the ESP32
(download boot) both pins must be at logical level 0.

These three strapping pins above are the ones that cause the most problems. Let's understand
the reason soon.

GPIO_15: Initialization log on the output of the serial communication pin U0TXD: If this
pin is disconnected (internal pull-up) or has a logical level 1 at its input,
we will have at the output of pin U0TXD, which is related to the serial communication of the chip, the Log of

chip initialization, with various relevant information. At logical level 0 this Log is
disabled.

42
Figure 3 - Segment of initialization log on pin U0TXD

GPIO_5 and GPIO_15: SDIO Slave Timing: These pins define the characteristics
from the communication of the chip with the SD card peripheral. If both are disconnected
(internal pull-up) or logic level 1, the communication will be of the type Rising-edge Sampling /
Rising-edge Output.

Finally, the problems


The problems begin when we forget about these strapping pins and their states.
logical when we are defining the GPIOs in the project schematic.

See the schematic below, we defined the I2C bus on GPIO_12 and GPIO_13:

43
Figure 4 - I2C Bus

We forgot that GPIO_12 (defined as SDA of I2C) is a strapping pin,


We routed and assembled the project's board this way. What will happen when you turn it on?
plate?

● Simply nothing will work: nothing on the serial output, nothing for recording, nothing for
boot.

We know that there is a need for pull-up resistors on the communication bus.
I2C for it to function properly. See R21 and R22 in the schematic.

By placing these resistors so that the I2C works, we set GPIO_12 to level
Logical 1... There lies the problem!!!

44
With the logical level set to 1 during the initialization of the ESP32, the FLASH memory
internal to the module that has the correct supply voltage of 3.3V, it has become
powered by 1V8. Below the recommended operating voltage.

Figure 05 below shows how the FLASH memory is connected internally to the module. The
The memory power supply (pin 8 - VCC) comes from the VDD_SDIO pin, which has its voltage
output defined by GPIO_12 during initialization.

Figure 5 - Internal FLASH memory connection to the module

There is even a note in the datasheet about this situation (MTDI is the GPIO_12):

45
Figura 6 - Nota no datasheet do ESP32

Another situation:

A simple button connected to GPIO_2. A pull-up resistor and the button connected to GND.
We see this in various projects. See in Fig.07 below:

Figure 7 - Connection of button to GPIO_2

Once again we will have problems, this time the ESP32 will not enter programming mode. The
GPIO_2 defines the boot mode and to enter download (recording) mode, both

46
pins, GPIO_2 respectively and also GPIO_0 must be at logic level 0. And
in this case the GPIO_2 is permanently at logical level 1 through the resistor of
pull-up R21.

This other situation in Fig.08 does not bring as many functional problems, but it can provoke
strangeness to those waiting for the initialization log to be printed on the chip's serial.

Figure 8 - LED connected to GPIO_15

We define GPIO_15 in the program as an output for activating an LED.

47
During the startup of the ESP32, GPIO_15 is connected to GND through the
resistor R21 and the LED D10 directly polarized. With GPIO_15 at logical level 0
we have the disabling of the Output Log.

Conclusion - ESP32 - understanding the pins


of Strapping
The datasheet is always the best friend of a hardware developer. The rule of
What remains here is the careful reading of the datasheet and other documents.
relevant, always when starting to work with a new device (Oh, this includes
the Errata documents too!). Pay attention to the details and the manufacturer's notes.
Make a list of important points to be noted during the project
(check-list).

This will help avoid errors, but if any slip through, it will aid in faster debugging.

References
1.[Link]
2.[Link]
f
3.[Link]
heet_en.pdf

48
Originally published on Embarcados, on 02/18/2020:linkfor the original article,
under the LicenseCreative Commons Attribution-ShareAlike 4.0 International.

ESP32 - Analyzing and correcting


the internal ADC
Author:José Morais

Maybe you have already seen somewhere that the ADC of the ESP32 is not linear or has too much
error in the readings, but what does this mean in practice? How can we solve it? Who will

49
help us? It is what we will analyze and try to correct in this article dedicated to the ADC of
ESP32.

Figure 1 - ESP32 ADC.

ESP32 and its peculiar ADC


After many complaints regarding the ADC on the ESP8266, especially about
count only 1 channel (1 V, 10 bits, SAR ADC) for this task, Espressif listened to your
users. In the ESP32 it included 18 channels (1.1 - 3.9 V, 9 - 12 bits, SAR ADC), which was separated
in 2 controllers, ADC1 (8 channels) and ADC2 (10 channels). This allows us, for example,
read 2 channels in parallel or even with DMA for audio and video protocols like I2S,
what a great advance!

50
Some curious details about the ADC in
ESP32
● Both controllers can be used in the digital domain and RTC, which are focused
at speed (2 M Samples/Sec) and low consumption (200 K Samples/Sec)
respectively;
● Configurable resolution: 9, 10, 11, and 12 bits;
● Configurable maximum voltage (internal attenuation): 0 dB (1.1 V), 2.5 dB (1.5 V), 6 dB
(2.2 V), 11 dB (3.9 V limited by VDD_A);
● Recommended voltage ranges for better accuracy:
○ 0dB: 100 - 950mV;
○ 2.5dB: 100 - 1250mV;
○ 6dB: 150 - 1750mV;
○ 11dB: 150 - 2450mV.
● The ADC2 cannot be used while the Wi-Fi is on, as the channel is
shared with the wireless communication module driver. A means to
To work around this, you would turn off the WiFi during the measurement and then turn it back on again;

● The ADC measurements will be noisier while WiFi is on.


sometimes due to poor diet and/or signal filtering;
● ULP allows ADC reading even during deep sleep;
● Each ESP32 can have up to 6% difference in readings, largely due to voltage.
the reference voltage (Vref) of the ADC has a large variation (1000 - 1200 mV). This
Variation in Vref causes different readings between the chips, see figure 1 below.
the comparison of 2 ESP32 with different Vref.

51
Figure 2 - Readings with different Vref.

Testing the ADC


Now that we know a little more about the details of the ADC, let's do some
tests in practice to analyze your curves.

The measurements were made with a simple average of 100 samples spaced 30 microseconds apart.
each, without capacitors or any method beyond the simple average for filtering. In
for all tests, we will adopt a reading with the standard Vref ("ADC Uncal") and another with
the calibration API using the true Vref ('ADC Cal'), which is stored in
memory of the newer ESP32s, manufactured from 2018 onwards. After the tests, we will
understand how to use the calibration API provided by Espressif.

52
The formula used in the measurements without calibration was:

1.1 or 3.3 V.

Resolution: 1024 or 4096.

ADC: Value read from pin.

Test A
In this test (figures 3 and 4), we will analyze ADC1 (GPIO36) and its error at 0 dB for the
following options:

● Wi-Fi OFF;
● 10 and 12 bits;
● 0 dB (0 - 1100 mV);
● Vref ADC Descal: 1100 mV;
● Vref ADC Cal: 1072 mV.

53
Figure 3 - 0dB Curves.

Figure 4 - Error of the 0dB curves.

Observing figures 3 and 4 that show the ADC reading and error for '0 dB, 10 and 12 bits.
with Wi-Fi OFF, we can see that the curve using the calibration API remained with
error <= 5 mV throughout the recommended voltage range, tending to 0 mV. The readings of 10 and
12 bits were practically identical, with no significant discrepancy in the

54
order of mV, but if you need more accurate and consistent readings, redo the
test with your board and analyze the results.

Despite the error with the calibration tending to ~0 mV in the voltage range recommended by
Espressif (100 - 950 mV), outside these limits, the error is large and can be completely
unacceptable, discarding these readings in many projects.

Test B
In this test (figures 5 and 6), we will analyze the ADC1 (GPIO36) and its error at 0 dB for the
following options:

● WiFi ON;
● 10 and 12 bits;
● 0dB (0 - 1100 mV);
● Vref ADC Descal: 1100 mV;
● Vref ADC Cal: 1072 mV.

55
Figure 5 - 0dB Curves.

Figure 6 - Error curves 0dB.

Observing figures 5 and 6 that differ from test A only by Wi-Fi ON,
we can see that the errors in the calibrated measurement, near the end, were greater than with the
Wi-Fi OFF. In addition, throughout the measurement range, there was noticeable noise on the graph.
there may be a need for better analog or digital filters.

Now let's change things up a bit, where most people program using the Arduino IDE.
reside. The following two tests will have an internal attenuation of 11 dB, which allows for
reading of 0 - 3.9 V (limited by VDD_A), standard in the Arduino IDE. Espressif itself says
that at 11 dB it loses linearity while at 0 dB it does not, so let's observe.

Test C

56
In this test (figures 7 and 8), we will analyze the ADC1 (GPIO36) and its error with 11 dB for
the following options:

● WiFi OFF;
● 10 and 12 bits;
● 11 dB (0 - 3900 mV);
● Vref ADC Descal: 1100 mV;
● Vref ADC Cal: 1072 mV.

Figure 7 - 11dB Curves.

57
Figure 8 - Error curves 11dB.

We can see that the errors have increased and it has also become much less linear,
mainly after 2 V. Even using calibration with true Vref, it was not the
sufficient to approximate the error to ~0 mV, remaining close to ~25 mV in the range
recommended.

Test D
In this test (figures 9 and 10), we will analyze the ADC1 (GPIO36) and its error with 11 dB for
the following options:

● WiFi ON;
● 10 and 12 bits;
● 11 dB (0 - 3900 mV);
● Vref ADC Descal: 1100 mV;

58
● Vref ADC Cal: 1072 mV.

Figure 9 - 11dB Curves.

Figure 10 - Error curves 11dB.

59
Again, we repeat the same test as the previous one, but with Wi-Fi ON. The curves
they remain similar, however, the noise generated by WiFi is quite noticeable, even being
It is inadvisable to use the ADC with WiFi ON in products that require stable readings.

Some measures to try to improve reading are to use an external attenuator such as
resistive divider at 0 dB and add analog/digital filters.

Calibration API
Espressif, after so many complaints from users, began to make available a
library (API) for ADC calibration with tables for comparison that also
they use two methods to tune the reading between the chips, which are recorded in the memory
(eFuse) of the latest ESP32s manufactured from 2018 onwards:

● Vref: The calibration with Vref represents the true value of Vref in that ESP32.
When available, it is used by the API instead of the standard (we will see more on this later);
● Two Point: The two-point calibration has the ADC1 and ADC2 readings for 150.
mV is 850 mV on that ESP32. If available, this method takes precedence over
the Vref when used by the API.

The ADC API does all the work of compensating the curves according to these and other
values recorded in memory. More details in the references at the end of the article. If still
if it's not enough, you can perform your own analyses and individual calibrations
the boards with some correction formula, as Espressif did in its line
assembly, however, in an automated way.

And if my ESP32 is earlier than 2018, will I be able to use this calibration? Yes, that's the case.
let's test now, changing the reference voltages to the maximums, standard and
true.

60
Test E
In this test (figures 11 and 12), we will analyze ADC1 (GPIO36) and its error with 0 dB for
the following options:

● WiFi OFF;
● 12 bits;
● 0 dB (0 - 1100 mV);
● Vref: 1000, 1100, 1200, 1072 mV.

Figure 11 - Vref 0dB Curves.

61
Figure 12 - Vref 0dB curve errors.

Observing figures 10 and 11, we can see that there is great variation assuming the
worst cases (1000 and 1200 mV). Only for the 1072 mV curve was the Vref used.
recorded in memory, with the rest defined in the code. Any of these curves
it is still better than using the method without calibration as seen in figures 2, 3, 4 and
5.

Test F
In this test (figures 13 and 14), we will analyze the ADC1 (GPIO36) and its error with 11 dB.
for the following options:

● WiFi OFF;
● 12 bits;
● 11 dB (0 - 3900 mV);
● Vref: 1000, 1100, 1200, 1072 mV.

62
Figure 13 - Vref curves 11dB.

Figure 14 - Vref curve error 11dB.

Observing figures 13 and 14, the errors with Vref 1200 mV reach up to nearly 300.
mV, being completely disposable in many products. Even assuming the Vref
true, it was not able for the error to tend to ~0 mV as at 0 dB. Again, any

63
one of these curves will be much better than without the calibration API, as seen in
figures 7, 8, 9 and 10.

Let's then roll up our sleeves and use this calibration API, which does everything.
dirty work for us. The code is simple, just initialize the structure
internal for calibration and then convert the read RAW value to mV with the function
specific to the API. The API will use the best method to fine-tune the reading whenever
available.

Code
#include<driver/adc.h>
#include<esp_adc_cal.h>
#include<freertos/FreeRTOS.h>
#include<freertos/task.h>
#include<esp_err.h>
#include<esp_log.h>

esp_adc_cal_characteristics_t adc_cal; //Structure that contains the information for calibration

voidapp_main()
{
adc1_config_width(ADC_WIDTH_BIT_12);//Configures the resolution
adc1_config_channel_atten(ADC1_CHANNEL_0, ADC_ATTEN_DB_11);//Configures the attenuation

esp_adc_cal_value_t adc_type = esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN_DB_11, ADC_WIDTH_BIT_12,


1100, &adc_cal);//Initialize the calibration structure

if(adc_type == ESP_ADC_CAL_VAL_EFUSE_VREF)
{
ESP_LOGI("ADC CAL","Vref eFuse encontrado: %umV", adc_cal.vref);
}
else if(adc_type == ESP_ADC_CAL_VAL_EFUSE_TP)
{
ESP_LOGI("ADC CAL", "Two Point eFuse found");
}
else
{

64
ESP_LOGW("ADC CAL","Nothing found, using default Vref: %umV", adc_cal.vref);
}

while(1)
{
/*
Obtain the RAW reading from the ADC to be used later by the calibration API.

Simple averages of 100 readings spaced 30us apart


*/
uint32_t voltage =0;
for(int i = 0; i < 100; i++)
{
voltage += adc1_get_raw(ADC1_CHANNEL_0);//Get the RAW value from the ADC
ets_delay_us(30);
}
voltage /=100;

voltage = esp_adc_cal_raw_to_voltage(voltage, &adc_cal); // Converts and calibrates the read value (RAW) to mV
ESP_LOGI("ADC CAL","Read mV: %u", voltage);//Displays the calibrated reading on the Serial Monitor

vTaskDelay(pdMS_TO_TICKS(1000));//Delay 1seg
}
}

Testing this code, you will also find out if your ESP32 has the values of Vref or
Two points recorded in memory, in addition to checking the calibrated voltage being displayed in
Serial Monitor.

65
Attention, it is necessary for the Vref and/or Two Point options to be enabled in
MENUCONFIG for API to be able to use, which comes by default ON, but can be
It is necessary for you to manually check if it is activated. More information in the references.

Conclusion
After several tests with the ADC on the ESP32, we can conclude that it really
it's not so good for some products, but Espressif's calibration is very useful and serves
for many others, even more so when 0 dB. If you need something even more
sophisticated, can use digital and/or analog filters to enhance a signal more
pleasant, in addition to applying some mathematical formula for correcting the ADC curve
(Excel can do this!).

If your product requires a better ADC, it would be advisable to use an ADC.


external, which is dedicated to this function and is usually much better than built-in ADCs
of microcontrollers. Continue studying ways for ADC calibration and say
for people, in the comments, the method used!

References
1.[Link]
tml#
2.[Link]
html#adc-calibration
3.[Link]
nce_manual_en.pdf

66
Originally published on Embarcados, on 03/18/2019:linkfor the original article,
under the LicenseCreative Commons Attribution-ShareAlike 4.0 International.

67
ESP32 - Security and protection of
flash
Author:José Maia

In this article, we will address, in an easy and quick manner, a very important subject for
who intends to sell products with the ESP32, the security of their hardware with
the code present in the flash memory, in order to prevent cloning, theft, etc.

68
We will use ESP-IDF v4.0-dev-76-g96aa08a0f-dirty (Ubuntu) for all articles
of this series and it will not cover how to use the IDF, being the reader's duty
understand how it works. More about the IDF:[Link]

Figure 1 - Protecting the ESP32.

Explaining in simple terms


All code (firmware) transferred to the ESP32 is saved, in most versions, in the
external flash memory, which further decreases security, since someone can
simply remove it for reading on an external hardware and clone it, in seconds,
our code that may have taken years to develop. Even if the flash is
embedded, as in the "PICO" version, it is possible to export all content from the flash with

69
just a command in the terminal. So, if all content can be easily obtained,
we must protect ourselves and that's what the ESP32 flash encryption provides us.

Flash encryption
Attention

● We will not address all functions and features of flash encryption, being
it is necessary for you to study the official documentation VERY WELL, in order to avoid
any headache that may occur as the IDF updates. We are not
responsible for any misuse on your part.
● The flash encryption limits how and/or how many times it is possible to upload
new codes. If done incorrectly, you may lose your ESP32 and it will not be
but possible to re-record it.
● We will address, for didactic reasons, only encryption with a single key.
pre-generated, thus, we can reprogram the ESP32 without any restrictions on
quantity.
● In environments where the highest security available is necessary, you should not
use a pre-generated key, allowing the ESP32 itself to generate its own,
individual for each hardware. In addition to also enabling Secure boot which does not
we will address here.

The flash encryption (AES-256) is a feature present in the ESP32 that encrypts
the content present in the flash. When enabled, physical readings without the key are not
sufficient to recover the content. Thus, we protect ourselves from those who try
export it for cloning etc. The key is stored in a eFuse block, which can be
protected against reading and writing (default) and, knowing the key, we can rewrite

70
codes without quantity limitation, unlike the case where the ESP32 generates its
own key, where we are limited to up to 3 physical uploads.

Let's observe some relevant items about cryptography:

● In a plaintext upload, the original (raw) binary is sent to the microcontroller.


● In an encrypted upload, the binary is sent to the microcontroller already
encrypted by the IDF.
● The eFuse 'FLASH_CRYPT_CNT' (7-bit) is responsible for permitting uploads.
plaintext, by counting physical uploads (up to 3x) and by controlling the
bootloader to encrypt the content of the flash. It can be protected against R/W.
After 3 plaintext uploads, this eFuse will reach its maximum and will only accept
encrypted uploads.
○ When it is an even number, the bootloader will encrypt all content of the
flash, logo, it is necessary to upload plaintext.
○ When it is an odd number, the bootloader will not encrypt the content
from flash, logo, encrypted upload is required.
● If the key is not known (pre-generated), we have a maximum of 3 physical uploads.
available (plaintext), which also allows us to disable encryption. If the
“FLASH_CRYPT_CNT” for protegido enquanto ímpar, não será possível novos
uploads plaintext.
● The binaries "Bootloader", "Partition table", "OTA DATA", all "APP (your code)"
and the partitions marked with the 'encrypted' flag in the partition table will be
encrypted. Partitions that are not marked with "encrypted" will not be
encrypted and can be read externally, be careful when using APIs
for access to flash as NVS and SPIFFS.
● If the 'FLASH_CRYPT_CNT' is not properly protected and/or there is still
any attempt to upload plaintext, attackers can insert malicious code
and read the content in an unencrypted form by the ESP32 itself without knowledge

71
of the key. Because of this, it is common to protect it from writing, in order to prevent
uploads plaintext.

Knowing the basic details (there are dozens of extra details in the official documentation that
you should read before performing the tests below), let's test the flash encryption and see
it really works! Remember that we will use the IDF on Ubuntu and almost everyone
commands may change according to your computer, project, addresses, and many
other things. The commands used here may not work for you, so you will need to
alter them according to your design, file paths, etc. This article is just
a demonstration and should be taken as a basis, not followed to the letter. The scripts
used are in the IDF folder, "esp-idf/components/esptool_py/esptool/", take
pay close attention to the use of file and script paths, as you may be
trying to run the command in the wrong location. Also pay attention to the port used,
your ESP32 may be on a different port than ours.

First, let's test a simple code just to check what it was about.
cited above, about the reading (cloning) of the unprotected flash memory. You can
ignore this part.

voidapp_main()
{

while(1)
{
ESP_LOGI("ESP32","Embedded...");
vTaskDelay(pdMS_TO_TICKS(1000));
}
}

When we perform a standard upload to the board, the computer uses a python script.
([Link]) with the command 'make flash', which basically compiles and uploads

72
With the sent code, we will make a reading (summary) of the eFuses to
comparison after enabling encryption:

python [Link] --port /dev/ttyUSB0 summary

[Link] v2.6
Connecting........__
EFUSE_NAME Description = [Meaningful Value] [Readable/Writeable] (Hex Value)
----------------------------------------------------------------------------------------
Security fuses:
FLASH_CRYPT_CNT Flash encryption mode counter =0R/W (0x0)
FLASH_CRYPT_CONFIG Flash encryption config (key tweak bits) =0R/W (0x0)
CONSOLE_DEBUG_DISABLE Disable ROM BASIC interpreter fallback =1R/W (0x1)
ABS_DONE_0 secure boot enabled for bootloader =0R/W (0x0)
ABS_DONE_1 secure boot abstract1locked =0R/W (0x0)
JTAG_DISABLE Disable JTAG =0R/W (0x0)
DISABLE_DL_ENCRYPT Disable flash encryption in UART bootloader =0R/W (0x0)
DISABLE_DL_DECRYPT Disable flash decryption in UART bootloader =0R/W (0x0)
DISABLE_DL_CACHE Disable flash cache in UART bootloader =0R/W (0x0)
BLK1 Flash encryption key
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R/W
BLK2 Secure boot key
=00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00R/W
BLK3 Variable Block3
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R/W

Efuse fuses:
WR_DIS Efuse write disable mask =0R/W (0x0)
RD_DIS Efusereaddisablemask =0R/W (0x0)
CODING_SCHEME Efuse variable block length scheme =0R/W (0x0)
KEY_STATUS Usage of efuse block3(reserved) =0R/W (0x0)

Config fuses:
XPD_SDIO_FORCE Ignore MTDI pin (GPIO12) for VDD_SDIO on reset =0R/W (0x0)
XPD_SDIO_REG If XPD_SDIO_FORCE, enable VDD_SDIO register on reset = 0 R/W (0x0)
XPD_SDIO_TIEH If XPD_SDIO_FORCE & XPD_SDIO_REG, 1=3.3V0=1.8V = 0R/W (0x0)
SPI_PAD_CONFIG_CLK Override SD_CLK pad (GPIO6/SPICLK) =0R/W (0x0)
SPI_PAD_CONFIG_Q Override SD_DATA_0 pad (GPIO7/SPIQ) =0R/W (0x0)
SPI_PAD_CONFIG_D Override SD_DATA_1 pad (GPIO8/SPID) =0R/W (0x0)
SPI_PAD_CONFIG_HD Override SD_DATA_2 pad (GPIO9/SPIHD) =0R/W (0x0)
SPI_PAD_CONFIG_CS0 Override SD_CMD pad (GPIO11/SPICS0) =0R/W (0x0)
DISABLE_SDIO_HOST Disable SDIO host =0R/W (0x0)

Identity fuses:
MAC Factory MAC Address

73
= [Link](CRC84OK) R/W
CHIP_VER_REV1 Silicon Revision1 =1R/W (0x1)
CHIP_VERSION Reserved for future chip versions =2R/W (0x2)
CHIP_PACKAGE Chip package identifier =0R/W (0x0)

Calibration fuses:
BLK3_PART_RESERVE BLOCK3 partially served for ADC calibration data =0 R/W (0x0)
ADC_VREF Voltage reference calibration =1114R/W (0x2)

Flash voltage (VDD_SDIO) determined by GPIO12 on reset (High for 1.8V, Low/NC for 3.3V).

Knowing that this ESP32 is not protected, we can export the flash content and
use for cloning, reverse engineering, or whatever comes to mind! Let's see if we find the
word used in ESP_LOGI(), 'Embedded...', when reading the content of the memory:

python [Link] --port /dev/ttyUSB0 read_flash 0x0 4096000 [Link]

[Link] v2.6
Serialport /dev/ttyUSB0
Connecting....
Detecting chip type... ESP32
Chip is ESP32D0WDQ6 (revision1)
Features:WiFi, BT, Dual Core,240MHz, VRef calibration in efuse, Coding Scheme None
MAC: [Link]
Uploading stub...
Running stub...
Stubrunning...
4096000(100%)
4096000(100%)
Read 4096000 bytes at 0x0 in 367.1 seconds (89.3 kbit/s)...
Hard resetting via RTS pin...

Using the command 'hexdump' to read the generated file, we were able to find the word
used in the code without encryption:

74
Figure 2 - Memory of the ESP32 cloned before encryption.

Now that cloning has been demonstrated with just one command in the terminal, indicating
that your unprotected product is completely vulnerable in the hands of someone, let's go
to protect us by activating encryption.

Creating the key


python [Link] generate_flash_encryption_key [Link]

We will use the IDF script itself to create a key (256b), but you can use
any method or key you wish. The command will export the key in the file

75
"[Link]", which you should leave a copy inside your project's folder, making it something
similar to ours:

Figure 3 - Project folder with key.

Writing the pre-generated key to the eFuse

python [Link] --port /dev/ttyUSB0 burn_key flash_encryption [Link]

[Link] v2.6
Connecting........_____...
Write key in efuse block 1. The key block will be read and write protected (no further changes).
orreadback). This is an irreversible operation.
Type 'BURN' (all capitals) to continue.
BURN
Burned key data. New value: 56f71f29a66c01 20c5 ee6b55 79 36d790 73b3 f62d48a2
dc03b8 at dc cb1b31fe e5

76
Disabling read/write to key efuse block…

The command above wrote our key to the eFuse and automatically protected against
R/W, which prevents anyone from being able to read or modify it. Despite this command
write in the terminal the stored key, when trying to read the key directly from eFuse
(summary) as previously done, it is returned:

BLK1 Flash encryption key


= ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??
?? ?? -/-

Now with a known key in the eFuse, we have the possibility of unlimited uploads.
(encrypted), which is very interesting in the development phase.

Activating flash encryption


Now with the key recorded, just activate the flash encryption in the "menuconfig" in
Security features

77
Figure 4 - Activating flash encryption.

Attention, if you did not save the pre-generated key, when uploading new code with
with encryption enabled, the ESP32 itself will generate a key that neither you, nor us, nor the
Espressif may read, leaving you with 3 uploads (plaintext) and/or attempts to deactivate the
cryptography, be careful! OTA updates are unlimited even without knowledge
of the key.

After activating the encryption, we will re-upload the code used previously from
standard form, as used before (upload plaintext). In this first boot, the bootloader
It will encrypt all the memory content and restart; this process may take a while.
so wait a little. After the ESP32 restarts, indicating that the encryption has been activated,
let's do a new reading of the flash to see if we find the word "Embarcados..."
again.

78
Figure 5 - ESP32 memory cloned after encryption.

In addition to the word 'Embarcados...' not being found, no readable text was seen, which
Previously, it was easily seen (Strings used by the IDF itself). The same
address where we found the word previously, now, is nothing more than a text
corrupted for anyone trying to read without the key!

If we look at the summary of the eFuses again, we can see that the "FLASH_CRYPT_CNT"
it went from 0 to 1, indicating that it now only accepts encrypted uploads, therefore, if we use
during the standard upload (plaintext), the ESP will enter a boot loop with the following message:

make flash monitor -j4

Jun 8 2016 [Link]

rst:0x1(POWERON_RESET),boot:0x13(SPI_FAST_FLASH_BOOT)
flash reader, 1000

79
ets_main.c371
Jun 8 2016 [Link]

rst:0x10(RTCWDT_RTC_RESET),boot:0x13(SPI_FAST_FLASH_BOOT)
flashreader,1000
ets_main.c371
Jun 8 2016 [Link]

rst:0x10(RTCWDT_RTC_RESET),boot:0x13(SPI_FAST_FLASH_BOOT)
flashreaderr,1000
ets_main.c371
Jun 8 2016 [Link]

The 'FLASH_CRYPT_CNT' is not write-protected by default, so someone can still


you can disable encryption, upload (plaintext) and read your flash in a way
decrypted, therefore, we must protect this eFuse against writing WHILE it is
in an odd number or use Secure Boot.

Protecting the eFuse


Let's protect the eFuse "FLASH_CRYPT_CNT" against writes to make it impossible
any type of upload without knowledge of the key, this automatically allows for
your boards are protected from unauthorized uploads, forcing your hardware to
accept only codes that have been encrypted with the key. Despite this
protection works with the same purpose as Secure Boot (prevent unauthorized uploads.
allowed), there are some cases where keeping Secure boot enabled may be better,
However, in most cases, by protecting the eFuse we no longer need Secure Boot.
(research better about this if it will be used in aggressive environments where safety must
prevail).

80
Before protecting the writing, we must ensure that it is in some odd number.
through the summary, which returned to us 'FLASH_CRYPT_CNT Flash encryption mode
counter = 1 R/W (0x1)

python [Link] --port /dev/ttyUSB0 write_protect_efuse FLASH_CRYPT_CNT

[Link] v2.6
Connecting........_
Permanently write-disabling efuse FLASH_CRYPT_CNT. This is an irreversible operation.
TYPE 'BURN' (ALL CAPITALS) TO CONTINUE.
BURN

From now on, it is impossible to disable encryption or send codes that do not
be encrypted by the key present in the ESP32.

Okay, if the standard upload no longer works, what will we do? We encrypt before
send! Although AES-256 is used, Espressif employs different methods of
functioning (details in the official documentation), so we need to encrypt by
IDF own script

Encrypting the binaries


The upload must now be done 'manually', requiring encryption and sending the
encrypted binaries. This part depends a lot on project to project,
especially in file paths and memory address, pay close attention.

5.1 Create a folder 'enc' within your project, it will store the encrypted binaries
by the script.

81
5.2 With the terminal open in your project folder, use the command “make all” to
discover what and where the files are stored.

make all -j4

Toolchain path: /home/ze/esp/xtensa-esp32-elf/bin/xtensa-esp32-elf-gcc


Toolchain version: crosstool-ng-1.22.0-80-g6c4433a
Compiler version: 5.2.0
Project is not inside a git repository, will not use 'git describe' to determine PROJECT_VER.
App"esp32"version:1
Python requirements from /home/ze/esp/esp-idf/[Link] are satisfied.

To flash all build output, run 'make flash' or:


python /home/ze/esp/esp-idf/components/esptool_py/esptool/[Link] --chip esp32 --port /dev/ttyUSB0 --baud 921600
--before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 80m --flash_size detect 0x363000
/home/ze/esp/esp32/build/ota_data_initial.bin0x1000/home/ze/esp/esp32/build/bootloader/bootloader.bin0x10000
/home/ze/esp/esp32/build/[Link] 0x8000 /home/ze/esp/esp32/build/[Link]

We can see that in this project of ours, where we use OTA and a partition table
4 binaries are uploaded to their respective addresses.

ota_data_initial.bin: 0x363000.

[Link]: 0x1000.

[Link] (the code itself): 0x10000.

[Link]: 0x8000.

We will encrypt them individually and afterwards, upload them. Do not


forget that the file paths need to be changed for your project.

82
5.3 With the terminal open in the scripts folder, use the commands below and do not forget.
to pay close attention to memory addresses and the path of the binaries.

python [Link] encrypt_flash_data --keyfile [Link] --address 0x1000 -o /home/ze/esp/esp32/enc/[Link]


/home/ze/esp/esp32/build/bootloader/[Link]

python [Link] encrypt_flash_data --keyfile [Link] --address 0x8000 -o /home/ze/esp/esp32/enc/[Link]


/home/ze/esp/esp32/build/[Link]

python [Link] encrypt_flash_data --keyfile [Link] --address 0x10000 -o /home/ze/esp/esp32/enc/[Link]


/home/ze/esp/esp32/build/[Link]

python [Link] encrypt_flash_data --keyfile [Link] --address 0x363000 -o


/home/ze/esp/esp32/enc/ota_data_initial.bin /home/ze/esp/esp32/build/ota_data_initial.bin

5.4 Upload the encrypted binaries using the command:

python [Link] --chip esp32 --port /dev/ttyUSB0 --baud 921600 write_flash --flash_mode dio
--flash_freq80m --flash_size detect0x1000/home/ze/esp/esp32/enc/bootloader.bin0x8000
/home/ze/esp/esp32/enc/partitions.bin0x10000enc/esp32.bin0x363000
/home/ze/esp/esp32/enc/ota_data_initial.bin

After the encrypted upload, the ESP32 will start normally as if nothing had happened.
happened. This method, although manual, can be automated by a script.
(bash), just place them in a file and run it in the terminal.

Now that the protection of the ESP32 is activated, we can be more relaxed about it.
about someone cloning our firmware, since it will not be possible without the key recorded. You
you must read all official documentation and it may also be interesting to use Secure
boot without encryption from the flash, analyze your project and get to work!

83
References
1.[Link]

Originally published on Embarcados, on 09/26/2019:linkfor the original article,


under the LicenseCreative Commons Attribution-ShareAlike 4.0 International.

84
Controlling ESP32 via WiFi
with address validation
MAC
Author:Roger Moschiel

The macaddress is a unique physical address in hexadecimal format with 6 bytes, which is
attributed to all hardware made for network communication, and as the identification is

85
unique, it can be used to control access in a local network, where by
For example, routers allow blocking specific MAC addresses.

In this tutorial we will apply this functionality on the ESP32, using the Arduino IDE to
set it up in AP mode, and validate the access of connected devices through the
MAC address. Only after validation is completed will the user be allowed to use the
system.

It is important to inform that this tutorial is of a didactic nature, since, despite the MAC
be unique for each device, it is possible to change it using specific techniques, which
does not guarantee effective security against unauthorized users. The complete code
used in this tutorial is available in my account ofGithub.

Installing libraries

There is a plugin for the Arduino IDE to support ESP32 boards, to


install it, check thetutorialfor Gabriel Almeida's Windows. For others
operating systems, follow the instructions in the accountGithubof the suppliers of
complement.

We will also use the ESP_ClientMacaddress library available on myGithub.

86
Setting up WiFi in AP mode (Access
Point)

An Access Point is a Wireless Local Area Network (WLAN), through which we can
connect a device (client) to ESP (host) via WiFi.

First, we import the following library to configure the WiFi connection on the ESP.

including <WiFi.h>

Choose the SSID and Password you want, this will be the way to identify the network in which the
the user must connect:

const char* ssid ="meu_ssid";


const char* senha ="minha_senha";

WiFi Server configured on port 80:

WiFiServer server(80);

Inside the setup(), to set the ESP in AP mode we use this command:

[Link](ssid, password);

87
And to start the server:

[Link]();

At this point, your code should look like this:

#include<WiFi.h> //wifi connection functionalities, such as AP and WebServer


Access point credentials
const char*ssid ="meu_ssid";
const char*senha ="minha_senha";
WiFiServer server(80); //Standard port 80
void setup() {//Initialize serial
[Link](115200);
[Link]();//Configures ESP in mode
[Link]("Configuring access point '%s'n", ssid);
[Link](ssid, password);
[Link]();
Configuration completed

voidloop() { }

Agora grave o código na ESP, e então use um celular pra verificar se a rede WiFi aparece
available, but don't connect yet.

88
Fig 1 – Available Networks

Sending commands through the


HTTP headers of the client

Edit the loop() according to the following code.

voidloop() {

Check if there is any client on the network.

89
WiFiClient client = [Link]();
In case of a positive, print 'New Client' on the monitor
if(client){
New Client
While connected client, checks if there are bytes to be read
//e concatenates the received bytes in the header String;
while([Link]()){
if([Link]()){
header += (char)[Link]();
//If a new blank line is received, data reading has ended
if([Link]("nrn")){
[Link](header);//prints received http headers
//we start the http response with the OK code (200),
the type of content to be sent and the type of connection.
[Link]("HTTP/1.1 200 OK");
[Link]("Content-Type:text/html");
[Link]("Connection: close");
[Link]();
//INSERT YOUR APPLICATION HERE

break;//exit do while loop


}
}
}
cabecalho ="";//ao encerrar conexão, limpa variável cabecalho
[Link](); [Link]();
Client disconnected.
}
}

Thus, during the execution of loop(), the ESP will always be checking if something has been done.
connection. Once a request is received from the client, we will save the received data
in the header string, and with the command [Link]() we respond with the status
OK (code 200) to signal to the client that we have successfully received the data. More

90
ahead, the field commenting "INSERT YOUR APPLICATION HERE" will be the place where
We will program the control functionalities.

Save the code, and with a mobile phone connect to the WiFi network you named, and then in
browser type the IP address [Link] of our host (ESP), by doing this, on the monitor
In the Arduino IDE, we will have the output with the received HTTP headers with the
device information.

Fig 2 – Response on the Serial Monitor of the Arduino IDE

Try typing the IP of the ESP followed by any text in your browser,
example type [Link]/test, and you will see that the content of the entered url is also
captured, soon, through the url we can determine commands to be sent to the
ESP.

91
Fig 3 – Command received through HTTP headers

Let's use this strategy to send commands to ESP through the browser. In this
We will send commands to toggle the state of the embedded LED on the module.
ESP32, which is connected to pin 2 of the board.

At the beginning of the setup(), add a command to set up the pin that controls the LED.
as output.

void setup() {
Configure the pin connected to the LED as output
pinMode(2, OUTPUT);
.......
}

Inside the loop(), below the comment 'INSERT YOUR APPLICATION HERE', we will
projetar o sistema para fazer a leitura dos comandos LED_ON e LED_OFF, assim
being able to control the LED state through the browser, in the following way:

...
//INSERT YOUR APPLICATION HERE
if([Link]("GET /LED_ON")>=0){
digitalWrite(2, true);//Turns on the LED
}else if([Link]("GET /LED_OFF")>=0){
digitalWrite(2, false);//Turn off the LED
}
...

Save the code, connect to the ESP WiFi network, and in the browser type
[Link]/LED_ON to turn on the LED, or [Link]/LED_OFF to turn off the LED.

92
Controlling ESP32 through a
web page with HTML
Now we have to create our webpage, for that we created the function run_html(), which
will receive the client itself as a parameter.

void run_html(WiFiClient client) {


}

So we start the html code with the following tags used to start a document
html.

<!DOCTYPE html><html>

The following CSS commands in the <head> of our page align the content accordingly.
with the screen size of the device.

<head><style media='screen' type='text/css'>


html{display:inline-block;margin:10px auto;text-align:center;}
</style></head>

Next, we create the body of our page, which is written between the tags
<body></body>, and in the body we insert a header with the title 'LED ACTIVATION'
using the tags <h1></h1>.

LED ACTIVATION

93
Still in the body of the page, we inserted a button between the tags <button></button> with the
título ‘ON’ e comprimento de 200px e tamanho da fonte de 80px.

<button style='width:200px;font-size:80px'>ON</button>

Previously, to turn on the LED, we had to type the IP address in the browser.
but the LED_ON command, this time we will assign this function to the button we just
to create.

To do this, we place the button code line between the <a></a> tags with the link of
redirection, and we use the <p> tag to position the buttons vertically.

<p><a href='/LED_ON'>
<button style='width:200px;font-size:80px'>ON</button>
</a></p>

In a similar way, we create another button to turn off the LED.

<p><a href='/LED_OFF'>
<button style='width:200px;font-size:80px'>OFF</button>
</a></p>

Finally, we close the html document with the </html> tag.

Dentro da função run_html(), vamos armazenar o conteúdo HTML na String


html_content, and use the [Link]() command in order to have the ESP send the html code to the
client, this is how the function looks:

voidrun_html(WiFiClientclient){}

94
Stringhtml_content = \
<!DOCTYPE html><html>
<head><style media='screen' type='text/css'>
html{display:inline-block;margin:10px auto;text-align:center;}
</style></head>
<body>
<h1 style='font-size:40px'>LED Activation</h1>
<p><a href='/LED_ON'>
<button style='width:200px;font-size:80px'>ON</button>
</a></p>
<p><a href='/LED_OFF'>
<button style='width:200px;font-size:80px'>OFF</button>
</a></p>
</body>
</html>

[Link](html_content);
}

Now that our webpage is ready, we will return to loop(), and in the field "INSERT
HERE YOUR APPLICATION" we added a call to the run_html() function.

//INSERT YOUR HTML APPLICATION HERE


run_html(client);
if([Link]("GET /LED_ON")>=0) {
digitalWrite(2, true);//Turns on the LED
}else if([Link]("GET /LED_OFF")>=0){
digitalWrite(2, false);//Turns off the LED
}
...

Record the code on the ESP and connect to the WiFi network with your cell phone or computer, and in
browser type the IP [Link] to load the html page. Now, instead of typing

95
the LED_ON or LED_OFF commands in your browser to activate the LED, you will be able to
do this simply by clicking the buttons on the page, and the http request will be sent
from the client (your browser) to the host (ESP).

Fig 4 - Web page for LED control

Validating access by WiFi MAC address

Import the ESP_ClientMacaddress library.

#include<ESP_ClientMacaddress.h>

96
Access the WiFi settings of your phone and look for the MAC address (macaddress),
nolinkdo you have access to instructions on how to view the mac address for Android, iOS,
Windows Phone and PC.

Fig 5 - MAC address of an Android phone

Back to the code, create an array to store the bytes of the MAC address.
any devices you wish to authorize access.

In this example, I will use 3 fictitious MAC addresses, where it should also be defined
amount of devices.

#define NUM_DEVICES 3

uint8_t macList[NUM_DEVICES][6] = {

97
{0xA7,0x16,0xD0,0xA6,0x45,0x3B}
{
The text provided appears to be a series of hexadecimal values, which do not translate directly into a meaningful sentence in English.
};

Create the boolean variable mac_known.

known_boolmac;

Now we instantiate the ClientMacaddress class, passing the list as a parameter.


MAC addresses and the number of authorized devices.

ClientMacaddress clientMac(macList, NUM_DISPOSITIVOS);

Change the code of the field "INSERT YOUR APPLICATION HERE" as demonstrated below:

...

//INSERT YOUR HTML APPLICATION HERE

The variable 'm' points to the MAC address of the client.

uint8_t *m = [Link](client);
Macaddress:%.2X:%.2X:%.2X:%.2X:%.2X:%.2Xn
m[0],m[1],m[2],m[3],m[4],m[5]);

determines if the client's MAC address is known


mac_conhecido = [Link](m);

run_html(client);//send HTML content to the client

If the client has a known MAC, grant access to control the LED
if(known_mac){

98
mac ok
if([Link]("GET /LED_ON")>=0){
digitalWrite(2, true);//Turns on the LED
}else if([Link]("GET /LED_OFF")>=0){
digitalWrite(2, false);//Turns off the LED
}
}else{
unauthorized mac
}
...

With this change, the getAddr() command stores the MAC address in the variable m.
client, then the command isKnown() sets the variable mac_conhecido to true if the
MAC for known, or false if unknown, thus preventing that
unauthorized devices have access to the control of the LED.

And to finish, we modified the run_html() function so that the web page only grants access
to the ON and OFF buttons if the client has a known MAC address, otherwise
we load the alert message "UNAUTHORIZED DEVICE".

voidrun_html(WiFiClientclient){
Stringhtml_content = \
<!DOCTYPE html><html>
<head><style media='screen' type='text/css'>
html{display:inline-block;margin:10px auto;text-align:center;}
</style></head>
<body>
<h1 style='font-size:40px'>LED Activation</h1>
if(known_mac){
html_content += \
<p><a href='/LED_ON'>"
"<button style='width:200px;font-size:80px'>ON</button>"\
</a></p>
<p><a href='/LED_OFF'>
"<buttonstyle='width:200px;font-size:80px'>OFF</button>"\

99
</a></p>
}
html_content += \
<p style='color:red;font-size:40px'>UNAUTHORIZED DEVICE</p>
}
html_content += \
</body>
</html>

[Link](html_content);
}

Record the code, and this time, use any device that you do NOT have.
registered the MAC address, connect to the ESP WiFi network and type the IP [Link] in
your browser. Thus the user will be notified that the device is not authorized to
access the system.

Fig 6 - Web page with alert message

100
We have finished!
In this tutorial, you learned how to build an Access Point with an ESP32 module.
using the ESP_ClientMacaddress library to validate the MAC Address
of the connected device.

We saw a simple example of how to control an LED using an interface


web page, now you can work based on this example replacing the LED for
activate a relay or any other device, and also customize the web page.

Originally published on Embarcados, on 03/13/2019:linkfor the original article,


under the LicenseCreative Commons Attribution-ShareAlike 4.0 International.

101
Espressif announces support for
graphic libraries on ESP32
Author:Muriel Costa

Espressif announced on 01/04/2019 in itssitethat the ESP32 will have official support
for the LittlevGL and uGFX graphic libraries.

The forecast is that working with graphical user interfaces on the ESP32 will become easier and
uncomplicated, since the libraries are now officially available. With this
Espressif's strategy seeks not only to reduce product development time, but
also serve an even larger market share with the audience that seeks resources
graphics with the user, mainly from IoT, their main target.

102
LittlevGL

ALittlevGLit is a free and open-source graphics library, providing everything that is


necessary to create a GUI (Graphical User Interface) embedded with elements
easy-to-use graphics, beautiful visual effects, and low memory consumption. The GUI
customized can be created with easy-to-use blocks, such as buttons, graphs, images,
lists, sliders, switches, or a keyboard. The library is free and
totally open source.

Figure 1: Application using ESP32 and LittlevGL graphics library.

Main features

● Powerful building blocks / Widgets: buttons, graphs, lists, controls


sliders, images, etc.
● Advanced graphical effects: animations, anti-aliasing, opacity, smooth scrolling, etc.
● Supports multiple input devices: touchpad, mouse, keyboard, encoder, etc.
● Multilingual support: UTF-8 encoding.
● Fully customizable graphic elements.

103
● Support for all types of microcontrollers and displays (regardless of
hardware).
● Highly scalable: can operate with minimal memory (80 KB Flash, 10 KB RAM).
● Support for operating system, external memory, and GPU (optional).
● Single buffer operation with the same advanced graphical effects.
● Written in C for maximum compatibility (also compatible with C++).
● Multi-platform simulator: supports GUI design on PC without hardware
embarked.

To learn more about the features of LittlevGL in Espressif modules visitthis


repository on GitHub.

µGFX
TheµGFXit was designed to be the smallest, fastest, and most advanced library
incorporated for screens and touch displays, providing everything that is necessary for
build an embedded GUI with all the features. One of the main advantages of
µGFX is lightweight because all unused features are disabled and not
are linked to the finalized binary. Furthermore, µGFX is modular, portable, and has its
complete source code available to all users, being paid only for use
commercial.

Main features

● Small and light.


● Totally customizable and extensible.
● Highly portable.
● Supports monochrome monitors, in shades of gray and color.
● Supports hardware acceleration.

104
● More than 50 drivers ready for use.
● Written in C, but can also be used with C++.
● Free for non-commercial use.
● Complete source code available.
● Works on low RAM systems; frame buffer is not required for the
majority of monitors.
● Fully multi-threaded reentrancy; Drawings on the screen can occur from
from any thread, at any time!

To learn more about the features of µGFX in Espressif modules visitthis


repository on GitHub.

Demo applications and use cases


The results of the applications can meet various scenarios, see below some
implementations.

Audio player

105
Figure 2: Application of the audio player on the ESP32.

Cliquehereto view the application video on the Espressif website.

Air conditioning thermostat

106
Figura 3: Aplicação do termostato no ESP32.

Cliquehereto watch the application video on the Espressif website.

Control panel for coffee machines

107
Figure 4: Application of the panel for coffee machines on the ESP32.

Clickhereto see the application video on the Espressif website.

Reference
1.ESP32 modules now support LittlevGL andµGFX

Publicado originalmente no Embarcados, no dia 01/02/2019: linkfor the original article,


under the LicenseCreative Commons Attribution-ShareAlike 4.0 International.

108
NORVI IIOT - ESP32 for
industrial projects
Author:Fábio Souza

The ESP32 has been used in various applications, including industrial ones. Taking advantage
the connectivity resources and processing power, combined with low cost,
It allows the development of various types of controllers and sensors.

As part of this trend, the company Norvi launched the NORVII IIOT industrial.
controller, a controller based on the ESP32-WROOM-32 module, which comes with
various resources, including an OLED or TFT screen of 0.96" to 1.44", mounted on a
standard industrial box for mounting on rails.

109
There are 5 product options in the three available series (AE01, AE02, and AE03):

110
Summary of resources from NORVII IIOT
industrial controller
● Wireless module - ESP32-WROOM32 with dual-core ESP32 processor at 160
MHz, 520 Kbytes SRAM, 4 Mbit Flash, WiFi 802.11 b/g/n and Bluetooth 4.2
● Storage - optional microSD card slot
● Display - 0.96" embedded OLED. 0.96" TFT screen or 1.44" TFT screen
● Communication - RS-485, WiFi, Bluetooth, LoRa or NB-IoT module (optional)
● I/Os:
○ 8x Digital Inputs
○ 2 transistor outputs of up to 24V
○ Just series AE01 - 6x relay outputs
○ Only series AE02 - 6x 16-bit analog inputs with 4 mA current -
20mA (AE02-I) / 0 - 10V (AE02-V)
● Power LED, RUN LED, 8x LEDs for I0 …… I7, 6x LEDs R0 …… R5, 2x LEDs for
T0… .T1
● MAX31856 temperature sensor (optional)
● DS3231 RTC optional with battery backup
● Power supply - nominal input of 24 Vdc
● Dimensões - 90,50 x 56,60 x 60,60 mm

111
Typical application of NORVI IIOT

The PLC can be programmed with the Arduino IDE and the company - Iconic Devices - provides
Arduino libraries and example programs for inputs, outputs, RTC, sensor of
temperature and I2C, etc.

Check out the product presentation video:

112
The company also provides expansion modules for the NORVII IIOT industrial.
controller for LoRa and NB-IoT applications

For more details, visit the product page:NORVI IIOT - ESP32 for industrial
projects

Originally published on Embarcados, on 12/18/2019:linkfor the original article,


under the LicenseCreative Commons Attribution-ShareAlike 4.0 International.

113
Maixduino: a super board with
RISC-V AI and ESP32
Author:Fábio Souza

The RISC V ISA is becoming popular and some applications are being created with it.
Recently, Kendryte K210 was released, a dual-core 64-bit RISC-V processor.
with neural network and audio accelerator, enabling artificial intelligence applications in

114
border, such as object recognition and speech processing. The K120 processor
was integrated into the moduleSipeed MAIX-I:

Now, based on the same module, the Maixduino board has been launched, a board with form
Arduino UNO factor, which also includes an ESP32.

115
The Maixduino can be programmed using the maixPy IDE (MicroPython), Arduino IDE,
OpenMV IDE and PlatformIO IDE. It has support for Tiny-Yolo, Mobilenet, and TensorFlow.
Light for deep learning. It also supports QVGA image identification.
60fps or VGA @ 30fps.

The board still features some interesting resources, such as a microphone, camera connector,
slot for SD card, audio output, connector for LCD, and various GPIOs:

116
Focusing on rapid prototyping of solutions with artificial intelligence and
image and sound recognition at the edge, some typical applications include wing
smart (robot vacuums or smart speakers), medical devices,
Industry 4.0 (smart separation or monitoring of electrical equipment), well
such as agriculture and education.

The Maixduino development board is currently sold aspart of a kitwhat is included


a OV2640 camera module and a 2.4-inch TFT display, costing $23.90.

117
The following video showcases an application made with Sipeed MAIX-I:

What do you think of this sign? Leave your comment below.

Originally published on Embarcados, on 05/24/2019:linkfor the original article,


under the licenseCreative Commons Attribution-ShareAlike 4.0 International.

118
Final Considerations

We have reached the end of our ebook.

If you have any questions, do not leave them unanswered. You can get in touch.
with the author through the comments section of the article, or then participate in our
community, interacting with other professionals in the field:

Embedded Community on Facebook

Embedded Community on Telegram

Embedded Community on LinkedIn

In case you have encountered any issues with the material or have any

suggestion, please contact us. Your opinion is very important

for us:contato@[Link]

119
Follow Embarcados on Social Media

[Link]

[Link]

[Link]

[Link]

[Link]

120

You might also like