Skip to content

Commit 88490fb

Browse files
author
Hasnain Virk
committed
Mitigating reception problems with lower data rates
A new algorithm has been taken in use to calculate the receive window length and the timing offset involved in opening of the said receive window. This algorithm performs better than the stock algorthm and consumes less power.
1 parent f4077af commit 88490fb

File tree

4 files changed

+56
-28
lines changed

4 files changed

+56
-28
lines changed

features/lorawan/lorastack/phy/LoRaPHY.cpp

Lines changed: 43 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,9 @@ SPDX-License-Identifier: BSD-3-Clause
3232
#define BACKOFF_DC_1_HOUR 100
3333
#define BACKOFF_DC_10_HOURS 1000
3434
#define BACKOFF_DC_24_HOURS 10000
35-
36-
#define CHANNELS_IN_MASK 16
35+
#define MAX_PREAMBLE_LENGTH 8.0
36+
#define TICK_GRANULARITY_JITTER 1.0
37+
#define CHANNELS_IN_MASK 16
3738

3839
LoRaPHY::LoRaPHY()
3940
: _radio(NULL),
@@ -388,23 +389,49 @@ uint8_t LoRaPHY::verify_link_ADR_req(verify_adr_params_t *verify_params,
388389
return status;
389390
}
390391

391-
double LoRaPHY::compute_symb_timeout_lora(uint8_t phy_dr, uint32_t bandwidth)
392+
float LoRaPHY::compute_symb_timeout_lora(uint8_t phy_dr, uint32_t bandwidth)
392393
{
393-
return ((double)(1 << phy_dr) / (double) bandwidth) * 1000;
394+
// in milliseconds
395+
return ((float)(1 << phy_dr) / (float) bandwidth * 1000);
394396
}
395397

396-
double LoRaPHY::compute_symb_timeout_fsk(uint8_t phy_dr)
398+
float LoRaPHY::compute_symb_timeout_fsk(uint8_t phy_dr)
397399
{
398-
return (8.0 / (double) phy_dr); // 1 symbol equals 1 byte
400+
return (8.0 / (float) phy_dr); // 1 symbol equals 1 byte
399401
}
400402

401-
void LoRaPHY::get_rx_window_params(double t_symb, uint8_t min_rx_symb,
402-
uint32_t rx_error, uint32_t wakeup_time,
403-
uint32_t *window_timeout, int32_t *window_offset)
403+
404+
void LoRaPHY::get_rx_window_params(float t_symb, uint8_t min_rx_symb,
405+
float error_fudge, float wakeup_time,
406+
uint32_t *window_length, int32_t *window_offset,
407+
uint8_t phy_dr)
404408
{
405-
// Computed number of symbols
406-
*window_timeout = MAX((uint32_t) ceil(((2 * min_rx_symb - 8) * t_symb + 2 * rx_error) / t_symb), min_rx_symb);
407-
*window_offset = (int32_t) ceil((4.0 * t_symb) - ((*window_timeout * t_symb) / 2.0) - wakeup_time);
409+
float min_rx_symbol_overlap_required = float (min_rx_symb);
410+
float target_rx_window_offset;
411+
float window_len_in_ms;
412+
413+
if (phy_params.fsk_supported && phy_dr == phy_params.max_rx_datarate) {
414+
min_rx_symbol_overlap_required = MAX_PREAMBLE_LENGTH;
415+
}
416+
417+
// We wish to be as close as possible to the actual start of data, i.e.,
418+
// we are interested in the preamble symbols which are at the tail of the
419+
// preamble sequence.
420+
target_rx_window_offset = (MAX_PREAMBLE_LENGTH - min_rx_symbol_overlap_required) * t_symb; //in ms
421+
422+
// Actual window offset in ms in response to timing error fudge factor and
423+
// radio wakeup/turned around time.
424+
*window_offset = floor(target_rx_window_offset - error_fudge - wakeup_time);
425+
426+
// Minimum reception time plus extra time (in ms) we may have turned on before the
427+
// other side started transmission
428+
window_len_in_ms = (min_rx_symbol_overlap_required * t_symb) - MIN(0, (*window_offset - error_fudge - TICK_GRANULARITY_JITTER));
429+
430+
// Setting the window_length in terms of 'symbols' for LoRa modulation or
431+
// in terms of 'bytes' for FSK
432+
*window_length = (uint32_t) ceil(window_len_in_ms / t_symb);
433+
434+
408435
}
409436

410437
int8_t LoRaPHY::compute_tx_power(int8_t tx_power_idx, float max_eirp,
@@ -791,7 +818,7 @@ void LoRaPHY::compute_rx_win_params(int8_t datarate, uint8_t min_rx_symbols,
791818
uint32_t rx_error,
792819
rx_config_params_t *rx_conf_params)
793820
{
794-
double t_symbol = 0.0;
821+
float t_symbol = 0.0;
795822

796823
// Get the datarate, perform a boundary check
797824
rx_conf_params->datarate = MIN(datarate, phy_params.max_rx_datarate);
@@ -811,9 +838,9 @@ void LoRaPHY::compute_rx_win_params(int8_t datarate, uint8_t min_rx_symbols,
811838
rx_conf_params->frequency = phy_params.channels.channel_list[rx_conf_params->channel].frequency;
812839
}
813840

814-
815-
get_rx_window_params(t_symbol, min_rx_symbols, rx_error, RADIO_WAKEUP_TIME,
816-
&rx_conf_params->window_timeout, &rx_conf_params->window_offset);
841+
get_rx_window_params(t_symbol, min_rx_symbols, (float) rx_error, RADIO_WAKEUP_TIME,
842+
&rx_conf_params->window_timeout, &rx_conf_params->window_offset,
843+
rx_conf_params->datarate);
817844
}
818845

819846
bool LoRaPHY::rx_config(rx_config_params_t *rx_conf)

features/lorawan/lorastack/phy/LoRaPHY.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -597,9 +597,10 @@ class LoRaPHY : private mbed::NonCopyable<LoRaPHY> {
597597
/**
598598
* Computes the RX window timeout and the RX window offset.
599599
*/
600-
void get_rx_window_params(double t_symbol, uint8_t min_rx_symbols,
601-
uint32_t rx_error, uint32_t wakeup_time,
602-
uint32_t *window_timeout, int32_t *window_offset);
600+
void get_rx_window_params(float t_symbol, uint8_t min_rx_symbols,
601+
float rx_error, float wakeup_time,
602+
uint32_t *window_length, int32_t *window_offset,
603+
uint8_t phy_dr);
603604

604605
/**
605606
* Computes the txPower, based on the max EIRP and the antenna gain.
@@ -632,12 +633,12 @@ class LoRaPHY : private mbed::NonCopyable<LoRaPHY> {
632633
/**
633634
* Computes the symbol time for LoRa modulation.
634635
*/
635-
double compute_symb_timeout_lora(uint8_t phy_dr, uint32_t bandwidth);
636+
float compute_symb_timeout_lora(uint8_t phy_dr, uint32_t bandwidth);
636637

637638
/**
638639
* Computes the symbol time for FSK modulation.
639640
*/
640-
double compute_symb_timeout_fsk(uint8_t phy_dr);
641+
float compute_symb_timeout_fsk(uint8_t phy_dr);
641642

642643
protected:
643644
LoRaRadio *_radio;

features/lorawan/mbed_lib.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,16 +70,16 @@
7070
"value": true
7171
},
7272
"max-sys-rx-error": {
73-
"help": "Maximum timing error of the receiver in ms. The receiver will turn on in [-RxError : + RxError]",
74-
"value": 10
73+
"help": "Maximum timing error of the receiver in ms. The receiver will turn on in [-RxError : + RxError]",
74+
"value": 1
7575
},
7676
"downlink-preamble-length": {
77-
"help": "Number of preamble symbols need to be captured (out of 8) for successful demodulation",
78-
"value": 5
77+
"help": "Number of whole preamble symbols needed to have a firm lock on the signal. Default: 5 + 1",
78+
"value": 6
7979
},
8080
"uplink-preamble-length": {
81-
"help": "Number of preamble symbols to transmit. Must be <= 8",
82-
"value": 8
81+
"help": "Number of preamble symbols to transmit. Default: 8",
82+
"value": 8
8383
},
8484
"fsb-mask": {
8585
"help": "FSB mask for upstream [Only for US915 & AU915] Check lorawan/FSB_Usage.txt for more details",

features/lorawan/system/lorawan_data_structures.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ typedef uint32_t lorawan_time_t;
4545
#endif
4646

4747
// Radio wake-up time from sleep - unit ms.
48-
#define RADIO_WAKEUP_TIME 1
48+
#define RADIO_WAKEUP_TIME 1.0
4949

5050
/*!
5151
* Sets the length of the LoRaMAC footer field.

0 commit comments

Comments
 (0)