- C 91%
- C++ 7.9%
- Python 1.1%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| .vscode | ||
| include | ||
| lib | ||
| src | ||
| test | ||
| .gitignore | ||
| nonet.py | ||
| partitions.csv | ||
| platformio.ini | ||
| README.md | ||
V+A's Coffee Probe
An ESP32-C6 temperature monitor for coffee roasting / brewing. It reads a DS18B20 probe once per second, keeps up to an hour of history, shows live statistics on a 20x4 I2C LCD, and serves an interactive web chart over its own Wi-Fi access point.
Features
- DS18B20 1-Wire probe, 12-bit (0.0625 °C) resolution, read non-blocking.
- Rolling history of up to 3600 samples (1 hour at 1 Hz).
- Selectable averaging windows: 10, 60, 300, 600, 1800 and 3600 seconds.
- 20x4 I2C LCD showing current, average, delta, min and max for the window.
- SoftAP with a web dashboard: interactive Chart.js line chart plus a now/avg/min/max readout.
- Auto-recovers if the probe is missing or unplugged (re-scans every 5 s).
- Optional timestamped serial debug logging.
Hardware
| Part | Connection |
|---|---|
| ESP32-C6-DevKitC-1 | — |
20x4 I2C LCD (PCF8574 backpack, addr 0x27) |
SDA → GPIO6, SCL → GPIO7, VCC → 3V3, GND → GND |
| Push button | GPIO10 → GND (uses internal pull-up) |
| DS18B20 | DQ → GPIO11, VDD → 3V3, GND → GND, 4.7 kΩ pull-up from DQ to 3V3 |
Notes for the ESP32-C6-DevKitC-1:
- GPIO6/GPIO7 are the default LP_I2C pins and are broken out on J1 (pins 5/6).
- Avoid GPIO12/13 (native USB D-/D+) and the strapping pins GPIO4/5/8/9/15.
- GPIO14 and GPIO27 are not exposed on this board.
The DS18B20 is used in normal 3-wire mode (not parasitic power).
Building and flashing
Requires PlatformIO. The ESP32-C6 needs the
pioarduino espressif32 platform (v7.x or newer).
pio run # build
pio run -t upload # flash
pio device monitor # serial monitor (115200 baud)
This project uses a custom partitions.csv (3 MB per OTA app slot) because the
Wi-Fi stack plus the embedded Chart.js page exceed the default 1.25 MB app
partition. Because the partition layout differs from the stock one, erase the
flash once before the first upload:
pio run -t erase && pio run -t upload
Configuration
Build switches at the top of src/main.cpp:
| Switch | Default | Effect |
|---|---|---|
USE_DISPLAY |
1 |
Set to 0 to run headless (skips I2C/LCD entirely) |
USE_WIFI |
1 |
Set to 0 to disable the SoftAP and web dashboard |
DEBUG_SERIAL |
0 |
Set to 1 for timestamped DBG(...) logging |
USE_DISPLAY and USE_WIFI can also be overridden at build time, e.g.
pio run -e esp32-c6-devkitc-1 with PLATFORMIO_BUILD_FLAGS=-DUSE_DISPLAY=0.
Other tunables in src/main.cpp:
TIMES[]— averaging windows in seconds.MAX_TEMPERATURES— history depth (default 3600).SAMPLE_INTERVAL_MS— sampling period (default 1000 ms).CONVERSION_MS— DS18B20 conversion time; tied to the 12-bit resolution (750 ms). Adjust if you changesetResolution().LONG_PRESS_MS— hold time to clear the stats (default 1000 ms).AP_SSID/AP_PASSWORD— SoftAP credentials.PIN_SDA,PIN_SCL,PIN_BUTTON,PIN_ONEWIRE.
Temperatures are stored internally in tenths of a degree Celsius (int16_t).
Usage
Button
- Short press — cycle the averaging window through 10 / 60 / 300 / 600 / 1800 / 3600 s.
- Long press (≥ 1 s) — clear the recorded history; all statistics restart.
LCD (20x4)
+--------------------+
| V+A's Coffee Probe | row 0: static, centred title
| Cur 21.4° n 3600 | row 1: current temperature, window size (s)
| Avg 21.2° Δ 0.3° | row 2: window average, delta since window start
| Max 22.0° Min 20.8°| row 3: window max / min
+--------------------+
Status messages (Stats cleared, DS18B20 missing) are shown on the 3rd line.
Web dashboard
Join the Wi-Fi network V-A Coffee Probe (password coffeeprobe by default)
and open http://192.168.4.1/. The page refreshes every 5 seconds.
| Route | Description |
|---|---|
/ |
Dashboard (chart + stats) |
/chart.js |
Embedded Chart.js 4.4.4 (205 KB, served from flash) |
/data |
{"interval":1,"temps":[tenths-of-°C,...]} |
Chart rendering happens in the browser, so it costs the device no memory. The access point has no internet connection, which is why Chart.js is embedded rather than loaded from a CDN.
Memory
Measured on the ESP32-C6-DevKitC-1 with USE_WIFI=1, USE_DISPLAY=1:
RAM: 13.7% (44924 / 327680 bytes) static, before runtime Wi-Fi heap
Flash: 40.8% (1282808 / 3145728 bytes) in a 3 MB app slot
- History: up to 3600 ×
int16_t≈ 8 KB heap. /dataresponse: ~20 KB JSON for a full hour, built in areserve()dString(~22 KB peak heap).- Wi-Fi SoftAP stack: roughly 50–80 KB heap.
Project layout
platformio.ini PlatformIO environment and library dependencies
partitions.csv Custom 8 MB flash partition table (3 MB OTA slots)
src/main.cpp Firmware
include/chart_js.h Chart.js 4.4.4 UMD minified, embedded as PROGMEM
include/index_html.h Web dashboard HTML/JS, embedded as PROGMEM
nonet.py Original MicroPython prototype (reference)
Dependencies
- LiquidCrystal_I2C 1.1.4
- OneWire — pinned to a commit with ESP32-C6 GPIO support (release 2.3.8 does not build for the C6)
- DallasTemperature 3.11.0
- Chart.js 4.4.4 (embedded)