Air Time calculation in (Micro)Python
-
As it is a common question how to calculate the air time of LoRa packets, so I post a Python 3/MicroPython script to calculate the data rate and airtime. Links about the calculations :
LoRa data rate calculator
LoRa air time calculator
Spreadsheet for LoRa airtime calculationLoRa.py (needed for Python3, not needed by Pycom MicroPython as it already has in 'network.LoRa' submodule)
BW_125KHZ = 0 BW_250KHZ = 1 BW_500KHZ = 2 CODING_4_5 = 1 CODING_4_6 = 2 CODING_4_7 = 3 CODING_4_8 = 4
# LoRaAirTimeCalc.py v0.1 (26/04/2018) for normal Python 3 (for PC) or Pycom MicroPython # By Roberto Colistete Jr (roberto.colistete at gmail.com) # from network import WLAN, LoRa # For Pycom MicroPython import LoRa # For Python3 import struct from math import ceil # Using Pycom constants for bw and cr, calculates the DR (datarate) in bps def dataratetheoretical(sf, bw, cr): if bw == LoRa.BW_125KHZ: bwv = 125 if bw == LoRa.BW_250KHZ: bwv = 250 if bw == LoRa.BW_500KHZ: bwv = 500 crv = 4/(4 + cr) return 1000*sf*bwv*(crv)/2**sf # Air time (in seconds) theoretical calculation for LoRa-RAW, where there is a default preamble of 8 bytes plus 5 bytes of CRC, etc def airtimetheoretical(payloadsize, sf, bw, cr): if bw == LoRa.BW_125KHZ: bwv = 125 if bw == LoRa.BW_250KHZ: bwv = 250 if bw == LoRa.BW_500KHZ: bwv = 500 if sf in [11,12]: lowDRopt = 1 else: lowDRopt = 0 tsym = (2**sf)/(bwv*1000) tpreamble = (8 + 4.25)*tsym # Preamble with 8 bytes numbersymbolspayload = 8 + max(ceil((8*payloadsize - 4*sf + 28 + 16)/(4*(sf - 2*lowDRopt)))*(4 + cr),0) tpayload = numbersymbolspayload*tsym tpacket = tpreamble + tpayload return tpacket, tpreamble, tpayload, tsym, numbersymbolspayload
Usage example (within ipython3), the first number is the airtime in seconds :
In [1]: from LoRaAirTimeCalc import * In [2]: airtimetheoretical(20, 10, LoRa.BW_125KHZ, LoRa.CODING_4_5) Out[2]: (0.37068799999999996, 0.100352, 0.27033599999999997, 0.008192, 33)
Another example, showing the airtime in ms (miliseconds) :
In [1]: from LoRaAirTimeCalc import * In [2]: [(payloadsize, airtimetheoretical(payloadsize, 8, LoRa.BW_125KHZ, LoRa.CODING_4_5)[0]*1000) for payloadsize in range(1, 33)] Out[2]: [(1, 51.711999999999996), (2, 51.711999999999996), (3, 61.952), (4, 61.952), (5, 61.952), (6, 61.952), (7, 72.19200000000001), (8, 72.19200000000001), (9, 72.19200000000001), (10, 72.19200000000001), (11, 82.432), (12, 82.432), (13, 82.432), (14, 82.432), (15, 92.672), (16, 92.672), (17, 92.672), (18, 92.672), (19, 102.91199999999999), (20, 102.91199999999999), (21, 102.91199999999999), (22, 102.91199999999999), (23, 113.15199999999999), (24, 113.15199999999999), (25, 113.15199999999999), (26, 113.15199999999999), (27, 123.392), (28, 123.392), (29, 123.392), (30, 123.392), (31, 133.632), (32, 133.632)
In this GitLab repository/folder "LoRaAirTimeCalc" it has better documentation and examples.
-
How do your calcs compare with
m=lora.stats() print('TxTime(ms)',m[7])
-
@rcolistete very nice and usefull, values equal to TTN Data page. Thanks a lot
-
@rcolistete
That's very useful. Thank you for for posting.