Continuing my work with e-paper, I built a dashboard to display news, stocks, and weather using an e-paper display HAT, an ESP32 Mini NodeMCU D1 development board, and an AM2302 (DHT22) temperature and humidity sensor. The dashboard performs complex tasks like parsing XML and CSV fetched from the internet, printing dynamic text, and drawing charts pixel by pixel at runtime on the ESP32.

Dashboard
PCB with MCU and the sensor

Hardware setup

The following schematic outlines the electrical connections between the MCU, the display and the AM2302 sensor:

Circuit diagram

The ESP32 board supplies power to the e-paper display and the AM2302 sensor. The MCU draws power via the 5V micro USB port connected to a wall socket.

Building and running the application

The Kconfig.projbuild file contains most of application configuration like the WiFi connection settings and stock symbols.

To display new stocks, add the stock symbols and their reference prices to Kconfig.projbuild. For instance, to add a second stock, insert new entries STOCK_SYM_2 (stock symbol) and STOCK_PRICE_2 (stock price) to the configuration file, and update the arrays names and prices_ref in stock.c file to reference them.

The URLs for news feed and stock API are set in the news.c and stock.c files respectively. Update them to use alternate data sources. The XML and CSV parsing logic in the parse() functions in each of them may require modifications (hopefully minor) for different data sources.

The ESP-IDF requires secure HTTP connections by default. For alternate data sources, replace the contents in news_cert.pem and stock_cert.pem files with the contents in their respective SSL root certificates. To obtain the certificates, issue the following command and take the last certificate in the chain of certificates:

$ openssl s_client -showcerts -connect $hostname:443 </dev/null

The vTaskDelay() at the end of main.c file controls the dashboard's refresh interval. The default value is 5 minutes. The e-paper display can take up to five seconds to update the screen. In addition, there is a maximum count of refresh cycles the display can withstand before wearing off (~100000). Consider these factors when using shorter refresh cycles.

Finally, build and upload the program to the ESP32 by issuing the command idf.py build flash.

How does it work?

Upon starting up, the ESP32 connects to a WiFi access point (2.4GHz network), synchronizes system time with an NTP server, and downloads news (from two RSS feeds for local and world news) and 30-day stock price time series over the internet.

A freeRTOS background task in dht.c file queries the AM2302 sensor for temperature and humidity at five-minute intervals. Another background task defined in news.c updates the news feed every hour. Stock prices are only updated once a day to avoid exceeding the API rate limits.

The app_main() function in main.c updates the e-paper display with the latest available data from the three sources.

Fonts were prepared by exporting each glyph as a JPEG image using GIMP to a directory and executing the fonttool.py script from within that directory. The following command generates a C header file that contains the images as bitmaps:

$ python -m fonttool $output $font_size

The functions defined in gui.c write content to the frame buffer, which, in turn, epd.c draws onto the display.

Bugs

A 4MB ESP-32 can store up to 15 days for 10 stock symbols. However, ESP-32's wifi stack appears to allocate memory in the background, causing the program to run out of memory after about an hour. As a workaround, da3f8f4.patch stops the wifi stack after downloading stock timeseries at the cost of no longer updating the news feed hourly.

Files: source.tar.gz, da3f8f4.patch