Skip to content

Commit 305a4b2

Browse files
shailensobheeclaude
andcommitted
fix: recalibrate noise detection to not drop legitimate Somfy frames
The previous threshold (>100 edges in 10 seconds) tripped on the very first button press — a single Somfy RTS press emits 500-900 edges in under a second. Worse, the cooldown was measured from the start of the count window, so the ISR re-enabled on the next loop iteration, missing only the frame repetitions in flight. New thresholds: >1000 edges in any 50ms window (~13x peak legitimate rate for SYMBOL=640µs), with a 2s cooldown measured from the moment the ISR was disabled. Tooltip and header comment updated to match. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent da0d93a commit 305a4b2

3 files changed

Lines changed: 21 additions & 14 deletions

File tree

data-src/index.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -949,8 +949,8 @@ <h1 style="text-align: center;"><img src="icon.png" style="width:50px;float:left
949949
<label for="cbEnableRadio" style="display:inline-block;cursor:pointer;">Enable Radio</label>
950950
</div>
951951
<div class="field-group" style="vertical-align:middle;margin-left:7px;float:right;display:inline-block;width:auto;">
952-
<input id="cbNoiseDetection" name="noiseDetection" type="checkbox" data-bind="transceiver.config.noiseDetection" style="display:inline-block;" title="When enabled, the RX interrupt is automatically disabled if more than 100 pulses are detected within 10 seconds (RF noise burst). The interrupt is re-enabled after a 100ms cooldown. Enable this if your radio is frequently disrupted by nearby RF interference." />
953-
<label for="cbNoiseDetection" style="display:inline-block;cursor:pointer;" title="When enabled, the RX interrupt is automatically disabled if more than 100 pulses are detected within 10 seconds (RF noise burst). The interrupt is re-enabled after a 100ms cooldown. Enable this if your radio is frequently disrupted by nearby RF interference.">Noise Detection</label>
952+
<input id="cbNoiseDetection" name="noiseDetection" type="checkbox" data-bind="transceiver.config.noiseDetection" style="display:inline-block;" title="When enabled, the RX interrupt is automatically disabled if more than 1000 pulses are detected within a 50ms window (genuine RF noise burst — well above the peak edge rate of a legitimate Somfy frame). The interrupt is re-enabled after a 2 second cooldown. Enable this only if your radio is frequently overwhelmed by continuous nearby RF interference." />
953+
<label for="cbNoiseDetection" style="display:inline-block;cursor:pointer;" title="When enabled, the RX interrupt is automatically disabled if more than 1000 pulses are detected within a 50ms window (genuine RF noise burst — well above the peak edge rate of a legitimate Somfy frame). The interrupt is re-enabled after a 2 second cooldown. Enable this only if your radio is frequently overwhelmed by continuous nearby RF interference.">Noise Detection</label>
954954
</div>
955955
<div class="field-group" style="margin-top:-18px;"><label style="font-size:12px;">(default when adding new motors)</label></div>
956956
<div class="field-group1" style="white-space:nowrap">

src/Somfy.cpp

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,16 @@ int sort_asc(const void *cmp1, const void *cmp2) {
4747
}
4848

4949
static int interruptPin = 0;
50+
// Noise detection thresholds calibrated for Somfy RTS (SYMBOL=640µs → peak
51+
// legitimate edge rate ~1500/s, i.e. ~75 edges per 50ms burst). Trip at ~13×
52+
// that to leave ample margin; 2s cooldown prevents immediate re-trip storms.
53+
static constexpr uint32_t NOISE_WINDOW_MS = 50;
54+
static constexpr uint32_t NOISE_EDGE_THRESHOLD = 1000;
55+
static constexpr uint32_t NOISE_COOLDOWN_MS = 2000;
5056
static volatile bool noiseDetected = false;
51-
static volatile unsigned long noiseStart = 0;
52-
static volatile uint32_t noiseCount = 0;
57+
static volatile unsigned long noiseWindowStart = 0;
58+
static volatile uint32_t noiseWindowCount = 0;
59+
static volatile unsigned long noiseDisabledAt = 0;
5360
static uint8_t bit_length = 56;
5461
somfy_commands translateSomfyCommand(const String& string) {
5562
if (string.equalsIgnoreCase("My")) return somfy_commands::My;
@@ -4198,14 +4205,14 @@ void RECEIVE_ATTR Transceiver::handleReceive() {
41984205
if (noiseDetected) return;
41994206
if (somfy.transceiver.config.noiseDetection) {
42004207
unsigned long now = millis();
4201-
if (noiseStart == 0) noiseStart = now;
4202-
if (now - noiseStart >= 10000) {
4203-
noiseStart = now;
4204-
noiseCount = 0;
4208+
if (noiseWindowStart == 0 || (now - noiseWindowStart) > NOISE_WINDOW_MS) {
4209+
noiseWindowStart = now;
4210+
noiseWindowCount = 0;
42054211
}
4206-
noiseCount++;
4207-
if (noiseCount > 100) {
4212+
noiseWindowCount++;
4213+
if (noiseWindowCount > NOISE_EDGE_THRESHOLD) {
42084214
gpio_intr_disable((gpio_num_t)interruptPin);
4215+
noiseDisabledAt = now;
42094216
noiseDetected = true;
42104217
return;
42114218
}
@@ -4885,11 +4892,11 @@ bool Transceiver::begin() {
48854892
void Transceiver::loop() {
48864893
somfy_rx_t rx;
48874894
if (noiseDetected && rxmode != 3 && this->config.noiseDetection) {
4888-
if (millis() - noiseStart > 100) {
4895+
if (millis() - noiseDisabledAt > NOISE_COOLDOWN_MS) {
48894896
gpio_intr_enable((gpio_num_t)interruptPin);
48904897
noiseDetected = false;
4891-
noiseStart = 0;
4892-
noiseCount = 0;
4898+
noiseWindowStart = 0;
4899+
noiseWindowCount = 0;
48934900
}
48944901
}
48954902
if(rxmode == 3) {

src/Somfy.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ struct transceiver_config_t {
426426
float deviation = 47.60; // Set the Frequency deviation in kHz. Value from 1.58 to 380.85. Default is 47.60 kHz.
427427
float rxBandwidth = 99.97; // Receive bandwidth in kHz. Value from 58.03 to 812.50. Default is 99.97kHz.
428428
int8_t txPower = 10; // Transmission power {-30, -20, -15, -10, -6, 0, 5, 7, 10, 11, 12}. Default is 12.
429-
bool noiseDetection = false; // Disable RX interrupt when RF noise is detected (>100 pulses/10s)
429+
bool noiseDetection = false; // Disable RX interrupt on RF noise burst (>1000 pulses/50ms, 2s cooldown)
430430
/*
431431
bool internalCCMode = false; // Use internal transmission mode FIFO buffers.
432432
byte modulationMode = 2; // Modulation mode. 0 = 2-FSK, 1 = GFSK, 2 = ASK/OOK, 3 = 4-FSK, 4 = MSK.

0 commit comments

Comments
 (0)