Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen Revision Vorhergehende Überarbeitung
mc_rxdelay_calc [2026/05/31 12:21] bmke-a-2345-tdeckmc_rxdelay_calc [2026/05/31 12:22] (aktuell) – gelöscht bmke-a-2345-tdeck
Zeile 1: Zeile 1:
-====== MeshCore RX Delay Calculator ====== 
- 
-===== What is RX Delay? ===== 
- 
-**RX Delay** (''rxdelay'' / ''rx_delay_base'') is a MeshCore repeater setting that **delays processing of flood-routed packets** based on how good the received signal is (the **packet score**). 
- 
-**Purpose:** MeshCore uses "first packet wins" for route discovery. Without RX delay, a repeater might forward a packet from a **weak, distant hop** before a **stronger, better path** arrives. RX delay gives better signals a head start by holding weaker copies longer in an internal queue. 
- 
-**Only affects flood routes.** Direct-route packets are processed immediately. 
- 
-**Default:** ''rxdelay = 0'' (disabled). Recommended minimum for repeaters is often **2** or higher, depending on neighbor density. 
- 
-**Limits (firmware):** 
- 
-   * Delay **< 50 ms**  → packet processed **immediately**  (no queue) 
-  * Delay **> 32 000 ms**  → capped at 32 seconds 
-  * ''rxdelay''  CLI range: **0 … 20**  (0 = off) 
-Sources: [[https://github.com/meshcore-dev/MeshCore/blob/main/examples/simple_repeater/MyMesh.cpp|MyMesh.cpp]], [[https://github.com/meshcore-dev/MeshCore/issues/2064|Issue #2064]], [[https://github.com/meshcore-dev/MeshCore/issues/2123|Issue #2123]] 
- 
-===== The Formula ===== 
- 
-<code javascript> 
-/** 
- * MeshCore RX delay (milliseconds) 
- * 
- * @param {number} rxDelayBase  - CLI value "rxdelay" (0 = disabled, typical 2–10) 
- * @param {number} score        - packet score 0.0 … 1.0 (from SNR + packet length) 
- * @param {number} airtimeMs    - estimated on-air time of the packet in ms 
- * @returns {number} delay in ms (can be negative → treated as immediate) 
- */ 
-function calcRxDelay(rxDelayBase, score, airtimeMs) { 
-  if (rxDelayBase <= 0) return 0; 
-  return (Math.pow(rxDelayBase, 0.85 - score) - 1) * airtimeMs; 
-} 
- 
-</code> 
- 
-**Excel equivalent**  (same formula as in your spreadsheet): 
-<code> 
- 
-=(rx_delay_base ^ (0.85 - score) - 1) * airtime 
- 
-</code> 
- 
-Your spreadsheet uses **airtime = 150 ms**  as a fixed example. In firmware, ''airtime''  comes from ''getEstAirtimeFor(packet_length)''  and depends on SF, bandwidth, and payload size. 
- 
-===== Packet Score (0.0 – 1.0) ===== 
- 
-The **score**  is //not//  raw SNR. It is computed in ''packetScoreInt()''  from SNR, spreading factor, and packet length: 
- 
-<code> 
-score = clamp(0, 1, ((SNR - SNR_threshold[SF]) / 10) * (1 - packet_len / 256)) 
- 
-</code> 
- 
-**Interpretation:** 
- 
-  * **score = 1.0**  → excellent signal, well above decoding threshold, short packet 
-  * **score = 0.5**  → moderate margin above threshold 
-  * **score = 0.0**  → at or below SNR threshold (should not decode reliably) 
-SNR thresholds per SF (approx.): SF7 −7.5 dB, SF8 −10, SF9 −12.5, SF10 −15, SF11 −17.5, SF12 −20. 
- 
-**Example:**  SF10, SNR = −5 dB, 64-byte packet → score ≈ ((−5 − (−15))  / 10) × (1 − 64/256) = **0.75** 
- 
-===== Reading the Table ===== 
- 
-Your Excel sheet layout: 
- 
-^rx_delay_base  score^0.1^0.2^0.3^0.4^0.5^0.6^0.7^0.8^0.9^1.0| 
-|**1** |0|0|0|0|0|0|0|0|0|0| 
-|**2** |102|85|70|55|41|28|16|5|−5|−15| 
-|…|…|…|…|…|…|…|…|…|…|…| 
- 
-  * **Rows**  = ''rx_delay_base''  (1 … 19 in your sheet; CLI allows up to 20) 
-  * **Columns**  = packet **score**  (0.1 … 1.0) 
-  * **Cells**  = delay in **milliseconds**  (for airtime = 150 ms) 
-**Key behaviors:** 
- 
-  * ''rx_delay_base = 1''  → always **0 ms**  delay (feature effectively off) 
-  * ''rx_delay_base'' **between 0 and 1**  → **inverted**  behavior: weak signals delayed //less//  than strong ones (avoid!) 
-  * Higher ''rx_delay_base''  → longer delays overall → stronger collision/backoff spreading 
-  * Higher **score**  (better signal) → **shorter**  delay → better paths propagate first 
- 
-===== Interactive Calculator ===== 
- 
-Paste the block below into a DokuWiki page. Requires **HTML embed**  enabled (''htmlok''  in config, or the htmlok plugin). Wrap in ''<html>…</html>''  if your wiki needs it. 
- 
-<html> <style> 
-<code> 
- 
-#mc-rxdelay { font-family: sans-serif; max-width: 960px; } 
-#mc-rxdelay table { border-collapse: collapse; width: 100%; font-size: 13px; } 
-#mc-rxdelay th, #mc-rxdelay td { border: 1px solid #ccc; padding: 4px 6px; text-align: right; } 
-#mc-rxdelay th { background: #eef; position: sticky; top: 0; } 
-#mc-rxdelay td.row-hdr { background: #f5f5f5; font-weight: bold; text-align: center; } 
-#mc-rxdelay .neg { color: #888; } 
-#mc-rxdelay .imm { background: #e8f5e9; } 
-#mc-rxdelay .queued { background: #fff8e1; } 
-#mc-rxdelay .controls { margin: 12px 0; display: flex; flex-wrap: wrap; gap: 16px; align-items: center; } 
-#mc-rxdelay .controls label { display: flex; align-items: center; gap: 6px; } 
-#mc-rxdelay .result-box { background: #f0f7ff; border: 1px solid #9cf; padding: 10px; margin: 12px 0; border-radius: 4px; } 
- 
-</code> 
- 
-</style> 
- 
-<div id="mc-rxdelay"> 
- 
-<code> 
-<div class="controls"> 
-  <label>Airtime (ms): <input type="number" id="mc-airtime" value="150" min="1" max="5000" step="1"></label> 
-  <label>Highlight rx_delay_base: <input type="number" id="mc-highlight-rx" value="2" min="0" max="20" step="0.1"></label> 
-  <label>Highlight score: <input type="number" id="mc-highlight-score" value="0.5" min="0" max="1" step="0.05"></label> 
-  <button type="button" onclick="mcRxDelayUpdate()">Recalculate</button> 
-</div> 
- 
-</code> 
- 
-<code> 
-<div class="result-box" id="mc-single-result"></div> 
- 
-</code> 
- 
-<code> 
-<div style="overflow-x:auto; max-height: 480px; overflow-y: auto;"> 
-  <table id="mc-rxdelay-table"> 
-    <thead></thead> 
-    <tbody></tbody> 
-  </table> 
-</div> 
- 
-</code> 
- 
-<code> 
-<p style="font-size:12px;color:#666;margin-top:8px;"> 
-  Green = <50 ms (processed immediately) · Yellow = queued · Grey italic = negative (also immediate) 
-</p> 
- 
-</code> 
- 
-</div> 
- 
-<script type="text/javascript"> /* MeshCore RX delay – matches Excel "rxdelay calc.xlsx" and firmware MyMesh::calcRxDelay */ 
- 
-var MC_RX_SCORES = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]; var MC_RX_BASES = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]; var MC_RX_THRESHOLD_MS = 50; var MC_RX_MAX_MS = 32000; 
- 
-function mcCalcRxDelay(rxDelayBase, score, airtimeMs) { 
- 
-<code> 
-if (rxDelayBase <= 0) return 0; 
-return (Math.pow(rxDelayBase, 0.85 - score) - 1) * airtimeMs; 
- 
-</code> 
- 
-} 
- 
-/** Optional: compute packet score from SNR (SF7–SF12), matching RadioLibWrappers.cpp */ function mcPacketScore(snr, sf, packetLen) { var thresholds = [-7.5, -10, -12.5, -15, -17.5, -20]; if (sf < 7 || sf > 12) return 0; if (snr < thresholds[sf - 7]) return 0; var rate = (snr - thresholds[sf - 7]) / 10.0; var penalty = 1 - (packetLen / 256.0); return Math.max(0, Math.min(1, rate * penalty)); } /**  Firmware-applied delay (clamp + threshold) */ function mcEffectiveRxDelay(rxDelayBase, score, airtimeMs) { 
-<code> 
- 
-var raw = mcCalcRxDelay(rxDelayBase, score, airtimeMs); 
-if (raw <MC_RX_THRESHOLD_MS) return 0; 
-return Math.min(Math.round(raw), MC_RX_MAX_MS); 
- 
-</code> 
- 
-} 
- 
-function mcRxDelayUpdate() { 
- 
-<code> 
-var airtime = parseFloat(document.getElementById('mc-airtime').value) || 150; 
-var hlRx    = parseFloat(document.getElementById('mc-highlight-rx').value) || 0; 
-var hlScore = parseFloat(document.getElementById('mc-highlight-score').value) || 0; 
- 
-</code> 
-<code> 
- 
-var raw = mcCalcRxDelay(hlRx, hlScore, airtime); 
-var eff = mcEffectiveRxDelay(hlRx, hlScore, airtime); 
-document.getElementById('mc-single-result').innerHTML = 
-  '<strong>Single value:</strong> rx_delay_base=' + hlRx + 
-  ', score=' + hlScore + ', airtime=' + airtime + ' ms<br>' + 
-  'Formula: (' + hlRx + '<sup>(0.85 − ' + hlScore + ')</sup>   − 1) × ' + airtime + 
-  ' = <strong>' + raw.toFixed(1) + ' ms</strong> (raw)<br>' + 
-  'Firmware effective delay: <strong>' + eff + ' ms</strong>' + 
-  (raw <MC_RX_THRESHOLD_MS ? ' (below 50 ms threshold → immediate)' : ''); 
- 
-</code> 
- 
-<code> 
-var thead = '<tr><th>rx_delay_base \\ score</th>'; 
-for (var s = 0; s <MC_RX_SCORES.length; s++) { 
-  thead += '<th>' + MC_RX_SCORES[s].toFixed(1) + '</th>'; 
-} 
-thead += '</tr>'; 
-document.querySelector('#mc-rxdelay-table thead').innerHTML = thead; 
- 
-</code> 
- 
-<code> 
-var tbody = ''; 
-for (var r = 0; r <MC_RX_BASES.length; r++) { 
-  var rx = MC_RX_BASES[r]; 
-  var rowClass = (Math.abs(rx - hlRx) <0.01) ? ' style="outline:2px solid #39f;"' : ''; 
-  tbody += '<tr' + rowClass + '><td class="row-hdr">' + rx + '</td>'; 
-  for (var c = 0; c <MC_RX_SCORES.length; c++) { 
-    var sc = MC_RX_SCORES[c]; 
-    var val = mcCalcRxDelay(rx, sc, airtime); 
-    var cls = ''; 
-    if (val <0) cls = 'neg'; 
-    else if (val <MC_RX_THRESHOLD_MS) cls = 'imm'; 
-    else cls = 'queued'; 
-    var hi = (Math.abs(rx - hlRx) <0.01 && Math.abs(sc - hlScore) <0.001) ? ' outline:2px solid #f90;' : ''; 
-    tbody += '<td class="' + cls + '" style="' + hi + '">' + 
-      (val <0 ? '<span class="neg">' + val.toFixed(0) + '</span>' : val.toFixed(0)) + 
-      '</td>'; 
-  } 
-  tbody += '</tr>'; 
-} 
-document.querySelector('#mc-rxdelay-table tbody').innerHTML = tbody; 
- 
-</code> 
- 
-} 
- 
-if (document.readyState === 'loading') { 
- 
-<code> 
-document.addEventListener('DOMContentLoaded', mcRxDelayUpdate); 
- 
-</code> 
- 
-} else { 
- 
-<code> 
-mcRxDelayUpdate(); 
- 
-</code> 
- 
-} </script> </html> 
- 
-===== SNR → Score Helper (optional second widget) ===== 
- 
-<html> <style> 
- 
-<code> 
-#mc-score-calc { font-family: sans-serif; max-width: 480px; } 
-#mc-score-calc .controls { display: flex; flex-wrap: wrap; gap: 12px; margin-bottom: 8px; } 
-#mc-score-calc .out { background: #f5f5f5; padding: 8px; border-radius: 4px; } 
- 
-</code> 
- 
-</style> <div id="mc-score-calc"> 
- 
-<code> 
-<p><strong>Estimate packet score from SNR</strong></p> 
-<div class="controls"> 
-  <label>SNR (dB): <input type="number" id="mc-snr" value="-5" step="0.5"></label> 
-  <label>SF: <select id="mc-sf"><option>7</option><option>8</option><option>9</option><option selected>10</option><option>11</option><option>12</option></select></label> 
-  <label>Packet len: <input type="number" id="mc-plen" value="64" min="1" max="256"></label> 
-  <button type="button" onclick="mcScoreUpdate()">Calc</button> 
-</div> 
-<div class="out" id="mc-score-out"></div> 
- 
-</code> 
- 
-</div> <script type="text/javascript"> function mcScoreUpdate() { 
- 
-<code> 
-var snr = parseFloat(document.getElementById('mc-snr').value); 
-var sf  = parseInt(document.getElementById('mc-sf').value, 10); 
-var pl  = parseInt(document.getElementById('mc-plen').value, 10); 
-var score = mcPacketScore(snr, sf, pl); 
-document.getElementById('mc-score-out').innerHTML = 
-  'Score = <strong>' + score.toFixed(3) + '</strong> — use this in the table above.'; 
- 
-</code> 
- 
-} mcScoreUpdate(); </script> </html> 
- 
-===== Practical Tuning Guide ===== 
- 
-  - **Start with ''rxdelay 2'' **  on repeaters in busy areas; increase if you still see duplicate flood collisions. 
-  - **Never use 0 < rxdelay < 1**  — it reverses the logic (bad paths win). 
-  - **''rxdelay 1'' **  gives zero delay for all scores (same as off). 
-  - Compare delays for your typical packet airtime: a 300 ms airtime doubles all table values. 
-  - Newer firmware may **autotune**  delays from neighbor count (CLI: ''get autotune''  / ''set autotune on''). 
-  - RX delay is complementary to **TX delay**  (''txdelay''): TX delay spreads //transmissions//, RX delay spreads //reception/processing//  of floods. 
- 
-===== CLI Reference ===== 
- 
-<code> 
-get rxdelay          # show current value (float, 0 = off) 
-set rxdelay 2          # enable with base 2 
- 
-</code> 
- 
-Companion radio stores the value internally as millis × 1000; repeater/room/sensor use the float directly. 
- 
----- 
- 
  
  • mc_rxdelay_calc.1780222900.txt.gz
  • Zuletzt geändert: 2026/05/31 12:21
  • von bmke-a-2345-tdeck