Lorawan Lopy4: Change frequencies to 433 to 868 and (915) in a same script



  • Hi,

    for an application we have to change the frequencies of the lorawan chip from 433 to 868 back and forth. But the lopy crashes when you try to do that on the newest version of the firmware.

    A while ago @Gijs-Neerhof @Gijs provided me with an alternate version of the firmware, but the bug still exists on the main firmware. Any perspective when that is going to change?

    kind regards,
    Mo.

    import pycom
    import time
    import ubinascii, binascii
    import socket
    from network import LoRa, Bluetooth
    from helpers.decoder import decodeValue
    import ujson
    import utime
    from config import Config
    from services.serialinterface import Command
    
    maxTry = 5
    
    def joinFreqency(freq):
        config = Config()
        dev_eui, app_eui, app_key = "","",""
        datarate = 0
        if freq == 433:
            lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.EU433)
            dev_eui = ubinascii.unhexlify(config.get("DevEui433"))
            app_eui = ubinascii.unhexlify(config.get("AppEui433"))
            app_key = ubinascii.unhexlify(config.get("AppKey433"))
            datarate = 5
        elif freq == 868:
            lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.EU868)
            dev_eui = ubinascii.unhexlify(config.get("DevEui868"))
            app_eui = ubinascii.unhexlify(config.get("AppEui868"))
            app_key = ubinascii.unhexlify(config.get("AppKey868"))
            datarate = 5
        elif freq == 915:
            lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.US915)
            for index in range(0, 7):
                lora.remove_channel(index)
    
            for index in range(16, 72):
                lora.remove_channel(index)
            lora.add_channel(8, frequency=903900000, dr_min=0, dr_max=3)
            lora.add_channel(9, frequency=904100000, dr_min=0, dr_max=3)
            lora.add_channel(10, frequency=904300000, dr_min=0, dr_max=3)
            lora.add_channel(11, frequency=904500000, dr_min=0, dr_max=3)
            lora.add_channel(12, frequency=904700000, dr_min=0, dr_max=3)
            lora.add_channel(13, frequency=904900000, dr_min=0, dr_max=3)
            lora.add_channel(14, frequency=905100000, dr_min=0, dr_max=3)
            lora.add_channel(15, frequency=905300000, dr_min=0, dr_max=3)
            lora.add_channel(65, frequency=904600000, dr_min=4, dr_max=4)
    
            dev_eui = ubinascii.unhexlify(config.get("DevEui915"))
            app_eui = ubinascii.unhexlify(config.get("AppEui915"))
            app_key = ubinascii.unhexlify(config.get("AppKey915"))
            datarate = 3
    
        lora.join(activation=LoRa.OTAA, auth=(dev_eui, app_eui, app_key), timeout=0)
        lora.callback(trigger=(LoRa.RX_PACKET_EVENT | LoRa.TX_PACKET_EVENT), handler=lora_cb)
        count = 0
        WAIT_SEC = 5
    
        while not lora.has_joined():
            Command(63, {"wait": count, "total": maxTry})
            time.sleep(5)
            count +=1
            if  count > maxTry :
                Command(1025, {"frequency_failed":freq})
                return 0
    
        s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
        s.setsockopt(socket.SOL_LORA, socket.SO_CONFIRMED, datarate)
        s.setblocking(True)
        command = "test"
        config.set("latest_frequency", freq)
        s.send(command)
        s.setblocking(False)
    
        return freq
    
    
    def joinWithSocket(freq):
        config = Config()
    
    
        dev_eui, app_eui, app_key = "","",""
        datarate = 0
        if freq == 433:
            lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.EU433)
            dev_eui = ubinascii.unhexlify(config.get("DevEui433"))
            app_eui = ubinascii.unhexlify(config.get("AppEui433"))
            app_key = ubinascii.unhexlify(config.get("AppKey433"))
            datarate = 5
        elif freq == 868:
            lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.EU868)
            dev_eui = ubinascii.unhexlify(config.get("DevEui868"))
            app_eui = ubinascii.unhexlify(config.get("AppEui868"))
            app_key = ubinascii.unhexlify(config.get("AppKey868"))
            datarate = 5
        elif freq == 915:
            lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.US915)
            for index in range(0, 7):
                lora.remove_channel(index)
    
            for index in range(16, 72):
                lora.remove_channel(index)
            lora.add_channel(8, frequency=903900000, dr_min=0, dr_max=3)
            lora.add_channel(9, frequency=904100000, dr_min=0, dr_max=3)
            lora.add_channel(10, frequency=904300000, dr_min=0, dr_max=3)
            lora.add_channel(11, frequency=904500000, dr_min=0, dr_max=3)
            lora.add_channel(12, frequency=904700000, dr_min=0, dr_max=3)
            lora.add_channel(13, frequency=904900000, dr_min=0, dr_max=3)
            lora.add_channel(14, frequency=905100000, dr_min=0, dr_max=3)
            lora.add_channel(15, frequency=905300000, dr_min=0, dr_max=3)
            lora.add_channel(65, frequency=904600000, dr_min=4, dr_max=4)
    
            dev_eui = ubinascii.unhexlify(config.get("DevEui915"))
            app_eui = ubinascii.unhexlify(config.get("AppEui915"))
            app_key = ubinascii.unhexlify(config.get("AppKey915"))
            datarate = 3
        lora.join(activation=LoRa.OTAA, auth=(dev_eui, app_eui, app_key), timeout=0)
        lora.callback(trigger=(LoRa.RX_PACKET_EVENT | LoRa.TX_PACKET_EVENT), handler=lora_cb)
        count = 0
        WAIT_SEC = 10
    
        while not lora.has_joined():
            Command(63, {"wait": count, "total": maxTry})
            time.sleep(2.5)
            count +=1
            if  count > maxTry :
                Command(1025, {"frequency_failed":freq})
                return 0
        config.set("latest_frequency", freq)
        s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
        s.setsockopt(socket.SOL_LORA, socket.SO_CONFIRMED, datarate)
        return s
    
    
    


  • @robert-hh of course


  • Global Moderator

    I indeed discussed this bug before, it happens intermittently.

    The issue is caused by the OTAA part. As we send join requests every ~9 or so seconds, it takes the semaphore for the LoRa radio every so often. When you then re-initialize the LoRa to another frequency (or the same frequency for that matter), the semaphore can be either be in a taken state (which will make it wait forever) or not taken (which will make it work). The chance is about 50/50 from my experience, and you cannot really take it into account. If the device receives a join accept, there is no issue.

    The issue is not solved with setting a timeout though. While that does make the function blocking, it will keep sending join requests after that. Also that should be fixed in the next release.

    Indeed a machine.reset() will work and my fix at the time is now merged into the main branch, which will hopefully make it into the next release

    The fix is simply:

    #if defined(FIPY) || defined(LOPY4)
        xSemaphoreGive(xLoRaSigfoxSem);
    #endif
    

    At the top of lora_init_helper(...) of modlora.c and stopping the timer for the timeout.

    Best,
    Gijs



  • @peterp yeah that could be possible but a bit difficult to implement with our workflow. I am also available in chat.



  • @robert-hh Hi no every frequency change. so from 433 to 915 and every other combination.



  • @momo232030 Another question: Does the crash happen at all attempt to change the frequency or specifically between certain ones, like 433 to 868? Is switching between 868 and 915 possible?


  • Global Moderator

    @momo232030 said in Lorawan Lopy4: Change frequencies to 433 to 868 and (915) in a same script:

    Hi,

    for an application we have to change the frequencies of the lorawan chip from 433 to 868 back and forth. But the lopy crashes when you try to do that on the newest version of the firmware.

    I haven't looked into the issue at all, but just a quick thought: would it be possible to refactor your application to machine.reset() if you need to switch frequencies?



  • @momo232030 you surely know that you hsve to connect two antennas when using both the 433 and 868/ 915 MHz bands. Of course that is not related to your switching issue.


Log in to reply
 

Pycom on Twitter