JakubandClaude Opus 5 fe02fda897 docs: restructure README, document external input, tidy docs tree
README had drifted from the firmware in several places:

- Supported Devices listed only the three nRF52 boards; Heltec V3/V4 were
  missing entirely, as was any mention that ESP32-S3 flashes differently.
  Flashing is now split per MCU, with the merged-vs-app-only .bin trap
  spelled out — that one costs an afternoon to diagnose from a dark screen.
- It advertised a Lemon/Default font switch that was retired in v1.23; there
  is one unified misc-fixed 6x9 font now and no font setting at all.
- tools/README claimed ENABLE_SCREENSHOT had to be added by hand, directly
  contradicting README's "no special build flags required". The envs have
  carried the flag for a while; rewrote the file to cover all four tools.
- "S key for screenshot" described screenshot.py's menu, not the device —
  screenshots are driven entirely from the host via CMD_GET_SCREENSHOT.

Structurally, general notes (factory reset on migration, BLE-over-USB
priority) sat at the tail of the ESP32 subsection and read as ESP32-specific;
they're now placed where they apply. Heltec wiring moved out of Supported
Devices into its own section so the device table stays scannable, and the
Solo Tools heading is no longer a link (it was generating a garbage anchor).

New docs/solo_features/external_keyboard.md covers CardKB and the wired
joystick: shortcut table, Full vs Compact, and the pin assignment. The pins
are marked as verified on real V4 hardware only — V3 inherits them from
Heltec's documented pin-compatibility and hasn't been checked on a board.

FEATURES.md (roadmap + code audit, developer-only) moves to
docs/development/roadmap.md; nothing referenced it by path.

Adds Building from source / Releasing / Repository layout, since the release
flow was only discoverable by reading the workflow.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 19:21:39 +02:00
2026-04-28 21:39:34 +10:00
2026-05-23 23:52:04 +02:00
2025-01-13 14:07:48 +11:00
2025-06-05 20:35:40 +12:00
2026-04-24 19:37:21 +00:00
2026-03-23 14:26:56 +01:00
2025-01-20 10:20:42 +11:00
2025-01-25 23:09:09 +11:00
2026-03-31 00:51:15 +13:00
2025-03-03 18:08:00 +13:00
2026-06-05 21:25:25 +12:00

MeshCore Solo Companion Firmware

A fork of the official MeshCore companion radio firmware with extended features and UI enhancements, targeting a growing set of supported devices.

Join the discussion on the official MeshCore Discord: https://discord.gg/sdhYArU2jr

Solo firmware thread: https://discord.com/channels/1495203904898728149/1505294337884553447


Supported Devices

Device MCU Display Firmware file
Seeed Wio Tracker L1 (OLED) nRF52840 SSD1306 / SH1106 128 × 64 solo-<version>-WioTrackerL1.uf2
Seeed Wio Tracker L1 (E-ink) nRF52840 GxEPD2 250 × 122 solo-<version>-WioTrackerL1Eink.uf2
GAT562 30S Mesh Kit nRF52840 SSD1306 128 × 64 solo-<version>-GAT562-30S-Mesh-Kit.uf2
Heltec LoRa32 V3 ESP32-S3 SSD1306 128 × 64 solo-<version>-Heltec-v3-merged.bin
Heltec LoRa32 V4 ESP32-S3 SSD1306 128 × 64 solo-<version>-heltec-v4-merged.bin

All firmware files are published on the releases page. Each binary supports both BLE and USB serial — there are no separate BLE/USB builds.

The MCU column decides how you flash: nRF52840 boards take a drag-and-drop .uf2, ESP32-S3 boards take a .bin written with a flasher — see Flashing.

The three nRF52840 boards work out of the box. The two Heltec boards have no joystick and no keyboard of their own, so they need a keyboard or a joystick wired up before the solo UI can be driven.


Feature highlights

  • Extended language support with native Unicode rendering and input — one unified 6×9 display font covering Latin, Greek and Cyrillic, plus on-screen keyboard alphabets for Cyrillic, Greek, Polish, Czech, Slovak, German, French, Spanish, Portuguese and Nordic (Danish/Norwegian/Swedish). Pick two in Settings Keyboard (Main and Additional) and switch between them while typing

  • Enabled sensor screens with support for onboard sensors (temperature, humidity, pressure, luminosity, CO₂) and GPS data

  • GPS navigation — a full navigation suite that needs no extra hardware (details in the Tools Screen docs):

    • Waypoints — mark a spot (car, camp, water…) with a short label, see it on the trail map, and get live bearing + distance back to it; the list always offers a one-tap backtrack to where your trail started
    • GPS compass — heading derived from course-over-ground (no magnetometer needed), shown as a clear scrolling heading tape with a large degrees + cardinal readout
    • Navigate to anything — a saved waypoint, a node straight from Nearby Nodes, or a location someone shares with you in a message
    • Share & save locations — send a waypoint to a contact or channel; on the other end, navigate to or save any shared location with one menu
    • Live location sharing — broadcast your position over the mesh as you move (movement-gated, to a channel or contact) and see others who share theirs as pins on the map and live distance/bearing in Nearby
    • Locator — arm a geofence around a target — a saved waypoint or a person (their live/last-known position) — and get an alert when you arrive/leave or they get near/far, with an optional homing beeper that ticks faster the closer you get. Set it from the Locator screen or straight from Nearby Nodes / Waypoints, and see the target as a flag on the map
    • GPS trail — background route recording with an auto-fit map (waypoints + live position), summary stats, auto-pause on stops, and GPX export
    • Metric or imperial — one global Units setting drives every distance and speed across the UI
  • Messages Screen — view and send messages, open message details, reply with quick messages or custom text, navigate to / save locations shared in a message, per-channel notification and melody overrides, add/edit/delete channels on-device

  • Favourites Dial — pin up to six contacts for quick access from the home screen

  • Settings Screen — configure display, sound, home page order, radio and system settings

  • Clock Screen — view time and date plus up to three configurable data fields, with built-in clock tools (one-shot alarm, countdown timer, stopwatch)

  • Screen Lock — lock the device to prevent accidental keypresses, with a lock screen showing time and sensor data

  • Tools Screen — GPS trail & waypoints, compass, nearby nodes (with ping & navigate), ringtone editor, remote bot, auto-advert, live location sharing, locator, diagnostics, repeater, remote admin

  • External Keyboard & Joystick — optional, auto-detected hardware: an M5Stack CardKB for typing messages without the on-screen grid (Fn+Enter submits, Fn+letter picks an accent, Tab is Hold-Enter, Fn+Esc locks), plus a wired joystick for boards without one. A Compact keyboard mode makes CardKB-only, joystick-free operation practical

  • Battery saving (radio) — two optional, independent toggles under Settings Radio:

    • Pwr save — hardware duty-cycle receive (SX126x SetRxDutyCycle): the radio cycles RX↔sleep on its own and wakes on a preamble, cutting average RX current with only a little added receive latency
    • Auto pwr — Adaptive Power Control: trims actual TX power on strong links (from ACK SNR) and ramps back up to the configured ceiling on weak/lost links; the home screen shows the live power

E-ink Display (Wio Tracker L1)

The e-ink variant targets the Wio Tracker L1 fitted with a 2.13″ GxEPD2 panel (250 × 122 px). All screens have been adapted for the e-ink panel:

  • Adaptive layout — every screen reflows correctly in both landscape (250 × 122) and portrait (122 × 250) orientations
  • Display rotation — configurable in Settings Display; applied immediately and persisted across reboots
  • Joystick rotation — independent of display rotation; useful for custom enclosures
  • Full refresh interval — configurable in Settings Display; reduces ghosting on long sessions
  • Clock seconds suppressed by default — seconds are hidden to reduce per-second panel refreshes and extend display lifetime; re-enable in Settings Display

Flashing

Warning

When migrating from official or other custom firmware, backup your data and perform a factory reset to prevent conflicts with existing settings:

  1. Open device settings in the companion app and download a data backup
  2. Go to MeshCore Flasher, select your device, and perform Erase flash before flashing

Updating from an earlier Solo release does not need this, unless the release notes say otherwise.

nRF52840 boards — Wio Tracker L1, GAT562

  1. Download the .uf2 file for your device from the releases page
  2. Press reset twice quickly to enter bootloader mode — the device should appear as a mass storage drive on your computer
  3. Copy the .uf2 file to the drive to flash the firmware

ESP32-S3 boards — Heltec V3, V4

ESP32-S3 has no UF2 bootloader and no mass-storage mode. Releases ship a single -merged.bin per board — bootloader, partition table and app in one image — which goes to offset 0x0:

  • MeshCore Flasher or any Web Serial ESP tool — select the -merged.bin and flash at 0x0
  • esptoolesptool.py --chip esp32s3 write_flash 0x0 solo-<version>-<device>-merged.bin

Note

Building from source produces a second, app-only firmware.bin alongside the merged one. That one belongs at offset 0x10000 and only works if a bootloader is already on the chip — flashing it at 0x0, or onto a freshly erased chip, leaves the device dead-silent. pio run -e <env> -t upload writes the bootloader, partition table and app at their correct offsets in one go, which is why it works where a hand-flashed single .bin does not. Releases only contain the merged image, so this only matters when building yourself.

Connecting the companion app

Applies to every board: each binary serves the companion app over both BLE and USB serial, but not at once.

Important

BLE has priority over USB serial. While a BLE connection is active the USB protocol is suspended. To connect the app over USB, disconnect from BLE first or disable BLE directly on the device.


Hardware setup — Heltec V3 / V4

A single button can't drive the solo UI, and neither Heltec board has a joystick or a keyboard of its own. Both stock builds therefore enable an M5Stack CardKB and a wired joystick on these pins — V3 and V4 are pin-compatible, so the assignment is identical for both:

Function GPIO Notes
CardKB SDA 3 second I2C bus (Wire1) — not the OLED's 17/18
CardKB SCL 4
Joystick UP 23
Joystick DOWN 6
Joystick LEFT 47
Joystick RIGHT 48
Back button 33 required whenever the joystick is enabled
Centre / Enter 0 the onboard PRG button — nothing to wire

Each joystick contact simply shorts its pin to GND — the firmware enables the internal pull-ups, so no external resistors are needed. CardKB needs power and ground alongside SDA/SCL; check your unit's own voltage rating before picking a rail.

Note

This assignment is confirmed working on real V4 hardware. V3 inherits it because Heltec documents the two boards as pin-compatible, but it hasn't been verified on a physical V3 — worth a continuity check against your own module before soldering.

Either device is enough on its own — pins with nothing attached read as not-pressed, and a missing CardKB is simply not detected at boot, so the unused half costs nothing. For a CardKB-only build, wire just SDA/SCL and set Settings Keyboard Ext. KB = Compact, which is designed to need no joystick at all.

These pins are only defaults: they live in the [env:Heltec_v3_companion_solo_dual] / [env:heltec_v4_companion_solo_dual] blocks in variants/heltec_v3/platformio.ini and variants/heltec_v4/platformio.ini, with comments listing which GPIOs each board has already claimed if you want to wire yours differently. Full details in External Keyboard & Joystick.


Documentation

This fork

Document Description
Messages Screen Sending messages, context menus, reply, navigate to / save shared locations, Notif/Melody overrides
Favourites Dial Pinned contacts grid, unread badges, pin/unpin
Clock Screen Clock page, date, configurable data fields, alarm / timer / stopwatch
Settings Screen All settings sections with values and interactions
Screen Lock Lock/unlock sequence, lock screen, auto-lock
Tools Screen GPS trail & waypoints, compass, navigation, nearby nodes, ringtone editor, remote bot, auto-advert, live location sharing, locator, diagnostics, repeater, remote admin
External Keyboard & Joystick CardKB shortcuts, Full vs Compact mode, wired joystick, Heltec V3/V4 wiring
Solo UI framework Developer guide — the reusable building blocks (screens, lists, popups, mini-icons, geo/persistence helpers) and how to add a new feature
Feature roadmap Developer notes — planned / done / rejected features and the code-audit backlog

Upstream MeshCore

Document Description
FAQ Frequently asked questions
CLI Commands Commands for repeaters, room servers and sensors
Terminal Chat CLI Commands for the terminal chat client
Companion Protocol Serial/BLE frame protocol between device and app
Packet Format LoRa packet structure
QR Codes Channel and contact QR code formats

Solo Tools

All solo builds include screenshot and GPX trail export support out of the box — no special build flags required.

Web app — nothing to install

Open Solo Tools in a browser with Web Serial support (Chromium-based) and click Connect device:

  • Screenshot — capture the current display contents as a PNG. Triggered entirely from the browser; nothing to press on the device.
  • GPX export — stream the recorded GPS trail and download a timestamped .gpx file. Start it on the device with Tools Trail Hold Enter Export once connected.

Offline equivalents

The same two features are available as local scripts — tools/screenshot.py and tools/trail_export.py — plus a font converter. See tools/README.md.

Important

Both routes use USB serial, which is suspended while a BLE connection is active — disconnect the companion app from BLE first. If the app is connected over USB, disconnect it too: the raw export stream would otherwise disrupt its frame protocol. (Over BLE the export is safe, since USB receive is ignored.)


Development

This fork tracks the upstream MeshCore repository. To prevent upstream changes from overwriting this README during merges, README.md is protected via .gitattributes. After cloning, run once:

git config merge.ours.driver true

Building from source

Environment Device
WioTrackerL1_companion_solo_dual Wio Tracker L1 (OLED)
WioTrackerL1Eink_companion_solo_dual Wio Tracker L1 (E-ink)
GAT562_30S_Mesh_Kit_solo_dual GAT562 30S Mesh Kit
Heltec_v3_companion_solo_dual Heltec LoRa32 V3
heltec_v4_companion_solo_dual Heltec LoRa32 V4
pio run -e <env>                                  # build only
pio run -e <env> -t upload                        # build and flash over USB
FIRMWARE_VERSION=v1.0.0 bash build.sh build-firmware <env> # release artifacts into out/

The last command runs the same path CI does: a .uf2 + DFU .zip on nRF52, or an app-only .bin plus a -merged.bin on ESP32. Releases carry the .uf2, the .zip and the -merged.bin only.

Releasing

Pushing a v* tag runs Build Solo Firmwares, which discovers every *_solo_dual environment automatically, builds them all and opens a draft release with the artifacts attached. Write the notes from release-notes.md and publish it. See RELEASE.md for the upstream companion/repeater/room-server tags.

Repository layout

Path Contents
examples/companion_radio/ui-new/ the solo UI — screens, widgets, UITask
src/helpers/ui/ display drivers, fonts, buttons, buzzer
variants/<board>/ per-board platformio.ini, target.h, target.cpp
docs/solo_features/ user documentation for this fork
docs/design/, docs/development/ developer notes and the feature roadmap
tools/ host-side helpers (screenshot, GPX export, font conversion)

Contributing

Contributions are welcome. Fork the repository, make your changes, and open a pull request. Please follow the existing code style and keep changes focused.


Contributors

Big thanks to the people who contributed to this fork:

Built on upstream MeshCore and its community.

S
Description
Companion firmware fork — offline GPS navigation (waypoints, compass, GPX export) on top of LoRa mesh messaging.
Readme
14 MiB
Languages
C 60%
C++ 37.9%
Python 1.4%
Shell 0.3%
HTML 0.3%
Other 0.1%