Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,6 @@
[submodule "firmware/rcc6-headless-companion"]
path = firmware/rcc6-headless-companion
url = https://github.com/n30nex/NeonPocketMC-RCC6-Headless.git
[submodule "firmware/ulp-solar-repeaters"]
path = firmware/ulp-solar-repeaters
url = https://github.com/n30nex/NeonPocketMC-ULP-Solar-Repeaters.git
12 changes: 12 additions & 0 deletions FLASHING.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,18 @@ python -m esptool --chip esp32c6 --port COM21 write-flash 0x0 <recovery-image.bi

Do not run a full-chip erase. Recovery resets NVS-backed BLE bonds and saved Wi-Fi but does not reach the SPIFFS data partition at `0xC90000`.

## ULP Solar Repeaters

Use the dedicated [ULP release](https://github.com/n30nex/NeonPocketMC-ULP-Solar-Repeaters/releases/tag/v1.0.0-rc.1) and choose the exact V3, V4, RAK4631, RAK3401 1 W, Xiao ESP32-S3, Xiao nRF52840, RCC6, or RC52 image. RCC6 and RC52 have separate headless and TFT files.

- ESP32 normal install: flash the matching `*-app.bin` at `0x10000`.
- nRF52 normal install: enter the board bootloader and copy the matching `.uf2` without erasing or replacing its SoftDevice/bootloader.
- Keep USB connected after restart and run `NeonPocketMC-ULP-Configurator.zip` to set the name, radio preset/region, transmit power, admin password, and power profile.
- New installs default to `ulp on` (balanced receive duty cycle). Existing saved settings remain authoritative; use `ulp on` once when upgrading an older repeater that had power saving disabled.
- RX duty cycling can miss packets. Validate coverage and current draw before a remote deployment.

None of these boards provides a universal raw-solar input. Use a protected battery and external MPPT/charge controller matched to the panel and cell; never wire an unregulated panel directly to VBAT or USB.

## Troubleshooting

For a blank screen, boot loop, or storage error, capture a 115200-baud log and report:
Expand Down
16 changes: 13 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,14 @@ These frames were captured from the OLED framebuffer running on the physical Hel

Capture provenance and checksums are recorded with each device gallery under [`docs/images`](docs/images).

## ULP Solar Repeaters

[NeonPocketMC ULP Solar Repeaters](https://github.com/n30nex/NeonPocketMC-ULP-Solar-Repeaters) are experimental MeshCore 1.17.1 builds for Heltec V3/V4, RAK4631, RAK3401 1 W, Xiao ESP32-S3, Xiao nRF52840, RCC6, and RC52. RCC6 and RC52 each have separate headless and 220×128 TFT images.

Power saving is **ON by default** on new installs. The recommended balanced profile combines MCU sleep with SX1262 receive duty cycling; the simple USB configurator handles name, radio preset, transmit power, admin password, and the ULP level before deployment. This work is based on and fully attributes [IoTThinks' EasySkyMesh power-saving implementation](https://github.com/IoTThinks/EasySkyMesh/releases/tag/PowerSaving17.1).

> RX duty cycling trades receive availability for energy savings and can miss packets. Solar deployments still require a protected battery and an external MPPT/charge controller matched to the panel and cell—never connect a raw panel directly to VBAT or USB.

## Current builds

Each product release is pinned to an exact source commit and artifact checksum in [`catalog.json`](catalog.json). Board-specific bootloaders, partitions, displays, and radio power paths remain separate.
Expand All @@ -151,6 +159,7 @@ Each product release is pinned to an exact source commit and artifact checksum i
| RCC6 without TFT | Screenless BLE, native-USB, or Wi-Fi Web/TCP companion | [v1.0.0-rc.1](https://github.com/n30nex/NeonPocketMC-RCC6-Headless/releases/tag/v1.0.0-rc.1) | Flash the selected app `.bin` at `0x10000` |
| RCC6 | Ultimate MQTT observer/repeater with setup WebUI | [v1.3.0-rc.1](https://github.com/n30nex/NeonPocketMC-RCC6-Repeater/releases/tag/v1.3.0-rc.1) | Flash the observer app at `0x10000`, then run the configurator |
| RCC6, TFT optional | Ultimate minimal or full Room Server | [v1.3.0-rc.1](https://github.com/n30nex/NeonPocketMC-RCC6-Repeater/releases/tag/v1.3.0-rc.1) | Pick minimal/full and headless/TFT, then flash its app at `0x10000` |
| V3, V4, RAK4631, RAK3401 1 W, Xiao ESP32-S3/nRF52840, RCC6, RC52 | Experimental ULP Solar Repeater; RCC6/RC52 headless or TFT | [v1.0.0-rc.1](https://github.com/n30nex/NeonPocketMC-ULP-Solar-Repeaters/releases/tag/v1.0.0-rc.1) | Pick the exact board image; use app-only `.bin` at `0x10000` or matching nRF52 `.uf2` |
| SenseCAP Indicator D1L | DeskOS touch companion with repeater and room management | [v1.7.9](https://github.com/n30nex/DeskOS-MeshCore/releases/tag/v1.7.9) | Existing DeskOS: app at `0x20000`; fresh install: full 8 MB image at `0x0` |

The RCC6 Web companion and networked service builds now use human-first dashboards with traffic bars, delivery and signal analytics, nearby-radio freshness, and coordinate-backed maps that never invent node locations. The MQTT observer/repeater defaults to **3-byte packet hash mode**. Its Windows/Linux configurator covers node name, radio preset and custom radio values, Wi-Fi, MQTT broker selection, and post-setup IP discovery. The preferred public brokers are `mqtt1.meshcore.ca` and `mqtt2.meshcore.ca`; the other upstream-compatible brokers remain selectable/configurable.
Expand All @@ -163,7 +172,7 @@ Exact install filenames, sizes, SHA-256 values, release links, and source commit

## Source layout

The nine firmware histories intentionally remain separate because they target different chips, bootloaders, transports, displays, and deployment roles. This repository indexes them as pinned Git submodules:
The ten firmware histories intentionally remain separate because they target different chips, bootloaders, transports, displays, and deployment roles. This repository indexes them as pinned Git submodules:

```text
firmware/
Expand All @@ -175,6 +184,7 @@ firmware/
rcc6-companion/
rcc6-headless-companion/
rcc6-mqtt-repeater/
ulp-solar-repeaters/
deskos-meshcore/
```

Expand All @@ -198,7 +208,7 @@ git submodule update --init --recursive
- **SenseCAP Indicator D1L:** use the DeskOS update image at `0x20000` on an existing install. The full 8 MB image at `0x0` is destructive and only for a fresh or unrecoverable device. The RP2040 SD bridge uses a separate UF2/BOOTSEL step; neither path formats the SD card.
- RCC6 merged recovery images stop well before SPIFFS and preserve MeshCore identity, contacts, channels, and preferences; they reset NVS-backed BLE bonds and saved Wi-Fi.
- The RC52 and RCC6 boards do **not** contain an MPPT controller suitable for an unregulated solar panel. Outdoor solar installs need an external regulator/charger matched to the panel and protected 1-cell battery.
- These are community prereleases, not official Heltec or MeshCore firmware.
- ULP Solar Repeaters are community builds based on IoTThinks EasySkyMesh power-saving work; they are not official IoTThinks, Heltec, RAKwireless, Seeed Studio, or MeshCore firmware.

See [`FLASHING.md`](FLASHING.md) for practical install and recovery instructions.

Expand All @@ -208,4 +218,4 @@ Room Server profiles, animated companion startup, RCC6 Diagnostics, and one-butt

[`scripts/verify_catalog.py`](scripts/verify_catalog.py) confirms each Git submodule pin, release URL, digest, and catalog invariant. Product repositories retain their own exact-target build workflows and hardware-specific release evidence.

Root documentation and catalog code are MIT licensed. Each of the nine firmware submodules retains its own upstream and third-party licenses.
Root documentation and catalog code are MIT licensed. Each of the ten firmware submodules retains its own upstream and third-party licenses.
38 changes: 37 additions & 1 deletion catalog.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"schema": 1,
"suite_version": "1.8.0-rc.1",
"suite_version": "1.9.0-rc.1",
"products": [
{
"id": "heltec-v3-companion",
Expand Down Expand Up @@ -152,6 +152,42 @@
{"name": "NeonPocketMC-RCC6-Ultimate-Server-v1.3.0-rc.1-configurator.zip", "size": 17855, "sha256": "8d7136d2fbfd7e51ad5da085deef60c0dc0257ea8a973f6d04d556c2bac82a4f", "url": "https://github.com/n30nex/NeonPocketMC-RCC6-Repeater/releases/download/v1.3.0-rc.1/NeonPocketMC-RCC6-Ultimate-Server-v1.3.0-rc.1-configurator.zip"}
]
},
{
"id": "ulp-solar-repeaters",
"hardware": "Heltec V3/V4, RAK4631, RAK3401 1W, Xiao ESP32-S3/nRF52840, RCC6, and RC52",
"role": "Ultra-low-power solar/battery MeshCore repeaters with default-on EasySkyMesh power saving",
"repository": "https://github.com/n30nex/NeonPocketMC-ULP-Solar-Repeaters",
"release": "https://github.com/n30nex/NeonPocketMC-ULP-Solar-Repeaters/releases/tag/v1.0.0-rc.1",
"tag": "v1.0.0-rc.1",
"commit": "f05eff932e52236d35b68e0646850458e3785f97",
"submodule": "firmware/ulp-solar-repeaters",
"profiles": ["heltec-v3", "heltec-v4", "rak4631", "rak3401-1w", "xiao-esp32s3", "xiao-nrf52840", "rcc6-headless", "rcc6-tft", "rc52-headless", "rc52-tft"],
"defaults": {"power_saving": true, "profile": "balanced", "radio_rxps_level": 5, "preamble": 16},
"attribution": "IoTThinks EasySkyMesh PowerSaving-v17",
"artifacts": [
{"name": "NeonPocketMC-ULP-Heltec-V3-v1.0.0-rc.1-app.bin", "size": 1190656, "sha256": "3376b69596327739514aed7594ddb6d53a8a5dd853623ce257e41e359182557e", "url": "https://github.com/n30nex/NeonPocketMC-ULP-Solar-Repeaters/releases/download/v1.0.0-rc.1/NeonPocketMC-ULP-Heltec-V3-v1.0.0-rc.1-app.bin"},
{"name": "NeonPocketMC-ULP-Heltec-V3-v1.0.0-rc.1-full-recovery.bin", "size": 1256192, "sha256": "6753b4742d063fecce7af1855c6a8c04943333b7ec5dc82dcf7671be824b0b62", "url": "https://github.com/n30nex/NeonPocketMC-ULP-Solar-Repeaters/releases/download/v1.0.0-rc.1/NeonPocketMC-ULP-Heltec-V3-v1.0.0-rc.1-full-recovery.bin"},
{"name": "NeonPocketMC-ULP-Heltec-V4-v1.0.0-rc.1-app.bin", "size": 1188336, "sha256": "07b0be8959ae39754a3f0922eede8ff0459939d08f80de7690fe0ff6ced08fc4", "url": "https://github.com/n30nex/NeonPocketMC-ULP-Solar-Repeaters/releases/download/v1.0.0-rc.1/NeonPocketMC-ULP-Heltec-V4-v1.0.0-rc.1-app.bin"},
{"name": "NeonPocketMC-ULP-Heltec-V4-v1.0.0-rc.1-full-recovery.bin", "size": 1253872, "sha256": "ec24e54630ca99bccc982322db6c34a9da500a62bcdf256fb0ee050a4f9f341a", "url": "https://github.com/n30nex/NeonPocketMC-ULP-Solar-Repeaters/releases/download/v1.0.0-rc.1/NeonPocketMC-ULP-Heltec-V4-v1.0.0-rc.1-full-recovery.bin"},
{"name": "NeonPocketMC-ULP-RAK3401-1W-v1.0.0-rc.1.hex", "size": 1402870, "sha256": "954a45207d97e167c5428417069a9e28cd12bec930392a61732719dd2464b5d4", "url": "https://github.com/n30nex/NeonPocketMC-ULP-Solar-Repeaters/releases/download/v1.0.0-rc.1/NeonPocketMC-ULP-RAK3401-1W-v1.0.0-rc.1.hex"},
{"name": "NeonPocketMC-ULP-RAK3401-1W-v1.0.0-rc.1.uf2", "size": 997888, "sha256": "082c214ffaadc4e0e50a76d21347bf1968eeefa8b4706fcb361ddaa7ff466548", "url": "https://github.com/n30nex/NeonPocketMC-ULP-Solar-Repeaters/releases/download/v1.0.0-rc.1/NeonPocketMC-ULP-RAK3401-1W-v1.0.0-rc.1.uf2"},
{"name": "NeonPocketMC-ULP-RAK4631-v1.0.0-rc.1.hex", "size": 1490367, "sha256": "94b5f57fdc3d6f849c25cf5d87a9bef8ee7ddf5006da9adeed1c1d50bdf11746", "url": "https://github.com/n30nex/NeonPocketMC-ULP-Solar-Repeaters/releases/download/v1.0.0-rc.1/NeonPocketMC-ULP-RAK4631-v1.0.0-rc.1.hex"},
{"name": "NeonPocketMC-ULP-RAK4631-v1.0.0-rc.1.uf2", "size": 1059840, "sha256": "9c76de3ea3441fec0b887bc3ee7bb99e9faae0d755a1e0b9290e6663b466f1db", "url": "https://github.com/n30nex/NeonPocketMC-ULP-Solar-Repeaters/releases/download/v1.0.0-rc.1/NeonPocketMC-ULP-RAK4631-v1.0.0-rc.1.uf2"},
{"name": "NeonPocketMC-ULP-RC52-Headless-v1.0.0-rc.1.hex", "size": 1097888, "sha256": "ae39eb8548f91e45ecda7679129eb2cdb0e1591f77f84d0f63c7020af79f9f7c", "url": "https://github.com/n30nex/NeonPocketMC-ULP-Solar-Repeaters/releases/download/v1.0.0-rc.1/NeonPocketMC-ULP-RC52-Headless-v1.0.0-rc.1.hex"},
{"name": "NeonPocketMC-ULP-RC52-Headless-v1.0.0-rc.1.uf2", "size": 780800, "sha256": "bfbf2a900aac5444429a231d8abbabd717f1c43bf9d6da21d3b8f73539f8d8ed", "url": "https://github.com/n30nex/NeonPocketMC-ULP-Solar-Repeaters/releases/download/v1.0.0-rc.1/NeonPocketMC-ULP-RC52-Headless-v1.0.0-rc.1.uf2"},
{"name": "NeonPocketMC-ULP-RC52-TFT-v1.0.0-rc.1.hex", "size": 1155443, "sha256": "05ab9823fea0d2051e36ecd4a96a6270b60c3b159195159fe611df3a4e26fe19", "url": "https://github.com/n30nex/NeonPocketMC-ULP-Solar-Repeaters/releases/download/v1.0.0-rc.1/NeonPocketMC-ULP-RC52-TFT-v1.0.0-rc.1.hex"},
{"name": "NeonPocketMC-ULP-RC52-TFT-v1.0.0-rc.1.uf2", "size": 821760, "sha256": "7ed010f2c05299a133ead72ebed234da985b5edd040d714f183305e22366ad58", "url": "https://github.com/n30nex/NeonPocketMC-ULP-Solar-Repeaters/releases/download/v1.0.0-rc.1/NeonPocketMC-ULP-RC52-TFT-v1.0.0-rc.1.uf2"},
{"name": "NeonPocketMC-ULP-RCC6-Headless-v1.0.0-rc.1-app.bin", "size": 573744, "sha256": "120ca0a36cfe68360ccff7c20aa299f8256a6d4b091ac95ea590c7ea21dccb34", "url": "https://github.com/n30nex/NeonPocketMC-ULP-Solar-Repeaters/releases/download/v1.0.0-rc.1/NeonPocketMC-ULP-RCC6-Headless-v1.0.0-rc.1-app.bin"},
{"name": "NeonPocketMC-ULP-RCC6-Headless-v1.0.0-rc.1-full-recovery.bin", "size": 639280, "sha256": "d70b778462ed8cf7856c8a0b5f05664fbac18e75eed12d4d3be85830a421b7ec", "url": "https://github.com/n30nex/NeonPocketMC-ULP-Solar-Repeaters/releases/download/v1.0.0-rc.1/NeonPocketMC-ULP-RCC6-Headless-v1.0.0-rc.1-full-recovery.bin"},
{"name": "NeonPocketMC-ULP-RCC6-TFT-v1.0.0-rc.1-app.bin", "size": 585008, "sha256": "c322b23a2b4b5bf9fffb66d9577a0a9a1028dbbc709630deaf5d416ea9fa0662", "url": "https://github.com/n30nex/NeonPocketMC-ULP-Solar-Repeaters/releases/download/v1.0.0-rc.1/NeonPocketMC-ULP-RCC6-TFT-v1.0.0-rc.1-app.bin"},
{"name": "NeonPocketMC-ULP-RCC6-TFT-v1.0.0-rc.1-full-recovery.bin", "size": 650544, "sha256": "32138e1e59925d342334fc61ade0ba0136be131d590add52f054bf7a900e7e44", "url": "https://github.com/n30nex/NeonPocketMC-ULP-Solar-Repeaters/releases/download/v1.0.0-rc.1/NeonPocketMC-ULP-RCC6-TFT-v1.0.0-rc.1-full-recovery.bin"},
{"name": "NeonPocketMC-ULP-Xiao-ESP32S3-v1.0.0-rc.1-app.bin", "size": 1152848, "sha256": "8471587433a4d0b32a636f8581c2ac6dfe8e731c8aeb91df72ba265a5c7cd672", "url": "https://github.com/n30nex/NeonPocketMC-ULP-Solar-Repeaters/releases/download/v1.0.0-rc.1/NeonPocketMC-ULP-Xiao-ESP32S3-v1.0.0-rc.1-app.bin"},
{"name": "NeonPocketMC-ULP-Xiao-ESP32S3-v1.0.0-rc.1-full-recovery.bin", "size": 1218384, "sha256": "3a17449ba06eade06fe5ef342203b8e92e277060709602c52a5cd4bbdda09792", "url": "https://github.com/n30nex/NeonPocketMC-ULP-Solar-Repeaters/releases/download/v1.0.0-rc.1/NeonPocketMC-ULP-Xiao-ESP32S3-v1.0.0-rc.1-full-recovery.bin"},
{"name": "NeonPocketMC-ULP-Xiao-nRF52840-v1.0.0-rc.1.hex", "size": 1253822, "sha256": "8c5651427e83a3e7af755ee1a1f6eaae566d670ed58b41db01a6e945ff4c02ed", "url": "https://github.com/n30nex/NeonPocketMC-ULP-Solar-Repeaters/releases/download/v1.0.0-rc.1/NeonPocketMC-ULP-Xiao-nRF52840-v1.0.0-rc.1.hex"},
{"name": "NeonPocketMC-ULP-Xiao-nRF52840-v1.0.0-rc.1.uf2", "size": 891904, "sha256": "4ff83da99e874fb7e4cd086df5b75e34d6e6f6b521f98f397e4b1491cec78f35", "url": "https://github.com/n30nex/NeonPocketMC-ULP-Solar-Repeaters/releases/download/v1.0.0-rc.1/NeonPocketMC-ULP-Xiao-nRF52840-v1.0.0-rc.1.uf2"},
{"name": "NeonPocketMC-ULP-Configurator.zip", "size": 3638, "sha256": "cd29e4c207c10f9be33654004dd5dded5a0d8a7924783a752fa46e4a4e01ed5d", "url": "https://github.com/n30nex/NeonPocketMC-ULP-Solar-Repeaters/releases/download/v1.0.0-rc.1/NeonPocketMC-ULP-Configurator.zip"}
]
},
{
"id": "deskos-d1l-client",
"hardware": "Seeed SenseCAP Indicator D1L with 480x480 touch display",
Expand Down
1 change: 1 addition & 0 deletions firmware/ulp-solar-repeaters
Submodule ulp-solar-repeaters added at f05eff
2 changes: 1 addition & 1 deletion scripts/verify_catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def main() -> None:
data = json.loads(CATALOG.read_text(encoding="utf-8"))
assert data["schema"] == 1
products = data["products"]
assert len(products) == 9
assert len(products) == 10
ids: set[str] = set()
names: set[str] = set()

Expand Down
Loading