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 calculation

    LoRa.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 :

    # 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.



Pycom on Twitter