This is a project with the ESP32 chip onboard the ESP32-DevKitC and a temperature and pressure sensor BMP180. It uses the ESP-IDF framework.
- Connect the
BMP180
to theESP32-DevKitC
. The default pins for I2C areGPIO 19
for SDA andGPIO 18
for SCL. This is set inmain.c
by callingpl_i2c_init(GPIO_NUM_19, GPIO_NUM_18, 100000);
- The ESP32 needs to connect to an existing WiFi network. See the section Project Configuration for the steps to enter the ssid and the password.
- Communicate with the ESP32 via UDP. Both sending and receiving are
done over the same port. The port and the timer periods for heartbeat
and measurements are set in
main.c
.#define UDP_PORT 50000 #define MEASUREMENT_RATE 600 #define HEARTBEAT_RATE 300
- The UDP communication consists of JSON objects that are send as
strings. The following listing shows all the current options.
The numerical values for the interval variables are in seconds.
{"type":"get", "quantity":"temperature"} {"type":"get", "quantity":"pressure"} {"type":"get", "quantity":["temperature", "pressure"]} {"type":"set", "name":"heartbeat", "value":"on"} {"type":"set", "name":"heartbeat", "value":"off"} {"type":"set", "name":"heartbeat_interval", "value": 30} {"type":"set", "name":"measurement_interval", "value": 5}
- The return objects have the following syntax.
Response to aget
request which has only a single element in the list ofquantity
.Response from a periodic{ "type":"response", "time":"2021-05-04 20:11:20 CET", "quantity": [{ "name":"temperature", "value": 21.5, "unit": "celsius" }] }
measurement
which holds a list of measured quantities inquantity
.For debug purposes the ESP32 also sends objects with type{ "type":"measurement", "time":"2021-10-18 14:41:29 CET", "quantity":[ { "name":"temperature", "value": 21.6, "unit":"celsius" }, { "name":"pressure", "value": 1019.310, "unit":"hPa" }] }
heartbeat
which do not contain any more information than thetype
and thetime
.{ "type":"heartbeat", "time":"2021-10-18 14:42:53 CET" }
- The UDP traffic is encrypted
AES-256-CBC
mode. The 32 byte key is set withmenuconfig
. The buffer lengthBUFFER_LENGTH
inal_crypto
determines the length of the outgoing message. The incoming messages can be as large as theBUFFER_LENGTH + 16
for they contain the initialization vector as the first 16 bytes.
The framework used in this project is the ESP-IDF by espressif that can be
found on GitHub and has an extensive documentation.
=> https://github.com/espressif/esp-idf
=> https://docs.espressif.com/projects/esp-idf/en/v4.2/esp32/get-started/index.html
This project uses version 4.2 of the ESP-IDF.
git clone --recursive --branch v4.2 https://github.com/espressif/esp-idf.git
Make sure to have the packages
python3-virtualenv
installed if you have an errorNo module pip
.
The setup needs the name python
so set the alternatives.
sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 10 && alias pip=pip3
Then install the toolchain for the local user inside the esp/esp-idf
directory by executing
./install.sh
After the installation you need to source esp/esp-idf/export.sh
. Create an
alias in .bashrc
.
alias get-idf='. $HOME/esp/esp-idf/export.sh'
For the gdb debugger to work you have to install the package
libpython2.7-dev
.
You can configure the framework for the project in an interactive terminal.
Then build
, flash
and monitor
the project. The port
for flashing is
/dev/ttyUSB0
on Ubuntu.
idf.py set-target esp32
idf.py menuconfig
idf.py build
idf.py flash -p <port>
idf.py monitor -p <port>
idf.py flash monitor -p <port>
idf.py size-components
The WiFi configuration of the
menuconfig
is located under
Component config ---> Wifi Connect Config ---> WiFi SSID /WiFi Password
.
The fast scan method should work fine.
Further documentation for monitor
.
=> https://docs.espressif.com/projects/esp-idf/en/v4.2/esp32/api-guides/tools/idf-monitor.html
Notice when writing components:
The following header files are part ofesp_common
component and do not need to be added to required lists inCMakeLists.txt
of components.
esp_err.h
The WiFi bundle uses the LwIP stack with esp_netif
and BSD Sockets
for UDP/TCP communication. Time synchronization is done via sntp
.
=> https://docs.espressif.com/projects/esp-idf/en/v4.2/esp32/api-guides/wifi.html
=> https://docs.espressif.com/projects/esp-idf/en/v4.2/esp32/api-reference/network/esp_netif.html
=> https://docs.espressif.com/projects/esp-idf/en/v4.2/esp32/api-guides/lwip.html
=> https://pubs.opengroup.org/onlinepubs/007908799/xns/socket.html
=> https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/system_time.html?highlight=system%20time
Get started with the ESP32-DevKitC V4 board with has the ESP-WROOM-32
chip. The I2C Bus works on 3.3 V
.
=> https://docs.espressif.com/projects/esp-idf/en/v4.2/esp32/hw-reference/modules-and-boards.html#esp32-devkitc-v4
=> https://docs.espressif.com/projects/esp-idf/en/v4.2/esp32/hw-reference/modules-and-boards.html#esp-modules-and-boards-esp32-wroom-32
For debugging use the ESP-Prog board which has JTAG debugging capabilities. The debugging chip uses two ports:
/dev/ttyUSB0
is for the JTAG interface and/dev/ttyUSB1
for the flashing.
To connect the correct pins see the third link.
=> https://docs.espressif.com/projects/esp-idf/en/v4.2/esp32/api-guides/jtag-debugging/index.html
=> https://github.com/espressif/esp-dev-kits/blob/master/esp-prog/docs/ESP-Prog_guide_en.md
=> https://docs.espressif.com/projects/esp-idf/en/v4.2/esp32/api-guides/jtag-debugging/configure-other-jtag.html
=> https://docs.platformio.org/en/latest/faq.html#faq-udev-rules
Make sure to apply the udev
rule to avoid permission issues and then start
the openocd
service. Note this has to run when starting the gdb
.
openocd -f interface/ftdi/esp32_devkitj_v1.cfg -f target/esp32.cfg
You can also flash the ESP32 via JTAG.
openocd -f interface/ftdi/esp32_devkitj_v1.cfg -f target/esp32.cfg -c "program_esp build/esp32-devkitc.bin 0x10000 verify exit"
Start the debugger
xtensa-esp32-elf-gdb -x gdbinit build/esp32-devkitc.elf
ESP-PROG | DevKit C |
---|---|
TDO | G15 |
TDI | G12 |
TCK | G13 |
TMS | G14 |
EN | EN |
TXD | TXD |
RXD | RXD |
VDD | 3V3 |
GND | GND |
IO0 | G0 |
=> https://github.com/espressif/esp-dev-kits/blob/master/esp-prog/docs/_static/program_pin.png
=> https://github.com/espressif/esp-dev-kits/blob/master/esp-prog/docs/_static/JTAG_pin.png
Temperature and air pressure sensor with an I2C interface.
- I2C address:
0x77
- I2C clock speed max:
3.4 MHz
See GitHub on debugging with the extension.
=> https://github.com/espressif/vscode-esp-idf-extension
=> https://github.com/espressif/vscode-esp-idf-extension/blob/master/docs/DEBUGGING.md
Useful settings.json
{
"idf.port": "/dev/ttyUSB1",
"idf.adapterTargetName": "esp32",
"idf.flashType": "UART",
"idf.openOcdConfigs": [
"interface/ftdi/esp32_devkitj_v1.cfg",
"target/esp32.cfg"
]
}
Useful launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "GDB",
"type": "cppdbg",
"request": "launch",
"MIMode": "gdb",
"miDebuggerPath": "${command:espIdf.getXtensaGdb}",
"program": "${workspaceFolder}/build/${command:espIdf.getProjectName}.elf",
"cwd": "${workspaceFolder}",
"environment": [
{
"name": "PATH",
"value": "${config:idf.customExtraPaths}"
}
],
"setupCommands": [
{ "text": "target remote :3333" },
{ "text": "set remote hardware-watchpoint-limit 2"},
{ "text": "mon reset halt" },
{ "text": "thb app_main" },
{ "text": "flushregs" }
],
"externalConsole": false,
"logging": {
"exceptions": true,
"moduleLoad": true,
"programOutput": true,
"engineLogging": false,
"trace": false,
"traceResponse": false
},
}
]
}