ESP32: Device Dashboard
Overview
This tutorial demonstrates how Mongoose Library can be used to implement a device dashboard on an ESP32. The full source code is at https://github.com/cesanta/mongoose/tree/master/examples/esp32/device-dashboard
This tutorial is a hardware example following on the device dashboard tutorial. You should read and follow that tutorial first.
Project structure
This example uses the ESP-IDF 4.x/5.x toolchain, and therefore the project structure follows a standard ESP-IDF CMake-based format:
main/
- a "main" component directory which includes application codemain/CMakeLists
- a standard ESP-IDF component-level project CMake filemain/main.c
- main application file, contains Mongoose logicmain/wifi.c
- contains Wifi setup routine,wifi_init()
main/mongoose.c
- a symlink to repo'smongose.c
main/mongoose.h
- a symlink to repo'smongose.h
main/net.c
- a symlink to the common code for this example,net.c
main/packed_fs.c
- a symlink to the packed filesystem in the common code section, containing the web files to be served,packed_fs.c
CMakeLists
- a standard ESP-IDF top-level project CMake filepartitions.csv
- defines a partition table for a 4MB boardsdkconfig.defaults
- default build valuesMakefile
- mainly invokes Docker to call the IDF utilities
In production code, all project files should be copied
to the main/
directory instead of creating symlinks.
Build the project
Before building the project, open the main/main.c
file and edit your WiFi network
name and WiFi password settings:
The next step is to build the project. It is assumed you're using Linux or Mac as a workstation, you have Docker installed, and your user is able to run it. If in doubt, check
$ docker ps
Start a terminal in the project directory; clone the Mongoose Library repo,
and run the make build
command:
$ git clone https://github.com/cesanta/mongoose
$ cd mongoose/examples/esp32/device-dashboard
$ make build
In order to flash this recently built firmware to your ESP32 board, plug it in a USB port
and execute (change /dev/ttyUSB0
to the actual serial port on your system):
$ make flash PORT=/dev/ttyUSB0
You can also download and unzip esputil, in that case run make flash2 PORT=/dev/ttyUSB0
. When done, connect to the serial console. You can use a serial port application like minicom or you can also use esputil, just run esputil -p /dev/ttyUSB0 monitor
.
Now start a browser on http://IP_ADDRESS
where IP_ADDRESS
is the
board's IP address printed on the serial console. You should see a login screen.
From here on, please go to the device dashboard tutorial and repeat some of the steps depicted there
Main function
The main()
function has three blocks:
- Mount a filesystem and write a sample file
- Initialise WiFi
- Run Mongoose
Mount filesystem
The firmware that has been built does not have a filesystem image flashed, but it
has SPIFFS filesystem support. So the following piece of code initialises
a filesystem, and writes a file hello.txt
using the
mg_file_printf() API call.
For this example we've chosen to embed all the web files in a packed filesystem, more information on the embedded filesystem tutorial
Initialise wifi
There we call a wifi_init()
function which is defined in main/wifi.c
.
That is a blocking function, i.e. it does not return until the board gets an
IP address:
Run Mongoose
Next goes Mongoose. Note that it should be run after network initialisation is complete - which is true in our case. The logic is standard - initialise the event manager, start a listener on port 80, and fall into an infinite event loop:
We have covered those aspects that are specific to the ESP implementation, for the details on the application and the UI, please see the device dashboard tutorial.
Using SPIFFS to store web files
In case we'd like to hold our web files on a partition using the SPIFFS filesystem, here is an example on how to do it.
This event handler function shows a RESTful handler with the /api/state
URI, which reports the amount of
free RAM. Other URIs are treated as static server requests:
There is a caveat there - we redefine FS handler. This is done because
SPIFFS is a flat file system without directory support. Therefore we
create our own filesystem which is derived from a standard POSIX FS but has
a stat()
function redefined - it returns a "directory" flag for /
: