Add +30dB external PA gain to ERP calculations and web UI display

Made-with: Cursor
This commit is contained in:
drjones
2026-04-03 21:34:35 -07:00
parent 51c561b9a9
commit 1ba65a59df
2 changed files with 9 additions and 8 deletions

View File

@@ -24,9 +24,10 @@
// Web server // Web server
#define WEB_PORT 80 #define WEB_PORT 80
// Jamming: max CC1101 TX (+10 dBm). External PA removed — radiated power is chip + antenna gain only. // Jamming: max CC1101 TX (+10 dBm). External PA gain added to ERP calculation.
// Jam always starts after boot self-test; use web “Stop Jamming” (or capture REC) to pause for RX/capture. // Jam always starts after boot self-test; use web “Stop Jamming” (or capture REC) to pause for RX/capture.
#define DEFAULT_AUTO_START_JAM true #define DEFAULT_AUTO_START_JAM true
#define JAM_EXT_PA_GAIN_DB 30 // Gain of external RF amplifier (e.g. 30 dB / 1 Watt)
// CC1101 only accepts 8 discrete power levels (index 0-7); jam path always uses max (10 dBm). // CC1101 only accepts 8 discrete power levels (index 0-7); jam path always uses max (10 dBm).
#define JAM_POWER_LEVELS 8 #define JAM_POWER_LEVELS 8
#define DEFAULT_JAM_POWER_IDX 7 // 10 dBm — full device output (see TI SWRS061 PATABLE / output power) #define DEFAULT_JAM_POWER_IDX 7 // 10 dBm — full device output (see TI SWRS061 PATABLE / output power)

View File

@@ -1481,9 +1481,9 @@ static void oledDrawHealth() {
(unsigned)(up/3600000), (unsigned)((up/60000)%60), (unsigned)((up/1000)%60)); (unsigned)(up/3600000), (unsigned)((up/60000)%60), (unsigned)((up/1000)%60));
u8g2.drawStr(0, 44, buf); u8g2.drawStr(0, 44, buf);
const int effDbm = (int)jamPower; const int effDbm = (int)jamPower + JAM_EXT_PA_GAIN_DB;
const uint32_t effMw = (uint32_t)roundf(powf(10.0f, effDbm / 10.0f)); const uint32_t effMw = (uint32_t)roundf(powf(10.0f, effDbm / 10.0f));
snprintf(buf, sizeof(buf), "PWR %ddBm / %umW", effDbm, min(effMw, (uint32_t)9999)); snprintf(buf, sizeof(buf), "PWR %ddBm / %umW", effDbm, min(effMw, (uint32_t)999999));
u8g2.drawStr(0, 55, buf); u8g2.drawStr(0, 55, buf);
snprintf(buf, sizeof(buf), "WIFI %d ESPNOW %u", snprintf(buf, sizeof(buf), "WIFI %d ESPNOW %u",
@@ -1736,8 +1736,8 @@ textarea:focus{border-color:#4fbf59;outline:none}
<h2>System Metrics</h2> <h2>System Metrics</h2>
<div class="sg"> <div class="sg">
<div class="s"><div class="sl">Uptime</div><div class="sv" id="mUp">—</div></div> <div class="s"><div class="sl">Uptime</div><div class="sv" id="mUp">—</div></div>
<div class="s"><div class="sl">CC1101 TX (max)</div><div class="sv" id="mPow">—<span class="su">dBm</span></div></div> <div class="s"><div class="sl">CC1101 TX (chip)</div><div class="sv" id="mPow">—<span class="su">dBm</span></div></div>
<div class="s"><div class="sl">ERP (chip only)</div><div class="sv" id="mEff">—<span class="su">dBm</span></div></div> <div class="s"><div class="sl">ERP (with PA)</div><div class="sv" id="mEff">—<span class="su">dBm</span></div></div>
<div class="s"><div class="sl">ERP Watts</div><div class="sv" id="mW">—<span class="su">mW</span></div></div> <div class="s"><div class="sl">ERP Watts</div><div class="sv" id="mW">—<span class="su">mW</span></div></div>
<div class="s"><div class="sl">R1 hardware</div><div class="sv" id="mR1h">—</div></div> <div class="s"><div class="sl">R1 hardware</div><div class="sv" id="mR1h">—</div></div>
<div class="s"><div class="sl">R2 hardware</div><div class="sv" id="mR2h">—</div></div> <div class="s"><div class="sl">R2 hardware</div><div class="sv" id="mR2h">—</div></div>
@@ -1812,7 +1812,7 @@ textarea:focus{border-color:#4fbf59;outline:none}
<div class="card"> <div class="card">
<h2>Controls</h2> <h2>Controls</h2>
<p style="font-size:10px;color:#3a7a3e;margin-bottom:8px">TX power is fixed at +10 dBm (CC1101 max, TI SWRS061). Radiated level includes your antenna gain only no external PA.</p> <p style="font-size:10px;color:#3a7a3e;margin-bottom:8px">TX power is fixed at +10 dBm chip max. Radiated level displayed is ERP including the configured +30 dBm external PA.</p>
<p style="font-size:10px;color:#4fbf59;margin-bottom:8px">Jamming starts automatically on every power-up. Press <strong>Stop Jamming</strong> to go standby for capture (REC), then start jam again when done.</p> <p style="font-size:10px;color:#4fbf59;margin-bottom:8px">Jamming starts automatically on every power-up. Press <strong>Stop Jamming</strong> to go standby for capture (REC), then start jam again when done.</p>
<p style="font-size:10px;color:#3a7a3e;margin-bottom:6px"><strong>Jam strategy</strong> Direct: wide LFSR + async TX. Precision: narrower deviation / key rate. Flood: bursty random packets (hypothesis for burst-sensitive links; verify in your chamber). CW: unmodulated carrier. Pulse: slow square wave (spoofs preamble AGC). Special: 60-byte blocking packet TX with 10ms delay (cypher-pulse clone).</p> <p style="font-size:10px;color:#3a7a3e;margin-bottom:6px"><strong>Jam strategy</strong> Direct: wide LFSR + async TX. Precision: narrower deviation / key rate. Flood: bursty random packets (hypothesis for burst-sensitive links; verify in your chamber). CW: unmodulated carrier. Pulse: slow square wave (spoofs preamble AGC). Special: 60-byte blocking packet TX with 10ms delay (cypher-pulse clone).</p>
<div style="display:flex;flex-wrap:wrap;gap:6px;margin-bottom:10px"> <div style="display:flex;flex-wrap:wrap;gap:6px;margin-bottom:10px">
@@ -2039,7 +2039,7 @@ function applyTelemetry(t){
const jm=t.jam_mode_str||({0:'direct',1:'precision',2:'flood',3:'cw',4:'pulse',5:'special'}[t.jam_mode])||'direct'; const jm=t.jam_mode_str||({0:'direct',1:'precision',2:'flood',3:'cw',4:'pulse',5:'special'}[t.jam_mode])||'direct';
parts.push(jm+' | '+b.join(' + ')); parts.push(jm+' | '+b.join(' + '));
} }
document.getElementById('bs').textContent=parts.length?parts.join(' | ')+' | '+t.jam_power+' dBm chip (ERP + antenna only)' document.getElementById('bs').textContent=parts.length?parts.join(' | ')+' | '+t.eff_power_dbm+' dBm ERP (chip + PA)'
:(jam?'Jamming on but no TX':'Standby Stop Jamming to capture'); :(jam?'Jamming on but no TX':'Standby Stop Jamming to capture');
document.getElementById('bs').style.color=(jam&&(tx1||tx2))?'#86f28a':(!bstall||!ok1||!ok2||jam||(lran&&!lstall))?'#f28a86':'#4fbf59'; document.getElementById('bs').style.color=(jam&&(tx1||tx2))?'#86f28a':(!bstall||!ok1||!ok2||jam||(lran&&!lstall))?'#f28a86':'#4fbf59';
document.getElementById('tog').textContent=jam?'Stop Jamming':'Start Jamming'; document.getElementById('tog').textContent=jam?'Stop Jamming':'Start Jamming';
@@ -2287,7 +2287,7 @@ static void handleLog() {
static void handleTelemetry() { static void handleTelemetry() {
float tempC = temperatureRead(); float tempC = temperatureRead();
const int8_t effDbm = jamPower; const int8_t effDbm = jamPower + JAM_EXT_PA_GAIN_DB;
const float effWatts = powf(10.0f, effDbm / 10.0f) / 1000.0f; const float effWatts = powf(10.0f, effDbm / 10.0f) / 1000.0f;
String err1 = jsonEscape(radio1Error); String err1 = jsonEscape(radio1Error);