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, numbersymbolspayloadUsage 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.
-
@rcolistete
That's very useful. Thank you for for posting. -
@rcolistete very nice and usefull, values equal to TTN Data page. Thanks a lot
-
How do your calcs compare with
m=lora.stats() print('TxTime(ms)',m[7])
Hello! It looks like you're interested in this conversation, but you don't have an account yet.
Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.
With your input, this post could be even better 💗
Register Login