mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-08-08 05:06:11 +00:00
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>
This commit is contained in:
@@ -10,14 +10,20 @@ Solo firmware thread: https://discord.com/channels/1495203904898728149/150529433
|
|||||||
|
|
||||||
## Supported Devices
|
## Supported Devices
|
||||||
|
|
||||||
| Device | Display | Firmware file |
|
| Device | MCU | Display | Firmware file |
|
||||||
| ------ | ------- | ------------- |
|
| ------ | --- | ------- | ------------- |
|
||||||
| Seeed Wio Tracker L1 (OLED) | SSD1306 / SH1106 128 × 64 | `solo-<version>-WioTrackerL1.uf2` |
|
| Seeed Wio Tracker L1 (OLED) | nRF52840 | SSD1306 / SH1106 128 × 64 | `solo-<version>-WioTrackerL1.uf2` |
|
||||||
| Seeed Wio Tracker L1 (E-ink) | GxEPD2 250 × 122 | `solo-<version>-WioTrackerL1Eink.uf2` |
|
| Seeed Wio Tracker L1 (E-ink) | nRF52840 | GxEPD2 250 × 122 | `solo-<version>-WioTrackerL1Eink.uf2` |
|
||||||
| GAT562 30S Mesh Kit | SSD1306 128 × 64 | `solo-<version>-GAT562-30S-Mesh-Kit.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](https://github.com/MarekZegare4/MeshCore-Solo/releases). Each binary supports both BLE and USB serial — there are no separate BLE/USB builds.
|
All firmware files are published on the [releases page](https://github.com/MarekZegare4/MeshCore-Solo/releases). 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](#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](#hardware-setup--heltec-v3--v4) before the solo UI can be driven.
|
||||||
|
|
||||||
<!-- **Enclosures (Wio Tracker L1)**
|
<!-- **Enclosures (Wio Tracker L1)**
|
||||||
- [E-ink case](https://www.printables.com/model/1420534-seeed-wio-tracker-l1-e-ink-enclosure)
|
- [E-ink case](https://www.printables.com/model/1420534-seeed-wio-tracker-l1-e-ink-enclosure)
|
||||||
- [OLED case](https://www.printables.com/model/1380791-meshpack-seeed-l1-oled) -->
|
- [OLED case](https://www.printables.com/model/1380791-meshpack-seeed-l1-oled) -->
|
||||||
@@ -26,7 +32,7 @@ All firmware files are published on the [releases page](https://github.com/Marek
|
|||||||
|
|
||||||
## Feature highlights
|
## Feature highlights
|
||||||
|
|
||||||
- Extended language support with native Unicode rendering and input ([Lemon font](https://github.com/cmvnd/fonts)) alongside the original ASCII mode (Default font with transliteration) — on-screen keyboard alphabets for Cyrillic, Greek, Polish, Czech, Slovak, German, French, Spanish, Portuguese and Nordic (Danish/Norwegian/Swedish), selectable in Settings › Keyboard › Alphabet
|
- 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
|
- Enabled sensor screens with support for onboard sensors (temperature, humidity, pressure, luminosity, CO₂) and GPS data
|
||||||
|
|
||||||
@@ -53,6 +59,8 @@ All firmware files are published on the [releases page](https://github.com/Marek
|
|||||||
|
|
||||||
- [Tools Screen](./docs/solo_features/tools_screen/tools_screen.md) — GPS trail & waypoints, compass, nearby nodes (with ping & navigate), ringtone editor, remote bot, auto-advert, live location sharing, locator, diagnostics, repeater, remote admin
|
- [Tools Screen](./docs/solo_features/tools_screen/tools_screen.md) — 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](./docs/solo_features/external_keyboard.md) — 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:
|
- **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
|
- **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
|
- **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
|
||||||
@@ -71,20 +79,62 @@ The e-ink variant targets the Wio Tracker L1 fitted with a 2.13″ GxEPD2 panel
|
|||||||
|
|
||||||
## Flashing
|
## Flashing
|
||||||
|
|
||||||
1. Download the `.uf2` file for your device from the [releases page](https://github.com/MarekZegare4/MeshCore-Solo/releases)
|
|
||||||
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
|
|
||||||
|
|
||||||
> [!IMPORTANT]
|
|
||||||
> BLE connection has priority over USB serial. When a BLE connection is active, the USB protocol is suspended. When connecting to the companion app via USB, ensure to disconnect from BLE first or disable BLE directly from the device to avoid confusion.
|
|
||||||
|
|
||||||
Updating to a newer version usually does not require erasing flash unless the release notes explicitly state otherwise.
|
|
||||||
|
|
||||||
> [!WARNING]
|
> [!WARNING]
|
||||||
> When migrating from official or other custom firmware, backup your data and **perform a factory reset** to prevent conflicts with existing settings:
|
> 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
|
> 1. Open device settings in the companion app and download a data backup
|
||||||
> 2. Go to [MeshCore Flasher](https://meshcore.io/flasher), select your device, and perform **Erase flash** before flashing
|
> 2. Go to [MeshCore Flasher](https://meshcore.io/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](https://github.com/MarekZegare4/MeshCore-Solo/releases)
|
||||||
|
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](https://meshcore.io/flasher)** or any Web Serial ESP tool — select the `-merged.bin` and flash at `0x0`
|
||||||
|
- **esptool** — `esptool.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`](./variants/heltec_v3/platformio.ini) and [`variants/heltec_v4/platformio.ini`](./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](./docs/solo_features/external_keyboard.md).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -100,7 +150,9 @@ Updating to a newer version usually does not require erasing flash unless the re
|
|||||||
| [Settings Screen](./docs/solo_features/settings_screen/settings_screen.md) | All settings sections with values and interactions |
|
| [Settings Screen](./docs/solo_features/settings_screen/settings_screen.md) | All settings sections with values and interactions |
|
||||||
| [Screen Lock](./docs/solo_features/screen_lock/screen_lock.md) | Lock/unlock sequence, lock screen, auto-lock |
|
| [Screen Lock](./docs/solo_features/screen_lock/screen_lock.md) | Lock/unlock sequence, lock screen, auto-lock |
|
||||||
| [Tools Screen](./docs/solo_features/tools_screen/tools_screen.md) | GPS trail & waypoints, compass, navigation, nearby nodes, ringtone editor, remote bot, auto-advert, live location sharing, locator, diagnostics, repeater, remote admin |
|
| [Tools Screen](./docs/solo_features/tools_screen/tools_screen.md) | GPS trail & waypoints, compass, navigation, nearby nodes, ringtone editor, remote bot, auto-advert, live location sharing, locator, diagnostics, repeater, remote admin |
|
||||||
|
| [External Keyboard & Joystick](./docs/solo_features/external_keyboard.md) | CardKB shortcuts, Full vs Compact mode, wired joystick, Heltec V3/V4 wiring |
|
||||||
| [Solo UI framework](./docs/design/solo_ui_framework.md) | **Developer guide** — the reusable building blocks (screens, lists, popups, mini-icons, geo/persistence helpers) and how to add a new feature |
|
| [Solo UI framework](./docs/design/solo_ui_framework.md) | **Developer guide** — the reusable building blocks (screens, lists, popups, mini-icons, geo/persistence helpers) and how to add a new feature |
|
||||||
|
| [Feature roadmap](./docs/development/roadmap.md) | **Developer notes** — planned / done / rejected features and the code-audit backlog |
|
||||||
|
|
||||||
### Upstream MeshCore
|
### Upstream MeshCore
|
||||||
|
|
||||||
@@ -119,18 +171,19 @@ Updating to a newer version usually does not require erasing flash unless the re
|
|||||||
|
|
||||||
All solo builds include screenshot and GPX trail export support out of the box — no special build flags required.
|
All solo builds include screenshot and GPX trail export support out of the box — no special build flags required.
|
||||||
|
|
||||||
### [Solo Tools Web App](https://marekzegare4.github.io/Solo-tools/) — no install required
|
### Web app — nothing to install
|
||||||
|
|
||||||
Open the link in a browser with Web Serial support (Chromium-based) and click **Connect device**. The web app supports:
|
Open [Solo Tools](https://marekzegare4.github.io/Solo-tools/) in a browser with Web Serial support (Chromium-based) and click **Connect device**:
|
||||||
|
|
||||||
- **Screenshot** — capture the current display contents as a PNG
|
- **Screenshot** — capture the current display contents as a PNG. Triggered entirely from the browser; nothing to press on the device.
|
||||||
- **GPX export** — stream the GPS trail and download a timestamped `.gpx` file
|
- **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.
|
||||||
|
|
||||||
Trigger the relevant action on the device (**Tools › Trail › Hold Enter** for GPX export, **S** key for screenshot) after connecting.
|
### Offline equivalents
|
||||||
|
|
||||||
> Disconnect from the companion app before connecting via USB — USB serial is suspended while a BLE connection is active.
|
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](./tools/README.md).
|
||||||
|
|
||||||
> If the companion app is connected over BLE the GPX export is safe (USB receive is ignored). If the app is on USB, disconnect it first — the raw stream will otherwise disrupt the app's frame protocol.
|
> [!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.)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -142,6 +195,39 @@ This fork tracks the upstream [MeshCore](https://github.com/meshcore-dev/MeshCor
|
|||||||
git config merge.ours.driver true
|
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 |
|
||||||
|
|
||||||
|
```sh
|
||||||
|
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](./.github/workflows/build-solo-firmwares.yml), 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](./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
|
### 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.
|
Contributions are welcome. Fork the repository, make your changes, and open a pull request. Please follow the existing code style and keep changes focused.
|
||||||
|
|||||||
@@ -0,0 +1,116 @@
|
|||||||
|
## External Keyboard & Joystick
|
||||||
|
|
||||||
|
[Go back](../../README.md)
|
||||||
|
|
||||||
|
Two optional hardware add-ons, both auto-detected and both entirely optional — a
|
||||||
|
build with them enabled runs exactly the same with nothing plugged in.
|
||||||
|
|
||||||
|
- **CardKB** — an M5Stack I2C QWERTY keyboard (address `0x5F`), for typing
|
||||||
|
messages, names and labels without walking the on-screen letter grid.
|
||||||
|
- **Wired joystick** — four direction contacts plus a Back button, replacing the
|
||||||
|
single-button navigation on boards that have no joystick of their own.
|
||||||
|
|
||||||
|
### Support by device
|
||||||
|
|
||||||
|
| Device | CardKB | Wired joystick |
|
||||||
|
| ------ | :----: | :------------: |
|
||||||
|
| Seeed Wio Tracker L1 (OLED) | ✅ Grove connector | onboard |
|
||||||
|
| Seeed Wio Tracker L1 (E-ink) | ✅ Grove connector | onboard |
|
||||||
|
| GAT562 30S Mesh Kit | — | onboard |
|
||||||
|
| Heltec V3 | ✅ solder to free GPIOs | ✅ solder to free GPIOs |
|
||||||
|
| Heltec V4 | ✅ solder to free GPIOs | ✅ solder to free GPIOs |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## CardKB
|
||||||
|
|
||||||
|
Plug it into the second I2C bus (the Grove connector on the Wio Tracker L1;
|
||||||
|
see [Wiring](#wiring-heltec-v3--v4) for the Heltec boards). The firmware probes
|
||||||
|
for it once at boot — nothing to enable in Settings.
|
||||||
|
|
||||||
|
The same bus is scanned for environment sensors, so a CardKB and a sensor can
|
||||||
|
share it.
|
||||||
|
|
||||||
|
### Typing
|
||||||
|
|
||||||
|
Printable characters insert straight at the cursor, bypassing the on-screen grid
|
||||||
|
completely. The alphabet and T9/ABC settings do not apply — a real keyboard sends
|
||||||
|
the right character already, so typing is always plain Latin ASCII regardless of
|
||||||
|
what Settings › Keyboard is set to.
|
||||||
|
|
||||||
|
| Key | Action |
|
||||||
|
| --- | ------ |
|
||||||
|
| letters / digits / symbols / space | insert at the cursor |
|
||||||
|
| Backspace | delete the character before the cursor |
|
||||||
|
| Esc | cancel / back |
|
||||||
|
| Arrows | same as the joystick |
|
||||||
|
| Enter | same as the centre button |
|
||||||
|
| **Fn+Enter** | **submit the field** — no need to find the DONE cell |
|
||||||
|
| **Fn+letter** | open the accent popup for that letter (e.g. Fn+A → á à ä ã…) |
|
||||||
|
| **Tab** | the Hold-Enter equivalent, everywhere — context menus, shift-lock, clear-all |
|
||||||
|
| **Fn+Esc** | lock / unlock the device (single press, works in both directions) |
|
||||||
|
|
||||||
|
Fn+Esc rather than the adjacent Fn+Backspace on purpose: Fn and Backspace sit
|
||||||
|
next to each other on CardKB's layout and would be far too easy to hit by
|
||||||
|
accident. See [Screen Lock](./screen_lock/screen_lock.md) for the physical
|
||||||
|
button equivalent.
|
||||||
|
|
||||||
|
### Ext. KB — Full vs Compact
|
||||||
|
|
||||||
|
**Settings › Keyboard › Ext. KB** picks how the on-screen keyboard behaves while
|
||||||
|
a CardKB is doing the typing.
|
||||||
|
|
||||||
|
| Mode | Behaviour |
|
||||||
|
| ---- | --------- |
|
||||||
|
| **Full** (default) | The letter grid stays on screen. Arrows and Enter drive the grid exactly as physical buttons do, so CardKB and the joystick can be used interchangeably. |
|
||||||
|
| **Compact** | The grid, the special-row icons and the status line are all hidden — only the text being typed and two shortcut hints remain. Arrows move the **text cursor** directly, and plain Enter submits the field (same as Fn+Enter). |
|
||||||
|
|
||||||
|
**Compact is designed to need no joystick at all**, which makes it the right
|
||||||
|
choice on a board where CardKB is the only input device — for example a Heltec
|
||||||
|
V3/V4 with no joystick soldered on. In that case set it once and forget it.
|
||||||
|
|
||||||
|
Cursor mode and the accent / placeholder popups draw their own visible feedback,
|
||||||
|
so they behave identically in both modes.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Wired joystick
|
||||||
|
|
||||||
|
Four direction contacts plus a separate Back button. Each contact simply shorts
|
||||||
|
its pin to ground — the firmware enables the internal pull-ups, so no external
|
||||||
|
resistors are needed.
|
||||||
|
|
||||||
|
- The board's existing user button (PRG on the Heltec boards) stays the
|
||||||
|
centre / Enter press.
|
||||||
|
- Back is **not** optional: the UI uses it unconditionally once the joystick is
|
||||||
|
enabled. Triple-clicking Back toggles the buzzer.
|
||||||
|
- **Settings › Display › Joystick rotation** rotates the direction mapping at
|
||||||
|
runtime (0–3), for a stick mounted sideways in a custom enclosure. It is
|
||||||
|
independent of display rotation.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Wiring (Heltec V3 / V4)
|
||||||
|
|
||||||
|
Neither board ships with a joystick or a keyboard header, so both are soldered to
|
||||||
|
free GPIOs. V3 and V4 are pin-compatible per Heltec's documentation and the solo
|
||||||
|
builds use the same assignment for both — **confirmed working on real V4
|
||||||
|
hardware**; still worth checking against your own V3 module before soldering.
|
||||||
|
|
||||||
|
| 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 when the joystick is enabled |
|
||||||
|
| Centre / Enter | 0 | the onboard PRG button — nothing to wire |
|
||||||
|
|
||||||
|
Everything above lives in the `[env:Heltec_v3_companion_solo_dual]` /
|
||||||
|
`[env:heltec_v4_companion_solo_dual]` blocks in
|
||||||
|
[`variants/heltec_v3/platformio.ini`](../../variants/heltec_v3/platformio.ini)
|
||||||
|
and [`variants/heltec_v4/platformio.ini`](../../variants/heltec_v4/platformio.ini),
|
||||||
|
with comments explaining which pins are safe to reuse. To build a CardKB-only
|
||||||
|
device, comment out the joystick block and set Ext. KB to Compact.
|
||||||
+77
-27
@@ -1,42 +1,92 @@
|
|||||||
#### Display Screenshot Tool
|
# Host-side tools
|
||||||
|
|
||||||
> **⚠️ Note:** The screenshot feature requires the `ENABLE_SCREENSHOT` build flag to be enabled. Add `-D ENABLE_SCREENSHOT` to your PlatformIO build flags, then recompile and flash the firmware.
|
Helper scripts that run on your computer, not on the device.
|
||||||
|
|
||||||
The firmware supports capturing the current display contents and transmitting
|
| Tool | Purpose |
|
||||||
it over USB serial. This is useful for debugging, remote monitoring, or
|
| ---- | ------- |
|
||||||
creating documentation.
|
| `screenshot.py` | capture the device display over USB serial and save it as a PNG |
|
||||||
|
| `trail_export.py` | capture a GPX track from the device over USB serial |
|
||||||
|
| `gpx-downloader/index.html` | the same GPX capture in a browser, via Web Serial |
|
||||||
|
| `bdf2gfx.py` | convert a BDF bitmap font to an Adafruit-GFX header |
|
||||||
|
|
||||||
**Important:** When the device is connected to the companion app, the USB
|
Python dependencies are managed with [uv](https://docs.astral.sh/uv/) — run the
|
||||||
serial port is not available for communication. To use the screenshot tool,
|
scripts with `uv run tools/<script>.py` from the repository root.
|
||||||
ensure the device is not connected to the companion app.
|
|
||||||
|
> [!TIP]
|
||||||
|
> The hosted [Solo Tools Web App](https://marekzegare4.github.io/Solo-tools/)
|
||||||
|
> does both screenshots and GPX export with nothing to install, and is the
|
||||||
|
> easiest option for most people. The scripts here are the offline equivalents.
|
||||||
|
|
||||||
|
> [!IMPORTANT]
|
||||||
|
> USB serial is suspended while a BLE connection is active, so disconnect the
|
||||||
|
> companion app from BLE before using any of these. If the app is connected over
|
||||||
|
> USB, disconnect it too — the raw stream would otherwise disrupt its frame
|
||||||
|
> protocol.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Display screenshot
|
||||||
|
|
||||||
|
All solo firmware environments are built with `-D ENABLE_SCREENSHOT`, so no
|
||||||
|
special build is needed. On other environments (repeater, room server, the
|
||||||
|
non-solo companion builds) add the flag yourself:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
PLATFORMIO_BUILD_FLAGS="-D ENABLE_SCREENSHOT" pio run -e <env> -t upload
|
||||||
|
```
|
||||||
|
|
||||||
**Usage:**
|
**Usage:**
|
||||||
|
|
||||||
1. Build and flash firmware with `-D ENABLE_SCREENSHOT` build flag enabled
|
1. Connect the device over USB, with no companion app attached
|
||||||
|
2. Run the tool:
|
||||||
Example for the OLED dual firmware:
|
|
||||||
|
|
||||||
```
|
|
||||||
PLATFORMIO_BUILD_FLAGS="-D ENABLE_SCREENSHOT" pio run -e WioTrackerL1_companion_dual -t upload
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Connect the device to your computer via USB (ensure no companion app connection)
|
|
||||||
3. Install dependencies and run the screenshot tool. To manage python and python dependencies, use uv: https://docs.astral.sh/uv/
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
cd tools
|
|
||||||
uv run tools/screenshot.py
|
uv run tools/screenshot.py
|
||||||
```
|
```
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
- `--port PORT` — Serial port to use (default: auto-detect)
|
- `--port PORT` — serial port to use (default: auto-detect)
|
||||||
- `--scale SCALE` — Upscale factor for the output image (1=no upscale, 2=2x, 3=3x, 4=4x, etc.; default: 1)
|
- `--scale SCALE` — upscale factor for the output image (1 = none; default: 1)
|
||||||
|
|
||||||
4. In the tool's interactive menu, press **S** to capture a screenshot
|
3. Press **S** in the tool's interactive menu to capture
|
||||||
5. The tool will save the screenshot as a PNG file in `tools/pngs/` with a timestamp-based filename
|
4. The PNG lands in `tools/pngs/` with a timestamped filename
|
||||||
|
|
||||||
**How it works:**
|
**How it works:**
|
||||||
- The tool sends the `CMD_GET_SCREENSHOT` command (66) to the device
|
|
||||||
- The device responds with `RESP_CODE_SCREENSHOT` (29) containing the framebuffer data
|
- The tool sends `CMD_GET_SCREENSHOT` (66) to the device
|
||||||
- The framebuffer is transmitted in chunks (128×64 display = 1024 bytes, split across multiple frames)
|
- The device replies with `RESP_CODE_SCREENSHOT` (29) carrying the framebuffer
|
||||||
- The tool reassembles the chunks and converts them to a PNG image
|
- The framebuffer arrives in chunks (a 128 × 64 display is 1024 bytes, split
|
||||||
|
across several frames), which the tool reassembles into a PNG
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## GPX trail export
|
||||||
|
|
||||||
|
1. Connect the device over USB, with no companion app attached
|
||||||
|
2. Start the listener:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
uv run tools/trail_export.py
|
||||||
|
```
|
||||||
|
|
||||||
|
Options:
|
||||||
|
- `--port PORT` — serial port to use (default: auto-detect)
|
||||||
|
- `--out OUT` — output file (default: a timestamped file in `tools/gpx/`)
|
||||||
|
|
||||||
|
3. On the device: **Tools › Trail › Hold Enter › Export (live)** or
|
||||||
|
**Export (saved)**
|
||||||
|
4. The script captures the GPX 1.1 XML stream and writes it to disk
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Font conversion
|
||||||
|
|
||||||
|
```sh
|
||||||
|
uv run tools/bdf2gfx.py <font.bdf> <first_hex> <last_hex> <VarPrefix> > out.h
|
||||||
|
```
|
||||||
|
|
||||||
|
Emits a contiguous glyph table over the given codepoint range, with empty
|
||||||
|
placeholders for codepoints the BDF does not define, so the renderer can index
|
||||||
|
by `cp - first`. This is how [`src/helpers/ui/MiscFixedFont.h`](../src/helpers/ui/MiscFixedFont.h)
|
||||||
|
— the unified 6×9 Latin/Greek/Cyrillic display font — was generated from
|
||||||
|
`6x9.bdf`.
|
||||||
|
|||||||
Reference in New Issue
Block a user