Fixed RX duty-cycle packet metadata handling (last message snr and rssi now should be good)

This commit is contained in:
Jarosław Domański committed 2026-07-18 02:08:34 +02:00
1 parent b68aa103df
commit 5d793ed682
10 files changed
+59 -28

No files matched your search

+10 -5
View File
@@ -191,20 +191,24 @@ bool Dispatcher::tryParsePacket(Packet* pkt, const uint8_t* raw, int len) {
void Dispatcher::checkRecv() {
Packet* pkt;
float score;
float snr;
float rssi;
uint32_t air_time;
{
uint8_t raw[MAX_TRANS_UNIT+1];
int len = _radio->recvRaw(raw, MAX_TRANS_UNIT);
if (len > 0) {
logRxRaw(_radio->getLastSNR(), _radio->getLastRSSI(), raw, len);
snr = _radio->getLastSNR();
rssi = _radio->getLastRSSI();
logRxRaw(snr, rssi, raw, len);
pkt = _mgr->allocNew();
if (pkt == NULL) {
MESH_DEBUG_PRINTLN("%s Dispatcher::checkRecv(): WARNING: received data, no unused packets available!", getLogDateTime());
} else {
if (tryParsePacket(pkt, raw, len)) {
pkt->_snr = _radio->getLastSNR() * 4.0f;
score = _radio->packetScore(_radio->getLastSNR(), len);
pkt->_snr = snr * 4.0f;
score = _radio->packetScore(snr, len);
air_time = _radio->getEstAirtimeFor(len);
rx_air_time += air_time;
} else {
@@ -221,7 +225,7 @@ void Dispatcher::checkRecv() {
Serial.print(getLogDateTime());
Serial.printf(": RX, len=%d (type=%d, route=%s, payload_len=%d) SNR=%d RSSI=%d score=%d time=%d",
pkt->getRawLength(), pkt->getPayloadType(), pkt->isRouteDirect() ? "D" : "F", pkt->payload_len,
(int)pkt->getSNR(), (int)_radio->getLastRSSI(), (int)(score*1000), air_time);
(int)pkt->getSNR(), (int)rssi, (int)(score*1000), air_time);
static uint8_t packet_hash[MAX_HASH_SIZE];
pkt->calculatePacketHash(packet_hash);
@@ -256,6 +260,7 @@ void Dispatcher::checkRecv() {
processRecvPacket(pkt);
}
}
_radio->onReceiveProcessed();
}
void Dispatcher::processRecvPacket(Packet* pkt) {
@@ -387,4 +392,4 @@ unsigned long Dispatcher::futureMillis(int millis_from_now) const {
return _ms->getMillis() + millis_from_now;
}
}
}
+3
View File
@@ -31,6 +31,9 @@ public:
*/
virtual int recvRaw(uint8_t* bytes, int sz) = 0;
/** Called after the received packet and its radio metadata have been processed. */
virtual void onReceiveProcessed() { }
/**
* \returns estimated transmit air-time needed for packet of 'len_bytes', in milliseconds.
*/
@@ -22,9 +22,6 @@ public:
float getCurrentRSSI() override {
return ((CustomLLCC68 *)_radio)->getRSSI(false);
}
float getLastRSSI() const override { return ((CustomLLCC68 *)_radio)->getRSSI(); }
float getLastSNR() const override { return ((CustomLLCC68 *)_radio)->getSNR(); }
float packetScore(float snr, int packet_len) override {
int sf = ((CustomLLCC68 *)_radio)->spreadingFactor;
return packetScoreInt(snr, sf, packet_len);
@@ -69,9 +69,6 @@ protected:
}
public:
float getLastRSSI() const override { return ((CustomLR1110 *)_radio)->getRSSI(); }
float getLastSNR() const override { return ((CustomLR1110 *)_radio)->getSNR(); }
uint8_t getSpreadingFactor() const override { return ((CustomLR1110 *)_radio)->getSpreadingFactor(); }
void setRxBoostedGainMode(bool en) override {
@@ -23,9 +23,6 @@ public:
float getCurrentRSSI() override {
return ((CustomSTM32WLx *)_radio)->getRSSI(false);
}
float getLastRSSI() const override { return ((CustomSTM32WLx *)_radio)->getRSSI(); }
float getLastSNR() const override { return ((CustomSTM32WLx *)_radio)->getSNR(); }
float packetScore(float snr, int packet_len) override {
int sf = ((CustomSTM32WLx *)_radio)->spreadingFactor;
return packetScoreInt(snr, sf, packet_len);
@@ -30,9 +30,6 @@ public:
float getCurrentRSSI() override {
return ((CustomSX1262 *)_radio)->getRSSI(false);
}
float getLastRSSI() const override { return ((CustomSX1262 *)_radio)->getRSSI(); }
float getLastSNR() const override { return ((CustomSX1262 *)_radio)->getSNR(); }
float packetScore(float snr, int packet_len) override {
int sf = ((CustomSX1262 *)_radio)->spreadingFactor;
return packetScoreInt(snr, sf, packet_len);
@@ -26,9 +26,6 @@ public:
float getCurrentRSSI() override {
return ((CustomSX1268 *)_radio)->getRSSI(false);
}
float getLastRSSI() const override { return ((CustomSX1268 *)_radio)->getRSSI(); }
float getLastSNR() const override { return ((CustomSX1268 *)_radio)->getSNR(); }
float packetScore(float snr, int packet_len) override {
int sf = ((CustomSX1268 *)_radio)->spreadingFactor;
return packetScoreInt(snr, sf, packet_len);
@@ -25,9 +25,6 @@ public:
float getCurrentRSSI() override {
return ((CustomSX1276 *)_radio)->getRSSI(false);
}
float getLastRSSI() const override { return ((CustomSX1276 *)_radio)->getRSSI(); }
float getLastSNR() const override { return ((CustomSX1276 *)_radio)->getSNR(); }
float packetScore(float snr, int packet_len) override {
int sf = ((CustomSX1276 *)_radio)->spreadingFactor;
return packetScoreInt(snr, sf, packet_len);
+39 -2
View File
@@ -314,9 +314,14 @@ int RadioLibWrapper::recvRaw(uint8_t* bytes, int sz) {
int len = 0;
if (state & STATE_INT_READY) {
if (isPacketReady()) {
if (_rx_ps_armed) {
stopReceiveDutyCycle();
}
len = _radio->getPacketLength();
if (len > 0) {
if (len > sz) { len = sz; }
_last_snr = _radio->getSNR();
_last_rssi = _radio->getRSSI();
int err = _radio->readData(bytes, len);
if (err != RADIOLIB_ERR_NONE) {
MESH_DEBUG_PRINTLN("RadioLibWrapper: error: readData(%d)", err);
@@ -331,12 +336,44 @@ int RadioLibWrapper::recvRaw(uint8_t* bytes, int sz) {
state = STATE_IDLE; // need another startReceive()
}
if (len > 0 && _rx_ps_enabled) {
_rx_hold_continuous = true;
int err = _radio->startReceive();
if (err == RADIOLIB_ERR_NONE) {
state = STATE_RX;
if (_nf_calib_active) {
_nf_sample_from = millis() + NF_CALIB_SETTLE_MS;
}
} else {
MESH_DEBUG_PRINTLN("RadioLibWrapper: error: startReceive after packet (%d)", err);
}
return len;
}
if (state != STATE_RX) {
startRecv();
}
return len;
}
void RadioLibWrapper::onReceiveProcessed() {
if (!_rx_hold_continuous) return;
if ((state & ~STATE_INT_READY) == STATE_TX_WAIT) {
_rx_hold_continuous = false;
return;
}
if ((state & STATE_INT_READY) != 0 || isReceivingPacket()) {
return;
}
_rx_hold_continuous = false;
if (!_rx_ps_enabled || _nf_calib_active) return;
state = STATE_IDLE;
startRecv();
}
uint32_t RadioLibWrapper::getEstAirtimeFor(int len_bytes) {
return _radio->getTimeOnAir(len_bytes) / 1000;
}
@@ -403,10 +440,10 @@ bool RadioLibWrapper::isChannelActive() {
}
float RadioLibWrapper::getLastRSSI() const {
return _radio->getRSSI();
return _last_rssi;
}
float RadioLibWrapper::getLastSNR() const {
return _radio->getSNR();
return _last_snr;
}
// Approximate SNR threshold per SF for successful reception (based on Semtech datasheets)
+7 -3
View File
@@ -16,12 +16,14 @@ protected:
mesh::MainBoard* _board;
uint32_t n_recv, n_sent, n_recv_errors;
int16_t _noise_floor, _threshold;
float _last_rssi, _last_snr;
bool _cad_enabled;
uint16_t _num_floor_samples;
int32_t _floor_sample_sum;
uint8_t _preamble_sf;
bool _rx_ps_enabled;
bool _rx_ps_armed; // radio is currently in RX duty-cycle mode
bool _rx_hold_continuous;
uint32_t _rx_ps_rx_us;
uint32_t _rx_ps_sleep_us;
@@ -81,16 +83,18 @@ protected:
public:
RadioLibWrapper(PhysicalLayer& radio, mesh::MainBoard& board)
: _radio(&radio), _board(&board), _preamble_sf(0), _rx_ps_enabled(false), _rx_ps_armed(false),
_rx_hold_continuous(false),
_rx_ps_rx_us(RX_PS_FALLBACK_RX_US), _rx_ps_sleep_us(RX_PS_FALLBACK_SLEEP_US),
_wd_last_busy(false), _wd_stage(0), _wd_strikes(0), _startrx_fails(0), _wd_last_transition(0),
_wd_stuck_thresh(0), _wd_observe_until(0), _wd_observe_ms(0),
_params_valid(false), _dbm_valid(false),
_nf_calib_active(false), _nf_last_calib(0), _nf_calib_deadline(0), _nf_sample_from(0)
{ n_recv = n_sent = n_recv_errors = n_wd_soft = n_wd_hard = 0; }
{ n_recv = n_sent = n_recv_errors = n_wd_soft = n_wd_hard = 0; _last_rssi = _last_snr = 0; }
void begin() override;
virtual void powerOff() { _radio->sleep(); }
int recvRaw(uint8_t* bytes, int sz) override;
void onReceiveProcessed() override;
uint32_t getEstAirtimeFor(int len_bytes) override;
bool startSendRaw(const uint8_t* bytes, int len) override;
bool isSendComplete() override;
@@ -136,8 +140,8 @@ public:
bool isCalibratingNoiseFloor() const { return _nf_calib_active; }
void resetStats() { n_recv = n_sent = n_recv_errors = 0; }
virtual float getLastRSSI() const override;
virtual float getLastSNR() const override;
float getLastRSSI() const override final;
float getLastSNR() const override final;
float packetScore(float snr, int packet_len) override { return packetScoreInt(snr, 10, packet_len); } // assume sf=10