---
title: "Etlas: e-paper dashboard"
date: 2024-09-05
layout: post
project: true
thumbnail: thumb_sm.jpg
---
Repurposed the [e-reader](../e-reader/) into something for regular use. News,
stocks, weather dashboard. ESP32 NodeMCU D1 + 7.5" Waveshare e-paper + DHT22
sensor.
Stocks: Two weeks EOD data from Polygon.io (max possible). Flask app on VPS
manages watchlist, relays the feed. Backend: httpd + htpasswd + slowcgi +
Flask.
gui_plot_stocks() plots a stepped graph; was easier to implement, but the code
is hideous; triggers watchdog. vTaskDelay() prevents that.
NOTE: Refactor. Bresenham’s?
News: Channel NewsAsia RSS. MCU does the parsing. Didn't plan to have a backend
at the time. Now that I have one for stocks, should relay the feed for
flexibility.
Weather: DHT22 single-wire protocol. 26µs/50µs/70µs pulses are too fast for
standard ESP32 APIs. Bit-banged relative pulse widths (ported from ESP8266):
```
static inline int dht_await_pin_state(int state, int timeout)
{
int t;
static const uint16_t delta = 1;
for (t = 0; t < timeout; t += delta) {
ets_delay_us(delta);
if (gpio_get_level(DHT_PIN) == state)
return t;
}
return 0;
}
static inline int dht_get_raw_data(unsigned char buf[BUFLEN])
{
int rc;
unsigned char i, pwl, pwh;
gpio_set_level(DHT_PIN, 0);
ets_delay_us(1100);
gpio_set_level(DHT_PIN, 1);
if (!dht_await_pin_state(0, 40)) {
rc = 1;
xQueueSend(dht_evt_queue, &rc, (TickType_t) 0);
return 0;
}
if (!dht_await_pin_state(1, 80)) {
rc = 2;
xQueueSend(dht_evt_queue, &rc, (TickType_t) 0);
return 0;
}
if (!dht_await_pin_state(0, 80)) {
rc = 3;
xQueueSend(dht_evt_queue, &rc, (TickType_t) 0);
return 0;
}
for (i = 0; i < BUFLEN; i++) {
if (!(pwl = dht_await_pin_state(1, 50))) {
rc = 4;
xQueueSend(dht_evt_queue, &rc, (TickType_t) 0);
return 0;
}
if (!(pwh = dht_await_pin_state(0, 70))) {
rc = 5;
xQueueSend(dht_evt_queue, &rc, (TickType_t) 0);
return 0;
}
buf[i] = pwh > pwl;
}
return 1;
}
```
epd_init() stalls intermittently on first refresh() after flash. Toggling delay
values in refresh() resolves it. If the first refresh succeeds, it remains
stable. Root cause unknown--suspect noisy power supply due to powering display
via MCU.
Uptime: August 2024 - January 2026
Commit: a92c86a.