LoPy4 change uplink channels by itself?
-
Hi everyone, the problem I am having now is, LoPy4 changes uplink channels by itself.
Since my gateway only listens to 8 channels, I deleted all the CN470 channels and add 8 channels by doing this:
for i in range(0, 96):
lora.remove_channel(i)
#lora.bandwidth(LoRa.BW_125KHZ)
lora.add_channel(index=84, frequency=487100000, dr_min=0, dr_max=5)
lora.add_channel(index=85, frequency=487300000, dr_min=0, dr_max=5)
lora.add_channel(index=86, frequency=487500000, dr_min=0, dr_max=5)
lora.add_channel(index=87, frequency=487700000, dr_min=0, dr_max=5)
lora.add_channel(index=80, frequency=486300000, dr_min=0, dr_max=5)
lora.add_channel(index=81, frequency=486500000, dr_min=0, dr_max=5)
lora.add_channel(index=82, frequency=486700000, dr_min=0, dr_max=5)
lora.add_channel(index=83, frequency=486900000, dr_min=0, dr_max=5)
It works fine at the beginning. In the figure below you can see its sending uplinks using the 8 channels I added.
After LoPy4 wakes up from deep sleep, I use lora.nvram_save() and lora.nvram_restore() to restore LoRa's join status. However, LoPy4 will not send uplink using the 8 channels I added at the beginning. Instead, its sending uplinks on random channels in the CN470 frequency band. In the figure below, you can see it is using none of the channels I defined at the beginning.
In the documentation, it says that the lora.nvram_save can store the LoRaWAN state, but it looks like uplink channels information will not be saved?
So I disabled the lora.nvram_save and lora.nvram_restore, then I copied the "delete all the channels and add my own channels" code and pasted it to the place where LoPy4 just wakes up from deep sleep. But I had the same issues, which makes no sense.
Has anyone run into a similar problem?? Really appreciate if someone can give me some suggestions. Thank you!
-
@robert-hh Okay thanks, I will try this firmware, and test lora.remove_channel(i), then add channel AS923-2 freqs (921.4MHz & 921.6MHz ).
-
@Gusti-Made-Arya-Wijaya I added a 1.20.2.r6 version for LoPy4 with the cn470 channel remove fixed to
Shared stuff
. Maybe that one works.
-
@robert-hh yes, the bug in lora.remove_channel(i) is not fixed yet, I think lora.remove_channel(i) is not work in all regions. Need help to fix it, because in Indonesia using AS923-2
-
@Gusti-Made-Arya-Wijaya There is in the README.MD of the pycom-micropython-sigfox directory, and in the ESP32 port directory. It's tricky to set up the build environment. It has to be a Linux OS.
-
@robert-hh yes, I have tried it and tested my code like on previous page. Is there any guidance to build custom firmware?
-
@Gusti-Made-Arya-Wijaya There was this bug that
ora.remove_channel(i)
did not work for the CN470 region. I made a PR in Aug 2020 to fix that, but I cannot tell whether that was implemented. I do not see it in theRelease/v1.20
branch, which seems to be the most recent one, with the most recent change on Dec 6, 20121. The repository management of Pycom is byblack box
. With many branches of unclear usage.
-
@Gusti-Made-Arya-Wijaya Didn't you try already the firmware from
Shared Stuff
and it did not work? In that case, you have to change the source files and build your own firmware.
-
@Gusti-Made-Arya-Wijaya @robert-hh Hello Robert, Should I modify region.c file in ...../pycom-micropython-sigfox/lib/lora/mac/region then re-compile the firmware? or can use this firmware https://github.com/robert-hh/Shared-Stuff.git ?
-
@robert-hh hello, sorry for super late reply, I have tried it, but still can't join using gateway with AS923-2 freq plan, If I replace the gateway with AS923-1 freq plan, my Lopy4 can join. So the freq play from lopy4 is not change
-
@Gusti-Made-Arya-Wijaya Don't you have to call prepare_channels before lora.join()? And do you have a gateway in reach?
-
hello @robert-hh I have uploaded firmware from https://github.com/robert-hh/Shared-Stuff.git and then uploaded script that I posted previously. but my lopy4 still can't join AS923-2 (921.4MHz & 921.6MHz ).
-
@robert-hh Hello, any update on this? I have the same issue, I want to change the uplink/downlink channel from AS923 to AS923-2 (912.4Mhz and 921.6MHz) but Lopy4 still keep default channel. I've modified code from https://github.com/pycom/pycom-libraries/blob/master/examples/lorawan-regional-examples/main_AS923.py , here is my code
# # Copyright (c) 2019, Pycom Limited. # # This software is licensed under the GNU GPL version 3 or any # later version, with permitted additional terms. For more information # see the Pycom Licence v1.0 document supplied with this file, or # available at https://www.pycom.io/opensource/licensing # """ OTAA Node example as per LoRaWAN AS923 regional specification - compatible with the LoPy Nano Gateway and all other LoraWAN gateways - tested works with a LoRaServer, shall works on TTN servers """ from network import LoRa import socket import ubinascii import struct import time LORA_CHANNEL = 1 LORA_NODE_DR = 4 ''' utility function to setup the lora channels ''' def prepare_channels(lora, channel, data_rate): # AS923_FREQUENCIES = [ # { "chan": 1, "fq": "923200000" }, # { "chan": 2, "fq": "923400000" }, # { "chan": 3, "fq": "922200000" }, # { "chan": 4, "fq": "922400000" }, # { "chan": 5, "fq": "922600000" }, # { "chan": 6, "fq": "922800000" }, # { "chan": 7, "fq": "923000000" }, # { "chan": 8, "fq": "922000000" }, # ] AS923_FREQUENCIES = [ { "chan": 1, "fq": "922600000" }, { "chan": 2, "fq": "922400000" }, { "chan": 3, "fq": "922200000" }, { "chan": 4, "fq": "922000000" }, { "chan": 5, "fq": "921800000" }, { "chan": 6, "fq": "921600000" }, { "chan": 7, "fq": "921400000" }, { "chan": 8, "fq": "921200000" }, ] if not channel in range(0, 9): raise RuntimeError("channels should be in 1-8 for AS923") if channel == 0: import uos channel = (struct.unpack('B',uos.urandom(1))[0] % 7) + 1 for i in range(0, 8): lora.remove_channel(i) upstream = (item for item in AS923_FREQUENCIES if item["chan"] == channel).__next__() # set default channels frequency lora.add_channel(int(upstream.get('chan')), frequency=int(upstream.get('fq')), dr_min=0, dr_max=data_rate) return lora ''' call back for handling RX packets ''' def lora_cb(lora): events = lora.events() if events & LoRa.RX_PACKET_EVENT: if lora_socket is not None: frame, port = lora_socket.recvfrom(512) # longuest frame is +-220 print(port, frame) if events & LoRa.TX_PACKET_EVENT: print("tx_time_on_air: {} ms @dr {}", lora.stats().tx_time_on_air, lora.stats().sftx) ''' Main operations: this is sample code for LoRaWAN on AS923 ''' lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.AS923, device_class=LoRa.CLASS_C, adr=False, tx_power=20) # create an OTA authentication params # dev_eui = binascii.unhexlify('0000000000000000') # app_key = binascii.unhexlify('a926e5bb85271f2d') # not used leave empty loraserver.io # nwk_key = binascii.unhexlify('a926e5bb85271f2da0440f2f4200afe3') app_eui = ubinascii.unhexlify('**************') app_key = ubinascii.unhexlify('*******************') # join a network using OTAA # lora.join(activation=LoRa.OTAA, auth=(dev_eui, app_key, nwk_key), timeout=0, dr=2) # AS923 always joins at DR2 lora.join(activation=LoRa.OTAA, auth=(app_eui, app_key), timeout=0, dr=2) # AS923 always joins at DR2 prepare_channels(lora, LORA_CHANNEL, LORA_NODE_DR) # wait until the module has joined the network print('Over the air network activation ... ', end='') while not lora.has_joined(): time.sleep(2.5) print('.', end='') print('') # create a LoRa socket lora_socket = socket.socket(socket.AF_LORA, socket.SOCK_RAW) # set the LoRaWAN data rate lora_socket.setsockopt(socket.SOL_LORA, socket.SO_DR, LORA_NODE_DR) # msg are confirmed at the FMS level lora_socket.setsockopt(socket.SOL_LORA, socket.SO_CONFIRMED, 0) # make the socket non blocking y default lora_socket.setblocking(False) lora.callback(trigger=( LoRa.RX_PACKET_EVENT | LoRa.TX_PACKET_EVENT | LoRa.TX_FAILED_EVENT ), handler=lora_cb) time.sleep(4) # this timer is important and caused me some trouble ... for i in range(0, 1000): pkt = struct.pack('>H', i) print('Sending:', pkt) lora_socket.send(pkt) time.sleep(300) code_text
-
@sheng That's fine. I will then make a Pull Request for the fix of lora.remove_channel(). Because that did not work before.
-
@robert-hh It Finally Works! But I didn't use the lora.add_channel function, instead, I just remove all the channels I dont need. So its something like this.
for i in range(0, 79):
lora.remove_channel(i)
for i in range(88,96):
lora.remove_channel(i)
Again, thank you so much for your help and patience, I really appreciate it!
-
@sheng You could try to move the join before the channel reconfiguration. AFAIK, the channel udate is part of the join response,
-
@robert-hh I see what you mean, but I am using ChirpStack. I tried the method you provided, but I still have the same problem. After I upload the code to the board, it works fine, it only uses the eight channels I added. But after it went back from deep sleep, it started sending using random frequencies again, which is annoying.
It seems the lora_add_channel() is not working.
-
@sheng no. You have to remove all channels, like you did initially, because the ttn server can add channels by service messages. And these are the ones you see.
edit: My code change makes the call to lora.remove_channel() working, which it did not before.
-
@robert-hh Thank you for your help, but I am having the same problem even though I am using the firmware you provided. I didn't make any changes to the firmware. What I did is just flash my board with the firmware you provided, and then run the same code again(but this time, I didn't remove all the channels, I just add 8 channels). Am I doing it right? Or I understand it wrong. Do you mean I don't need to remove any channels? And I can just add the channels I am using with "lora.add_channel" if I am using the firmware you provided.
Again, thank you so much for your patience and time. Really appreciate it!
-
@sheng Right