Jamming: fixed dual carriers 315 + 433.92 MHz (no sweep)

- R1 locks 315 MHz with narrow FM deviation + LFSR; R2 locks 433.92 with max deviation
- Remove VCO sweep tables, tickSweepFast, and hop loop; ~2.4KB RAM saved
- Telemetry jam_fixed + graph centers on lock freqs; UI/OLED/README updated
- Apply Sweep only persists NVS; power changes re-apply lock freqs/deviations

Made-with: Cursor
This commit is contained in:
drjones
2026-03-24 19:08:10 -07:00
parent 01d95ee0e9
commit 656673cffd
3 changed files with 117 additions and 256 deletions

104
README.md
View File

@@ -7,29 +7,22 @@ ESP32-S3 + dual CC1101 + external amplifiers + OLED display + web interface.
## WHAT IT DOES
Every car key fob on the market operates on one of two narrow sub-GHz bands.
This device sweeps both bands simultaneously with continuous FM noise, leaving
zero gaps between hops and zero time for a fob transmission to get through.
Most car key fobs that matter for NA vs EU/global boil down to two on-air
channels: about **315 MHz** (North America) and **433.92 MHz** (Europe and much
of the rest of the world).
300 - 320 MHz North American band
Honda/Acura 303.825 MHz
Chamberlain/LiftMaster 310.0 MHz
Toyota/Lexus/Scion 314.98 MHz
Ford/GM/Chrysler/Dodge/Jeep 315.0 MHz
Linear Delta-3 / LiftMaster 318.0 MHz
This firmware **does not sweep** those bands anymore. Each CC1101 **locks** on
one frequency and stays there at full configured TX power:
390 - 436 MHz European and global band
Chamberlain/LiftMaster 390.0 MHz
Holtek-based remotes 418.0 MHz
Somfy RTS / SMC 5326 433.42 MHz
BMW/VW/Audi/Mercedes/Hyundai/Kia 433.92 MHz
Asian/Euro fobs 434.42 MHz
Radio 1 315.000 MHz Narrow FM deviation + Galois LFSR on GDO0
(energy concentrated on the NA fob channel)
A fob button press generates a 200-500ms transmission window.
Radio 1 completes a full sweep of 300-320 MHz every 75ms.
Radio 2 completes a full sweep of 390-436 MHz every 180ms.
Every target frequency gets hit multiple times per fob press.
The car never receives a clean signal.
Radio 2 433.920 MHz Maximum CC1101 FM deviation + same LFSR
(wide, loud noise on the dominant EU/global ISM fob channel)
Both antennas scream continuously while jamming is enabled — no hopping, no
dwell time, no split energy across a span. The web UI and OLED show these as
locked carriers (`jam_fixed` in telemetry).
---
@@ -57,17 +50,17 @@ The car never receives a clean signal.
GPIO 12 SCK
GPIO 13 MISO
[CC1101 NUMBER 1 - 300-320 MHz sweep]
[CC1101 NUMBER 1 - 315 MHz locked jam]
GPIO 7 CS (chip select, dedicated)
GPIO 4 GDO0 (LEDC PWM noise output)
GPIO 4 GDO0 (LFSR noise into direct async TX)
3V3 VCC
GND GND
[CC1101 NUMBER 2 - 390-436 MHz sweep]
[CC1101 NUMBER 2 - 433.92 MHz locked jam]
GPIO 8 CS (chip select, dedicated)
GPIO 5 GDO0 (LEDC PWM noise output)
GPIO 5 GDO0 (LFSR noise into direct async TX)
3V3 VCC
GND GND
@@ -97,33 +90,24 @@ The car never receives a clean signal.
[RF CONFIGURATION]
Modulation FM noise (direct async TX via GDO0 LEDC PWM)
Frequency deviation 380 kHz (CC1101 hardware maximum)
Noise bandwidth ~1010 kHz per hop (Carson rule: 2 x (380 + 125))
Bitrate 250 kbps
Carrier plan Radio 1 locked 315.000 MHz, Radio 2 locked 433.920 MHz
Modulation FM from Galois LFSR bitstream on GDO0 (direct async TX)
Deviation R1 25 kHz (narrow — energy on 315)
Deviation R2 380 kHz (CC1101 max — wide noise on 433.92)
LFSR clock 50 kHz (hardware timer ISR)
Bitrate (RadioLib) 250 kbps context for begin()
RX bandwidth 812 kHz (maximum)
TX power -30 / -20 / -15 / -10 / 0 / 5 / 7 / 10 dBm (8 steps)
Default TX power 10 dBm
Amplifier gain +20 dB (configurable in web UI)
Effective output 30 dBm / ~1 Watt (with amplifiers, at 10 dBm TX)
[SWEEP CONFIGURATION - defaults]
[LEGACY SWEEP SETTINGS IN WEB UI / NVS]
Radio 1 center 310.0 MHz
Radio 1 span 20.0 MHz (300 - 320 MHz)
Radio 1 steps 25 (0.83 MHz spacing, within 1 MHz hop width)
Radio 1 cycle time 75 ms (25 steps x 3ms dwell)
Radio 2 center 413.0 MHz
Radio 2 span 46.0 MHz (390 - 436 MHz)
Radio 2 steps 60 (0.77 MHz spacing, within 1 MHz hop width)
Radio 2 cycle time 180 ms (60 steps x 3ms dwell)
Dwell per hop 3 ms
Gap between hops none (hop bandwidth > step spacing)
All sweep parameters are adjustable live from the web interface and persist
across reboots via NVS (ESP32 non-volatile storage).
Dwell, steps, and span are still saved to NVS if you use Apply Sweep.
Fixed-carrier jamming does not use them. Tunables are in config.h:
JAM_LOCK_FREQ_1_MHZ, JAM_LOCK_FREQ_2_MHZ, JAM_DEV_KHZ_R1_NARROW,
JAM_DEV_KHZ_R2_WIDE.
---
@@ -136,11 +120,11 @@ Three dot indicators in the header show the current page.
[PAGE 0 - STATUS] (default)
Header: inverted bar reading JAMMING ACTIVE when running, STANDBY when not
Header: inverted bar reading LOCKED JAM when running, STANDBY when not
Row 1: ANT1 current frequency in MHz with animated radio-wave arcs
Row 2: ANT2 current frequency in MHz with animated radio-wave arcs
Row 3: TX power breakdown: radio dBm + amp gain = effective dBm
Row 4: FULL DUAL-BAND TX badge when both radios active, else temp and heap
Row 4: 315 + 433.92 LOCK badge when both radios active, else temp and heap
Row 5: uptime since boot
[PAGE 1 - FREQ AND HOPS]
@@ -219,18 +203,13 @@ Connect to the WiFi access point, then open the control panel in a browser.
Start / Stop jamming toggle
TX power selector (8 levels: -30 dBm to 10 dBm)
Amplifier gain input (dB, affects displayed effective power only)
Sweep dwell time (ms per hop)
Radio 1 steps and span (MHz)
Radio 2 steps and span (MHz)
Sweep tuning fields (legacy — stored in NVS only, not used for jam)
All settings persist to NVS on save
[VISUALIZATIONS]
Two canvas sweep displays, one per radio band.
Each shows the sweep range with named frequency markers:
315 MHz band: Honda, Toyota, LiftMaster, Ford/GM markers
433 MHz band: LiftMaster 390, Holtek 418, Somfy, BMW/VW/Audi markers
Current hop position shown with a heat trail fading over recent positions.
Two canvas displays show a narrow window around each locked carrier (markers
for common fob channels still drawn where they fall in range).
Canvas height 90px, updates every 1 second with telemetry.
Two sparkline charts showing 2-minute rolling history:
@@ -247,9 +226,10 @@ Connect to the WiFi access point, then open the control panel in a browser.
Minimum heap KB recorded
Hop count Radio 1 (total since boot)
Hop count Radio 2 (total since boot)
Combined hops per second
Hop counters (stay at 0 in fixed-carrier mode; kept for API compatibility)
WiFi clients on AP
Nodes (ESP-NOW): count of other boards running this firmware in range
Jam mode: LOCKED when jam_fixed is true in telemetry
Uptime
24-hour mission progress bar in the header
@@ -349,8 +329,7 @@ The system is designed to run unattended at full power indefinitely.
[KEY FUNCTIONS IN MAIN.CPP]
startJamming() initializes both CC1101s, sets power, starts async TX
tickSweep() advances one radio by one hop step
startJamming() initializes both CC1101s, locks freqs, sets deviation, async TX
oledTick() OLED update loop, handles pages and notifications
oledDrawStatus() page 0 renderer
oledDrawFreq() page 1 renderer
@@ -359,19 +338,16 @@ The system is designed to run unattended at full power indefinitely.
oledBootMsg() synchronous boot status message
encISR() rotary encoder interrupt service routine
handleToggle() HTTP handler: start/stop jamming
handleSettings() HTTP handler: update sweep and power parameters
handleSettings() HTTP handler: update TX power
handleTelemetry() HTTP handler: JSON status for web UI polling
handleLogs() HTTP handler: timestamped log ring buffer
handleRoot() HTTP handler: serves embedded web UI HTML
logLine() timestamped log entry to ring buffer and Serial
loop() sweeps both radios, runs OLED, runs OTA, watchdog
loop() ESP-NOW tick, HTTP, OLED, capture FSM, watchdog
[SWEEP LOOP TIMING]
[JAM TIMING]
Both radios are swept independently in the same loop() pass.
tickSweep() is a no-op if less than sweepDwellMs have elapsed.
There are no blocking delays in the main loop.
OLED and web server run interleaved with no impact on sweep timing.
Carriers are fixed after startJamming(); no hop loop. LFSR ISR runs at 50 kHz.
---