
Switch
byrantech/laptop
anyon_e, a highly integrated, high end, open source laptop. Attempt the impossible.

An e-ink tide and weather display for Lakebay, WA (Mayo Cove · Puget Sound). An ESP32 wakes on a timer, fetches NOAA tide predictions and NWS weather over HTTPS, renders a dashboard into a framebuffer on-device, streams…
Tide carrier is an open-source printed circuit board by toddself, from the toddself/weather-esp32-eink repository on GitHub. It is a 2-layer board of 75 × 55 mm with 6 parts on 5 nets, routed with 13 tracks and 0 vias.
Its parts include 2 resistors and 2 ICs. It belongs with the lEDs and displays boards and the ESP32 boards of this library.
An e-ink tide and weather display for Lakebay, WA (Mayo Cove · Puget Sound). An ESP32 wakes on a timer, fetches NOAA tide predictions and NWS weather over HTTPS, renders a dashboard into a framebuffer on-device, streams it to a 13.3" e-paper panel, and goes back to sleep.
tide-fw/ — Arduino/ESP32 firmware (PlatformIO). Fetches data, renders the
dashboard, and drives the e-ink display.tide-assets/ — offline Rust tool that bakes the Inter font and dashboard
icons into C++ atlas headers consumed by the firmware. Only needs to be re-run
when the font/icon set changes; the generated headers are checked in.docs/ — Waveshare reference material and wiring-power.md (the
PowerBoost-to-driver-board power wiring).pcb/ — board files.On each wake (tide-fw/src/main.cpp):
PST8PDT, US DST rules).fetchAll() pulls NOAA tides + NWS forecast and parses them into TideData.REFRESH_SECS seconds, then repeats.Any failure (no WiFi, no time, fetch error) skips straight to deep sleep and retries on the next wake.
pio) — firmware build/flash/test. This repo pins the PATH to
~/.platformio/penv/bin via mise.toml, and Python via mise.tide-assets.just — task runner (see Common commands).mise (optional but recommended) — provisions Python and sets default
environment variables (see below).The firmware is configured at build time. tide-fw/platformio.ini reads these
values from the environment (sysenv.*) and bakes them into the binary as
compile-time -D flags:
| Variable | Required | Purpose |
|---|---|---|
WIFI_SSID | yes | WiFi network name (2.4 GHz only — the ESP32 has no 5 GHz) |
WIFI_PASS | yes | WiFi password |
REFRESH_SECS | yes | Deep-sleep interval between refreshes, in seconds |
NWS_LAT | yes | Latitude (decimal degrees) for the NWS forecast + sun/moon |
NWS_LON | yes | Longitude (decimal degrees) |
NWS_STATION_TEMP | yes | NWS observation station ID for current conditions (e.g. KTIW) |
NWS_STATION_TIDE | yes | NOAA CO-OPS tide station ID (e.g. 9446583) |
mise.toml supplies defaults for all of these except WIFI_PASS, which is
intentionally not committed and must be provided at flash time (this project keeps
it in fnox). The committed defaults point at Lakebay, WA:
# mise.toml
WIFI_SSID = "…"
REFRESH_SECS = "900" # 15 minutes
NWS_LAT = "47.259174"
NWS_LON = "-122.764622"
NWS_STATION_TEMP = "KTIW"
NWS_STATION_TIDE = "9446583"To point the display at a different location, change NWS_LAT/NWS_LON and the
two station IDs — no source edits required. If you are not using mise,
export them all yourself before flashing:
export WIFI_SSID="your-network"
export WIFI_PASS="your-password"
export REFRESH_SECS=900
export NWS_LAT=47.259174
export NWS_LON=-122.764622
export NWS_STATION_TEMP=KTIW
export NWS_STATION_TIDE=9446583These are read by PlatformIO's build, so they must be set in the same shell that runs
just fw-flash.NWS_STATION_TEMP(weather/temperature) andNWS_STATION_TIDE(tides) are two different stations from two different NOAA services — find a nearby observation station viaapi.weather.gov/points/<lat>,<lon>and a tide station at tidesandcurrents.noaa.gov.
Wire up power and the panel. See docs/wiring-power.md and the pin map in
CLAUDE.md. The target board is the Waveshare E-Paper ESP32 Driver Board
paired with the 13.3" e-Paper HAT (K).
Set the on-board switches.
Connect the board over USB-C (older boards use micro-USB). The USB-UART bridge is a CH343 on recent boards (CP2102 on older ones) — install the matching driver if the serial port doesn't enumerate.
Set the environment variables (see above). With mise, only
WIFI_PASS is left to provide:
export WIFI_PASS="your-password"(Optional) Regenerate assets if you changed the font or icons:
just fw-assetsBuild and flash:
just fw-flashTo flash and immediately watch the serial log:
just fw-flash-monitorWatch the boot log (115200 baud) to confirm WiFi connects, time syncs, and the fetch/render succeeds:
just fw-monitorYou should see it connect, render, then print
Entering deep sleep for 900 s.
For deployment, turn Switch 2 (UART power) OFF to save power once the firmware is flashed.
All wrapped by just (see justfile):
just # list all recipes
just check # lint + tests (Rust) + firmware native tests
just test # cargo test -p tide-assets
just lint # cargo fmt --check + clippy -D warnings
just fw-assets # regenerate font/icon headers (cargo run -p tide-assets)
just fw-test # pio test -e native (host-side render/parse tests)
just fw-flash # build + upload firmware
just fw-monitor # open the serial monitor
just fw-flash-monitor # upload, then open the serial monitortide-fw has a PlatformIO native env that compiles the
platform-independent parsing/rendering code and runs it under the Unity test
framework on the host — it excludes the ESP32-only sources (main.cpp,
display.cpp, net.cpp, fetch.cpp, battery.cpp). Run it with just fw-test.
CI (self-hosted Forgejo runner) runs cargo fmt --check, clippy -D warnings,
cargo test for tide-assets, and pio test -e native for the firmware.
The renderer is platform-independent, so you can preview the dashboard on the host without flashing:
tide-fw/tools/render_preview.sh # writes /tmp/render.png (as the panel shows it)It renders renderDashboard with representative data and also emits
/tmp/render_paper.png (inverted). Handy for iterating on layout/fonts/icons.
Note on device memory: a full 960×680 2bpp frame is ~159 KB, larger than the largest contiguous block on this no-PSRAM ESP32 (~110 KB). The firmware renders in two horizontal bands and streams each — grayscale is preserved. The host preview renders the whole frame at once.
board = esp32dev) — ESP32,
4 MB flash, 2.4 GHz WiFi.See CLAUDE.md and docs/ for the full pin map, switch settings, and wiring
diagrams.
| Qty | Value | Footprint | References |
|---|---|---|---|
| 2 | 100k | Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P7.62mm_Horizontal | R1, R2 |
| 2 | M2 | MountingHole:MountingHole_2.2mm_M2 | H1, H2 |
| 1 | PowerBoost_1000C | tide-carrier:PowerBoost_1000C | U2 |
| 1 | Waveshare_ESP32_Driver | tide-carrier:Waveshare_ESP32_Driver | U1 |
It measures 75 × 55 mm and has 2 copper layers, 1.6 mm thick.
6 parts. The full list of its parts is on this page, with links to each part's symbol and footprint where PCBKit's library has them.
From the toddself/weather-esp32-eink repository on GitHub, at the commit this page was made from: the board is pcb/carrier/tide-carrier.kicad_pcb. PCBKit opens the board in the browser, with nothing to install.
Its repository states no licence, so its author keeps all rights: ask toddself before reusing the design.

byrantech/laptop
anyon_e, a highly integrated, high end, open source laptop. Attempt the impossible.


Jcparkyn/dpoint
Open-source digital stylus using camera tracking and inertial measurements

VoronDesign/Voron-Hardware
Cool Hardware designed by the Voron Design group

hoglet67/RGBtoHDMI
Bare-metal Raspberry Pi project that provides pixel-perfect sampling of Retro Computer RGB/YUV video and conversion to HDMI

hackclub/OnBoard
💡 Join 1,000 teenagers and make your first PCB with a $100 grant!

Luos-io/luos_engine
Open-source and real-time orchestrator for cyber-physical-systems, to easily design, test and deploy embedded applications and digital twins.
