From 76108e753bc036cf9102f24953745ac2a31b6357 Mon Sep 17 00:00:00 2001 From: Frank Hessel Date: Thu, 1 Dec 2022 08:21:49 +0100 Subject: [PATCH] Add functions to calculate sensitivity of the modems --- .../chirpotle/chirpotle/tools/__init__.py | 2 +- .../chirpotle/chirpotle/tools/helpers.py | 56 +++++++++++++++++++ controller/chirpotle/setup.py | 1 + 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/controller/chirpotle/chirpotle/tools/__init__.py b/controller/chirpotle/chirpotle/tools/__init__.py index fe064de..632da93 100644 --- a/controller/chirpotle/chirpotle/tools/__init__.py +++ b/controller/chirpotle/chirpotle/tools/__init__.py @@ -1,4 +1,4 @@ -from .helpers import filter_msg, lora_iterframes, lora_formatpayload, format_hexstring, FrameFilter, calc_lora_airtime, calc_lora_symboltime, seq_eq +from .helpers import filter_msg, lora_iterframes, lora_formatpayload, format_hexstring, FrameFilter, calc_lora_airtime, calc_lora_symboltime, calc_lora_minsnr, calc_lora_sensitivity, seq_eq from .prompts import prompt_bandwidth, prompt_frequency, prompt_module, prompt_spreadingfactor from .wormhole import LoRaWormhole, Rx2Wormhole, DownlinkDelayedWormhole from .beaconclock import next_beacon_ts diff --git a/controller/chirpotle/chirpotle/tools/helpers.py b/controller/chirpotle/chirpotle/tools/helpers.py index 6ef1589..13a26b6 100644 --- a/controller/chirpotle/chirpotle/tools/helpers.py +++ b/controller/chirpotle/chirpotle/tools/helpers.py @@ -1,5 +1,8 @@ import math import time + +from scipy.constants import Boltzmann + from chirpotle.dissect.base import LoRaWANMessage from typing import List @@ -118,6 +121,59 @@ def calc_lora_airtime(payload_length, spreadingfactor=7, bandwidth=125, t_payload = symbol_time * payload_symb_nb return t_payload + t_preamble +def calc_lora_bitrate(spreadingfactor=7, bandwidth=125, codingrate=5): + """ + Calculates the effective LoRa bitrate (ignoring preamble, header and CRC) + for a given spreading factor, bandwidth and coding rate. + + This value represents the maximum channel capacity if one would be able to + permanently stream data at the specific parameters. + + The returned value is in bit/s. + """ + symbol_time = calc_lora_symboltime(spreadingfactor, bandwidth) + bits_per_symbol = spreadingfactor + bit_per_sec = 1000 / symbol_time * bits_per_symbol + bit_per_sec_after_fec = bit_per_sec * (4/codingrate) + return bit_per_sec_after_fec + +def calc_lora_minsnr(spreadingfactor = 7): + """ + Returns the minimum demodulator SNR for a specific spreading factor + + Values from the SX1276 datasheet, section 4.1.1.2 + + Returns values in dBm + """ + return { + 6: -5.0, + 7: -7.5, + 8: -10.0, + 9: -12.5, + 10: -15.0, + 11: -17.5, + 12: -20.0, + }[spreadingfactor] + +def calc_lora_sensitivity(spreadingfactor = 7, bandwidth = 125, + rx_noise_figure = 6, temp_kelvin = 293): + """ + Returns the receiver sensitivity in dBm + + Calculation based on "AN1200.22: LoRa Modulation Basics", Chapter 4.2 + + :param spreadingfactor: The spreading factor used for transmission. Default: 7 + :param bandwidth: The bandwidth (kHz) used for transmission. Default: 125 + :param rx_noise_figure: Receiver architecture noise figure in dB, Default: 6 (for SX1272/76) + :param temp_kelvin: Temperature (Kelvin) of the receiver. Default: 293 (~20°C) + """ + noise_floor = 10 * math.log10( + Boltzmann + * temp_kelvin + * (bandwidth * 1000) + * 1000) + return noise_floor + rx_noise_figure + calc_lora_minsnr(spreadingfactor) + def seq_eq(seq1, seq2): it1=iter(seq1) it2=iter(seq2) diff --git a/controller/chirpotle/setup.py b/controller/chirpotle/setup.py index 7260a07..20cbaa2 100644 --- a/controller/chirpotle/setup.py +++ b/controller/chirpotle/setup.py @@ -13,6 +13,7 @@ 'crcmod==1.7', # CRC calculation (e.g. beacons) 'gpstime==0.3.3', # timestamps are GPS timestamps 'colorama==0.4.4',# Colorful text output in scripts + 'scipy==1.8.0', # Calculations of sensitiviy etc. ], scripts=[ 'scripts/beaconclock',