ebook-esp32-part-1
ebook-esp32-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 continue with the mission of publishing new texts daily on the site.
A big hug.
Embedded Team.
1
Summary
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
● 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.
5
Setting up the environment of
development of the ESP32 in
Windows
Author:Gabriel Almeida
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.
In the case of Windows, the installation procedure is divided into the following steps:
7
Python and Git can be downloaded from the following sites, respectively:
● [Link]
● [Link]
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
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:
Once the environment is set up, let's go to the application. The process of configuring
the application can be divided into 4 stages:
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
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"
cd ~/esp
cp -r $IDF_PATH/examples/get-started/hello_world
cd /esp/hello_world
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:
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]
15
Setting up the environment
Eclipse for ESP32
Author:Muriel Costa
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.
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.
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.
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.
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
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.
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.
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
$ make menuconfig
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.
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.
37
Figure 24: Modified Python interpreter call name.
References
1.[Link]
2.[Link]
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.
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:
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
41
Understanding the functions of the pins of
strapping
Let's understand what exactly each strapping pin does, following the table of
Fig.01:
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.
See the schematic below, we defined the I2C bus on GPIO_12 and GPIO_13:
43
Figure 4 - I2C Bus
● 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.
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:
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.
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.
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.
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.
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;
51
Figure 2 - Readings with different Vref.
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.
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.
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.
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.
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.
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.
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.
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>
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
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.
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!).
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]
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.
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:
[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:
[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.
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:
[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:
Now with a known key in the eFuse, we have the possibility of unlimited uploads.
(encrypted), which is very interesting in the development phase.
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:
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]
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)
[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
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.
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]: 0x8000.
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] --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]
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
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:
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]();
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
voidloop() {
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
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.
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.
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.
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>
<p><a href='/LED_OFF'>
<button style='width:200px;font-size:80px'>OFF</button>
</a></p>
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.
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).
#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.
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.
};
known_boolmac;
Change the code of the field "INSERT YOUR APPLICATION HERE" as demonstrated below:
...
uint8_t *m = [Link](client);
Macaddress:%.2X:%.2X:%.2X:%.2X:%.2X:%.2Xn
m[0],m[1],m[2],m[3],m[4],m[5]);
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.
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.
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
Main features
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.
µ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
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!
Audio player
105
Figure 2: Application of the audio player on the ESP32.
106
Figura 3: Aplicação do termostato no ESP32.
107
Figure 4: Application of the panel for coffee machines on the ESP32.
Reference
1.ESP32 modules now support LittlevGL andµGFX
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.
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
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.
117
The following video showcases an application made with Sipeed MAIX-I:
118
Final Considerations
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:
In case you have encountered any issues with the material or have any
for us:contato@[Link]
119
Follow Embarcados on Social Media
[Link]
[Link]
[Link]
[Link]
[Link]
120