Skip to content

Commit 52b9d87

Browse files
weebl2000jirogit
authored andcommitted
Use hardware channel activity detection for checking interference
1 parent 856df24 commit 52b9d87

6 files changed

Lines changed: 36 additions & 8 deletions

File tree

examples/companion_radio/MyMesh.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ float MyMesh::getAirtimeBudgetFactor() const {
255255
}
256256

257257
int MyMesh::getInterferenceThreshold() const {
258-
return 0; // disabled for now, until currentRSSI() problem is resolved
258+
return 1; // non-zero enables hardware CAD (Channel Activity Detection) before TX
259259
}
260260

261261
int MyMesh::calcRxDelay(float score, uint32_t air_time) const {

examples/simple_repeater/MyMesh.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -871,7 +871,7 @@ MyMesh::MyMesh(mesh::MainBoard &board, mesh::Radio &radio, mesh::MillisecondCloc
871871
_prefs.advert_interval = 1; // default to 2 minutes for NEW installs
872872
_prefs.flood_advert_interval = 12; // 12 hours
873873
_prefs.flood_max = 64;
874-
_prefs.interference_threshold = 0; // disabled
874+
_prefs.interference_threshold = 1; // non-zero enables hardware CAD before TX
875875

876876
// bridge defaults
877877
_prefs.bridge_enabled = 1; // enabled

examples/simple_room_server/MyMesh.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -622,7 +622,7 @@ MyMesh::MyMesh(mesh::MainBoard &board, mesh::Radio &radio, mesh::MillisecondCloc
622622
_prefs.advert_interval = 1; // default to 2 minutes for NEW installs
623623
_prefs.flood_advert_interval = 12; // 12 hours
624624
_prefs.flood_max = 64;
625-
_prefs.interference_threshold = 0; // disabled
625+
_prefs.interference_threshold = 1; // non-zero enables hardware CAD before TX
626626
#ifdef ROOM_PASSWORD
627627
StrHelper::strncpy(_prefs.guest_password, ROOM_PASSWORD, sizeof(_prefs.guest_password));
628628
#endif

examples/simple_sensor/SensorMesh.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -723,7 +723,7 @@ SensorMesh::SensorMesh(mesh::MainBoard& board, mesh::Radio& radio, mesh::Millise
723723
_prefs.flood_advert_interval = 0; // disabled
724724
_prefs.disable_fwd = true;
725725
_prefs.flood_max = 64;
726-
_prefs.interference_threshold = 0; // disabled
726+
_prefs.interference_threshold = 1; // non-zero enables hardware CAD before TX
727727

728728
// GPS defaults
729729
_prefs.gps_enabled = 0;

src/helpers/radiolib/RadioLibWrappers.cpp

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -168,10 +168,37 @@ void RadioLibWrapper::onSendFinished() {
168168
state = STATE_IDLE;
169169
}
170170

171+
int16_t RadioLibWrapper::performChannelScan() {
172+
return _radio->scanChannel();
173+
}
174+
171175
bool RadioLibWrapper::isChannelActive() {
172-
return _threshold == 0
173-
? false // interference check is disabled
174-
: getCurrentRSSI() > _noise_floor + _threshold;
176+
if (_threshold == 0) return false; // interference check is disabled
177+
178+
int16_t result = performChannelScan();
179+
// scanChannel() triggers DIO interrupt (CAD done) which sets STATE_INT_READY
180+
// via setFlag() ISR. Clear it before restarting RX so recvRaw() doesn't
181+
// try to read a non-existent packet and count a spurious recv error.
182+
state = STATE_IDLE;
183+
startRecv();
184+
185+
if (result != RADIOLIB_CHANNEL_FREE) {
186+
// Random backoff to desynchronize retries between competing nodes
187+
uint32_t backoff_until = millis() + random(8000, 22000);
188+
while (millis() < backoff_until) {
189+
vTaskDelay(1); // yield CPU to FreeRTOS tasks including BLE
190+
}
191+
return true;
192+
}
193+
194+
// Small jitter even when channel is free to prevent simultaneous TX
195+
// from two nodes that both detect a free channel at the same time
196+
uint32_t jitter_until = millis() + random(0, 500);
197+
while (millis() < jitter_until) {
198+
vTaskDelay(1); // yield CPU to FreeRTOS tasks including BLE
199+
}
200+
201+
return false;
175202
}
176203

177204
float RadioLibWrapper::getLastRSSI() const {

src/helpers/radiolib/RadioLibWrappers.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,14 @@ class RadioLibWrapper : public mesh::Radio {
3131
bool isInRecvMode() const override;
3232
bool isChannelActive();
3333

34-
bool isReceiving() override {
34+
bool isReceiving() override {
3535
if (isReceivingPacket()) return true;
3636

3737
return isChannelActive();
3838
}
3939

4040
virtual float getCurrentRSSI() =0;
41+
virtual int16_t performChannelScan();
4142

4243
int getNoiseFloor() const override { return _noise_floor; }
4344
void triggerNoiseFloorCalibrate(int threshold) override;

0 commit comments

Comments
 (0)