Add a new command `region bulk` for defining region hierarchies in a single line. This command allows users to create multiple regions in a single message. Updated the documentation to include usage examples and detailed parameter descriptions.
some older ESP32 boards were pushing the limits of the dram segment causing the linker to fail, especially for ble and wifi firmwares.
lowering OFFLINE_QUEUE_SIZE reduces dram usage
This slipped through in PR #2327 and I noticed because the TechoBoard.h
for my variant doesn't include the Wire header, so the source file
in question does not coincidentally obtain a copy.
The `::init` method in the Adafruit ST7789 library is responsible to
initialize the device. This includes performing a reset, which can be
found in the Adafruit source for `Adafruit_SPITFT`.
Before this change, MeshCore performed its own ST7789 display reset
sequence, which consisted of three steps.
* Pull reset low
* Wait 10ms
* Pull reset high
Importantly, there was no fixed delay after pulling reset high. The
ST7789 driver requires a delay (T<sub>RT</sub>) of 5ms in Sleep In Mode
and 120ms in Sleep Out Mode before it will properly receive commands.
When `Adafruit_SPITFT` resets the device after MeshCore has already
reset it, the mandatory time may not have elapsed, leading to strange
behavior. In the author's case, this issue caused the initial
`fillScreen` to fail, such that the display showed an uninitialized
framebuffer.
This removes the MeshCore delay, leaving the responsibility of reset to
`Adafruit_SPITFT`, where they have the correct delays in place with
extra safety margin. The change was briefly tested by Josiah VanderZee
and Ben Zignego on a custom hardware build using an nRF52840 Dongle and
an Adafruit 4311 TFT display. The user button seemed to behave
strangely, but the display looked correct.
Adds a complete simulation harness for the MeshCore radio platform, including:
### ADAPTIVE routing strategy (sim/src/RoutingStrategies.h)
Hash-based relay gate selects a deterministic subset of nodes to forward each
flood, with relay percentage adapted to local neighbour density:
- SPARSE (<=4 neighbours): 100% relay -- no redundancy to spare
- MEDIUM (5-14): 25% relay
- DENSE (>=15): 15% relay
Selection uses hash(packet_seed XOR node_seed) with no coordination required.
Different packets select different subsets for stochastic load balancing.
Relay suppression: nodes cancel queued outbound TX if they overhear another
node already relaying the same flood (matched by packet hash).
### DensityEstimator (sim/src/DensityEstimator.h)
Passive sliding-window neighbour count from normal traffic -- no extra messages.
Only counts direct senders (hop_count==1) over a configurable window (default 60s).
Uses std::unordered_set for unique counting; no fixed-array cap.
### Adaptive TX power saving (sim/src/SimNode.h)
power_save_enabled reduces TX power in DENSE/MEDIUM tiers:
DENSE: configurable (default 10 dBm, saves 75% TX current vs 20 dBm)
MEDIUM: configurable (default 14 dBm, saves 60% TX current)
SPARSE: always full power -- every hop counts on marginal links
Validated: 100% delivery maintained at -10dBm DENSE reduction. Energy savings
~35% radio total. TX power reduction also lowers area RF noise floor.
### Scenario suite (sim/scenarios/)
scenario_adaptive: ADAPTIVE vs DEFAULT vs PATH_SNR_HYBRID comparison
scenario_concurrent: 2-8 simultaneous flood sources
scenario_longchain: 20-hop chains at marginal SNR
scenario_mixed: ADAPTIVE + legacy DEFAULT interoperability
scenario_dutycycle: EU 1% duty cycle enforcement validation
scenario_relay_pct_sweep: grid sweep to find optimal DENSE%/MEDIUM% operating point
scenario_txpower: TX power saving vs delivery rate vs energy trade-off
### Key empirical results
FM50 ADAPTIVE vs DEFAULT: equal delivery rate, -65% airtime, -70% collisions
CH20 (chain): ADAPTIVE = SPARSE throughout, identical to DEFAULT
TX power MODERATE (-10dB): 100% delivery, -35% energy across all topologies
Legacy interop: zero delivery regression with mixed firmware
### Bug fixes
- DensityEstimator: replace seen[64] array with unordered_set (was capping at 64 neighbours)
- SimBus::onTransmit: add len > 255 guard before memcpy into 255-byte buffer
- SimNode p_forward gate: >= -> > (was silently dropping relays at p_forward=1.0)
- SimNode TX power reset: remove redundant !power_save_enabled clause
- scenario_concurrent: fix stale ConcurrentResult* pointer after vector reallocation
- scenario_relay_pct_sweep: update TxCallback from 4-arg to 5-arg (tx_power_dbm)
- scenario_adaptive: remove unused variable last_suppressed
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
USE_LR1110 was missing from the preprocessor guard in CommonCLI.cpp,
causing both get and set to fail silently on T1000-E:
- get radio.rxgain returned the full radio config string (fell through
to the memcmp("radio", 5) branch)
- set radio.rxgain returned "unknown config" (no branch matched)
Fix: add -D USE_LR1110 to variants/t1000-e/platformio.ini and include
USE_LR1110 in the #if guard on both get and set branches.
CustomLR1110Wrapper already implements setRxBoostedGainMode() and
getRxBoostedGainMode() via the RadioLibWrapper virtual interface,
so no radio-layer changes are required.
Tested on T1000-E: get/set/persist all confirmed working.