This project runs on a Heltec Vision Master E290 and displays dive stats on e-paper.
It supports:
- Normal low-power operation with deep sleep
- Orientation-based display layout
- Magnet/reed-switch wake
- OTA firmware updates
- Optional internet auto-update from GitHub release binaries
- Daily data refresh from a JSON endpoint
- Auto firmware version from Git (
git describe --tags --always --dirty)
The firmware fetches JSON from JSON_URL defined in src/secrets.h.
Expected fields:
totalDivestotalMinutesUnderwaterdeepestDivedaysUntilnextDive
- Device wakes from:
- Reed switch (
WAKE_PINLOW) - 24-hour timer wake
- Reed switch (
- After handling wake logic, it returns to deep sleep.
- Forced refresh (
?refresh=1) happens only when:- The 24-hour timer wake fires
- OTA mode is entered
- Other wake events show cached values from RTC memory.
- Reed switch LOW opens a short orientation check window.
- OTA mode is entered when rotation matches
OTA_ROTATION(currently270in code trigger logic). - Side orientations are rendered at 90-degree display orientation to avoid showing a 270-degree-rendered screen.
Relevant constants in src/DiveInfo.ino:
OTA_ROTATIONOTA_WINDOW_MSWAKE_PIN
- OTA mode screen shows:
- Logo + battery
- Current device IP
- OTA listens for
OTA_WINDOW_MS(currently 60s). - If no OTA upload occurs, firmware reboots.
- If
INTERNET_OTA_MANIFEST_URLis set insrc/secrets.h, firmware checks for updates:- During daily timer wake (
INTERNET_OTA_CHECK_ON_TIMER_WAKE = 1) - When OTA mode is entered with the magnet
- During daily timer wake (
- If manifest
versiondiffers from current firmware version, the device downloads and appliesbin_url. - Updates are skipped when battery percent is below
INTERNET_OTA_MIN_BATTERY_PERCENT.
Manifest JSON example:
{
"version": "v1.6.0",
"bin_url": "https://github.com/<user>/<repo>/releases/download/v1.6.0/firmware.bin"
}platformio.ini is configured with:
vision_master_e290(default): OTA upload (espota)vision_master_e290_usb: emergency USB upload (esptool,COM9)
Commands:
# Default (OTA)
platformio run -e vision_master_e290 -t upload
# Emergency USB
platformio run -e vision_master_e290_usb -t uploadFirmware secrets/config:
- Copy
src/secrets.example.htosrc/secrets.h - Set your own:
wifiListJSON_URLOTA_HOSTNAMEOTA_PASSWORD(set non-empty for protection)INTERNET_OTA_MANIFEST_URL(optional)INTERNET_OTA_MIN_BATTERY_PERCENT(optional)INTERNET_OTA_CHECK_ON_TIMER_WAKE(optional)
Runtime settings in code (src/DiveInfo.ino):
OTA_ROTATIONif you want a different trigger orientation
Edit platformio.ini:
upload_portunderenv:vision_master_e290to current OTA IP shown on the deviceupload_portunderenv:vision_master_e290_usbif COM port changes
Worker secrets/config (src/worker.js):
- Set Cloudflare Worker env vars:
ICS_URLDIVEL0GS_USERDIVEL0GS_PASS
src/worker.jsis included in this repo as a Cloudflare Worker source for generating the JSON payload.- OTA upload requires the board to be on the OTA screen and reachable on the same network.
src/secrets.his intentionally ignored by Git so personal Wi-Fi and endpoint values are not committed.- Firmware version shown on screen is injected at build time from Git via
scripts/git_version.py.