All firmwares

ZephCore

Custom

A ground-up port of MeshCore from Arduino to the Zephyr RTOS. Replaces the Arduino loop with Zephyr's event-driven primitives so the CPU sleeps between events, while aiming for full protocol compatibility with stock MeshCore firmware and the MeshCore mobile apps.

Reimplementation of MeshCore (Reference)

Maintainer
liquidraver ↗
Status
Active
Maturity
Beta
Lifecycle
Active
Latest version
1.16.8-zephcore
Released
2026-07-31
Runtime
Zephyr · C++
Distribution
Community
Licensing
Open source
License
MIT

Capabilities

Transports

  • BLE
  • USB serial
  • Native TCP
  • Wi-Fi AP

Operations

  • Web flasher
  • OTA updates
  • BLE DFU

Networking

  • Repeater
  • Room server
  • Observer
  • MQTT
  • KISS modem

Hardware

  • GPS
  • Display
  • Sensors
  • Low-power RX

Protocol

  • MeshCore compatible
  • Raw packet send
  • Raw packet observe

Node role

CompanionRepeaterRoom serverObserver

Features

  • Zephyr RTOS event-driven architecture
  • CAD-based RX power saving
  • Adaptive contention window
  • Adaptive Power Control
  • DFU / OTA update support
  • Listen-only observer (WiFi + MQTT)
  • Protocol-compatible with MeshCore apps

Project signals

popularity 2026-08-05 verification 2026-08-05
GitHub stars
129
Forks
31
Watchers
8
Open issues
14
Contributors
14
Release downloads
5,937
Latest downloads
53
Source available
Yes
Releases available
Yes
CI builds
Yes

Releases

from GitHub · updated 2026-07-31
  1. v1.16.8-zephcore # Latest Pre-release 5 days ago · 2026-07-31 15:45 UTC

    ZephCore 1.16.8-zephcore

    [!CAUTION] This is a pre-release. ESP32 light sleep is enabled by default on Heltec repeaters and has not been validated on hardware yet — see the light-sleep section for what to check and how to build it out. It is deliberately not published to the apps.meshamerica.com configurator, which keeps offering v1.16.7; flash this one manually from the assets below if you want to help test it. The nRF based boards should be fine.

    [!IMPORTANT]

    Before you upgrade

    From v1.16.5 / v1.16.6 / v1.16.7 — clean flash, no re-bond, bonds and data survive.

    From v1.16.2 / v1.16.3 / v1.16.4 — clean flash, bonds and data survive. If you are on an ESP32-S3 / ESP32-C board and have not yet taken the v1.16.5 update, you still owe the one-time serial reflash: the app moved to flash offset 0x10000 in v1.16.5, and a board on the old layout cannot cross that update over WiFi-OTA or the browser flasher — flash the -merged.bin once over USB/serial. Affected boards: Heltec V3 / V4 / V4.3, Station G2, Wireless Tracker / V2, XIAO ESP32-S3 / C3 / C6, LilyGo T-Lora C6, ThinkNode M9. Identity, contacts, channels, prefs, and BLE bonds are preserved. nRF52, classic ESP32 (T-Beam / PICO-D4 / TTGO LoRa32), STM32WL, and native Linux are unaffected.

    From v1.16.1 or older — flash it; on first boot it clears BLE bonds automatically (identity, contacts, channels, prefs preserved). Re-bond your phone/desktop once.

    Coming from Arduino MeshCore — flash it; auto-formats on first boot (new identity, clean storage).

    Heltec ESP32 repeaters now light-sleep, and their USB CLI stops answering 10 minutes after boot as a result. Reconnecting your terminal normally resets the node and gives you another 10 minutes; if it doesn't, power-cycle. Details in the light-sleep section below.

    One CLI rename: set/get cad.probe.interval is now set/get probe.interval — the same setting, renamed because one measurement now feeds both the noise floor and the CAD probe. Your stored value carries over; only the command name changed. set/get agc.reset.interval is gone (see below).

    Take this with a grain of salt — try the formatters if anything anomalous happens with your node.


    A power and radio-measurement release. Repeaters no longer wake on a fixed 5 s tick — they sleep until their next real deadline. Every ESP32 build drops to 80 MHz, and Heltec repeaters now light-sleep between packets. The noise-floor sampler and CAD probe were unified into one measurement, the SX126x RSSI/AGC calibration is now band-correct, and the observer role got a batch of fixes for settings that silently never reached the hardware.

    Highlights

    Repeaters are now deadline-driven — the periodic housekeeping tick is gone

    Every repeater woke five times a second-and-a-bit forever: a fixed 5 s "housekeeping" timer that ran the noise-floor sample, the CAD probe, advert timers and the tempradio revert. None of that actually needs a poll — each item is either a deadline or a sampler with its own interval.

    The new mesh/Maintenance.h contract lets the event loop ask "when does maintenance next have work?" and arm one one-shot wake for exactly that moment. An idle repeater now sleeps until its soonest real deadline instead of on a fixed cadence. A hard ceiling (CONFIG_ZEPHCORE_MAINTENANCE_BACKSTOP_MS, default 60 s) clamps the wake as a safety net against a missed deadline — it should never bind in normal operation.

    Companions and room servers keep their periodic tick deliberately: the companion block contains genuine pollers (contact-dump progress, BLE advertising watchdog) with no deadline to arm, and the room server is paced by its own 500 ms push timer regardless.

    ESP32 power: 80 MHz everywhere, and light sleep on Heltec repeaters

    Espressif parts have no equivalent of the nRF52's "idle at microamps in WFI" — WAITI gates the core clock but le …

  2. v1.16.7-zephcore # 11 days ago · 2026-07-25 13:15 UTC

    ZephCore 1.16.7-zephcore

    [!IMPORTANT]

    Before you upgrade

    From v1.16.6 / v1.16.5 — clean flash, no re-bond, bonds and data survive.

    From v1.16.2 / v1.16.3 / v1.16.4 — clean flash, bonds and data survive. If you are on an ESP32-S3 / ESP32-C board and have not yet taken the v1.16.5 update, you still owe the one-time serial reflash: the app moved to flash offset 0x10000 in v1.16.5, and a board on the old layout cannot cross that update over WiFi-OTA or the browser flasher — flash the -merged.bin once over USB/serial. Affected boards: Heltec V3 / V4 / V4.3, Station G2, Wireless Tracker / V2, XIAO ESP32-S3 / C3 / C6, LilyGo T-Lora C6. Identity, contacts, channels, prefs, and BLE bonds are preserved. nRF52, classic ESP32 (T-Beam / PICO-D4 / TTGO LoRa32), STM32WL, and native Linux are unaffected.

    From v1.16.1 or older — flash it; on first boot it clears BLE bonds automatically (identity, contacts, channels, prefs preserved). Re-bond your phone/desktop once.

    Coming from Arduino MeshCore — flash it; auto-formats on first boot (new identity, clean storage).

    Take this with a grain of salt — try the formatters if anything anomalous happens with your node.


    A stability-and-hardware release. The headline is a whole-node wedge fixed in the GPS power-management path that shipped in v1.16.6, plus RX duty cycle finally working on LR1110 boards and a new safety margin that stops signal-independent duty-cycle packet drops on every radio. Rounded out by joystick-UI fixes and a color-display improvement for the Heltec T114.

    Highlights

    Fixed: a GPS node could wedge completely on standby (regression in v1.16.6)

    v1.16.6 introduced GPS-UART suspend to save power (an armed nRF UARTE receiver costs ~0.5–1 mA even with the GPS module powered down). It had a race that could hang the entire node — no LoRa, no USB, no BLE, CLI answering -> busy, recoverable only by reboot.

    The upstream nRF UARTE suspend path spins forever waiting for an RXTO event after issuing STOPRX. In interrupt-driven mode the receiver runs one byte at a time and re-arms from its ISR; if a byte happened to finish in the narrow window where the driver had already disabled the ENDRX interrupt, the receiver was left stopped-and-un-rearmed, STOPRX produced no RXTO, and the wait never returned — with the main mesh thread stuck inside it. Any nRF board that powers its GPS module down and suspends the port on standby could hit this.

    Fixed in two independent layers, so neither alone is load-bearing:

    • ZephyrGPSManager settles ~5 ms before suspending the GPS UART, letting the last in-flight byte finish and the RX ISR re-arm, so the receiver is armed-and-idle when STOPRX fires — the state that reliably yields RXTO. Standby happens at most every few minutes, so the cost is negligible.
    • New patch 0010 bounds the driver's RXTO wait to 4 ms instead of spinning forever. On timeout it falls through to the unconditional nrf_uarte_disable() that force-stops the receiver anyway — so even if a byte still lands in the race window, the node can never hang.

    RX duty cycle now works on LR1110 boards

    LR1110 boards (T1000-E, ThinkNode M9, and other LR11xx radios) now get real RX duty-cycle sniff mode instead of sitting in continuous receive — a substantial receive-power saving on battery nodes, the same mechanism SX126x boards have had. This took a significant rework of the LR11xx LoRa driver to land correctly.

    New: duty-cycle safety margin stops signal-independent packet drops

    set-able via CONFIG_ZEPHCORE_LORA_DC_MARGIN_PCT (default 15%), shared by every radio (SX126x / LR11xx / LR20xx).

    The theoretical per-cycle "deaf-time" budget that duty cycle is computed from assumes the sleep clock and the wake transition are exact. They are not: the chip's sleep timer runs on an internal RC oscillator (RC64k on SX126x, RTC on LR11xx) that drifts several …

  3. v1.16.6-zephcore # 13 days ago · 2026-07-23 15:33 UTC

    ZephCore 1.16.6-zephcore

    [!IMPORTANT]

    Before you upgrade

    From v1.16.5 — clean flash, no re-bond, bonds and data survive.

    From v1.16.2 / v1.16.3 / v1.16.4 — clean flash, bonds and data survive. If you are on an ESP32-S3 / ESP32-C board and have not yet taken the v1.16.5 update, you still owe the one-time serial reflash described there: the app moved to flash offset 0x10000 in v1.16.5, and a board on the old layout cannot cross that update over WiFi-OTA or the browser flasher — flash the -merged.bin once over USB/serial. Affected boards: Heltec V3 / V4 / V4.3, Station G2, Wireless Tracker / V2, XIAO ESP32-S3 / C3 / C6, LilyGo T-Lora C6. Identity, contacts, channels, prefs, and BLE bonds are preserved. nRF52, classic ESP32 (T-Beam / PICO-D4 / TTGO LoRa32), STM32WL, and native Linux are unaffected.

    From v1.16.1 or older — flash it; on first boot it clears BLE bonds automatically (identity, contacts, channels, prefs preserved). Re-bond your phone/desktop once.

    Coming from Arduino MeshCore — flash it; auto-formats on first boot (new identity, clean storage).

    Take this with a grain of salt — try the formatters if anything anomalous happens with your node.


    A maintenance release: an important admin-password fix, a substantial identity-key randomness hardening on ESP32, GPS standby power savings, and the removal of Adaptive Power Control — plus two new boards, muzi works R1 Neo and an experimental first cut at the ThinkNode M9 in dev.

    Highlights

    2-tap and 5-tap are switched

    After a lot of inadvertently sent adverts, the functions of the 2 and 5 clicks were switched, so a double click with the user button now only enables/disables the LEDs and no longer accidentally sends a flood advert.

    Fixed: uppercase letters in an admin password were silently lowercased

    If you set or changed an admin password on v1.16.5 and can no longer log in, this is why. v1.16.5 introduced case-insensitive CLI keywords by lowercasing the first two words of every command before matching them. That is safe for get cad — but password <value> puts the value in the second word, so password MyPass was stored as mypass, and the password you typed afterwards never matched. (set guest.password <value> has three words and was never affected.)

    The normalizer has been removed and CLI commands are case-sensitive again, matching upstream Arduino MeshCore. If you are locked out, re-flash and reconfigure, or log in with the all-lowercase form of the password you set.

    The one place autocapitalization genuinely hurts — typing commands to the V-Contact from a phone keyboard, which capitalizes the first letter of every line — is handled narrowly instead: only character 0 of a V-Contact chat line is folded. No command takes an argument at position 0, so no value can be touched.

    Identity keys are now generated with hardened, hardware-verified randomness

    Your node's identity — the Ed25519 keypair that is your node on the mesh — is generated once, on first boot, and kept for life. An investigation into how the randomness behind that key is gathered found that ESP32 boards were generating identities with far less entropy than intended. Two independent problems, both fixed in this release:

    • The ESP32 hardware RNG was running unseeded. It only produces true random numbers while the radio (WiFi/BT) is active — and identity generation runs before the radio comes up (on repeaters, the radio never comes up at all). Key generation now feeds the RNG from the chip's ADC noise source for its duration, Espressif's documented method for exactly this pre-radio situation. Verified on hardware: the RNG's output went from a fixed pattern to statistically ideal.
    • The timing-jitter backup source measured nothing on ESP32. It sampled the CPU's cycle counter against work …
Show all 20 releases →

Device compatibility (35)

✓ 34 Supported◑ 1 Partial
DeviceMCURadioStatusNotes
RAK WisBlock / WisMesh (RAK 4631)nrf52840Semtech SX1262✓ Supported
Atlavox M1nrf52840Semtech SX1262✓ Supported
Atlavox Beacon Solarnrf52840Semtech SX1262✓ Supported
RAK WisMesh Repeater Mininrf52840Semtech SX1262✓ Supported
Yeti Wurks Base Stationnrf52840Semtech SX1262✓ Supported
μArt.cz Solar Node Stationnrf52840Semtech SX1262✓ Supported
LilyGo T-Echonrf52840Semtech SX1262✓ Supported
Wio Tracker L1nrf52840Semtech SX1262✓ Supported
Wio Tracker L1 Pronrf52840Semtech SX1262✓ Supported
Heltec V3esp32-s3Semtech SX1262✓ Supported
Heltec WSL3esp32-s3Semtech SX1262✓ Supported
Heltec V4esp32-s3Semtech SX1262✓ Supported
Heltec V4 + Expansion Kit (Touch)esp32-s3Semtech SX1262✓ Supported
Heltec T114nrf52840Semtech SX1262✓ Supported
Heltec Wireless Tracker v3esp32-s3Semtech SX1262✓ Supported
LilyGo T-Beam (SX1262)esp32Semtech SX1262✓ Supported
LilyGo T-LoRa C6esp32-c6Semtech SX1262✓ Supported
RAK WisMesh 1W Booster (3401 + 13302)nrf52Semtech SX1262✓ Supported
RAK WisMesh Tagnrf52840Semtech SX1262✓ Supported
Seeed Studio SenseCAP Solar Node P1nrf52840Semtech SX1262✓ Supported
Seeed Studio SenseCAP Solar Node P1-Pronrf52840Semtech SX1262✓ Supported
Seeed Studio SenseCAP T1000-Enrf52840Semtech LR1110✓ Supported
UnitEng Station G2esp32-s3Semtech SX1262✓ Supported
Elecrow ThinkNode M1nrf52840Semtech SX1262✓ Supported
Elecrow ThinkNode M3nrf52840Semtech LR1110✓ Supported
Elecrow ThinkNode M6nrf52840Semtech SX1262✓ Supported
ProMicro nrf52 (faketec)nrf52840Semtech SX1262✓ Supported
GAT-IoT GAT562 30snrf52Semtech SX1262✓ Supported
Xiao C3esp32-c3Semtech SX1262✓ Supported
Xiao C6esp32-c6Semtech SX1262✓ Supported
Xiao S3 WIOesp32-s3Semtech SX1262✓ Supported
Xiao S3 (plain)esp32-s3Semtech SX1262✓ Supported
Xiao nRF52 WIOnrf52840Semtech SX1262✓ Supported
Xiao MG24 + SX1262efr32mg24Semtech SX1262✓ Supported
Xiao nRF54L15 + SX1262nrf54l15Semtech SX1262◑ PartialEarly bring-up; not all peripherals wired.