Welcome to the Pycom forum Forum
    • \[\[global:header.categories\]\]
    • \[\[global:header.recent\]\]
    • \[\[global:header.tags\]\]
    • \[\[global:header.popular\]\]
    • Login

    Explore Pybytes | Official Documentation | Report a Firmware Bug/Issue | GitHub

    Has anyone successfully used lora.nvram_save() and restore?

    Scheduled Pinned Locked Moved LoPy
    lopyloranvram
    17 Posts 7 Posters 4.9k Views 9 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • bmarkusB Offline
      bmarkus @johncaipa
      last edited by

      @johncaipa said in Has anyone successfully used lora.nvram_save() and restore?:

      @jalperin @jmarcelino works but the counter is restarted on each send, this value is not stored?

      Unfortunately it is not possible to get or set your own FCnt value, otherwise it would be possible to handle in your code. Just one of the several missing LoRa/LoRaWAN functions.

      J 1 Reply Last reply Reply Quote 0
      • J Offline
        johncaipa @bmarkus
        last edited by

        @bmarkus in the documentation says that this value is saved, then I do not know what would be the problem, because in each sending after waking up the packet counters is always in 1 on TTN.
        "lora.nvram_save()
        Save the LoRaWAN state (joined status, network keys, packet counters, etc) in non-volatile memory in order to be able to restore the state when coming out of deepsleep or a power cycle."

        bmarkusB 1 Reply Last reply Reply Quote 0
        • bmarkusB Offline
          bmarkus @johncaipa
          last edited by

          @johncaipa said in Has anyone successfully used lora.nvram_save() and restore?:

          @bmarkus in the documentation says that this value is saved, then I do not know what would be the problem, because in each sending after waking up the packet counters is always in 1 on TTN.
          "lora.nvram_save()
          Save the LoRaWAN state (joined status, network keys, packet counters, etc) in non-volatile memory in order to be able to restore the state when coming out of deepsleep or a power cycle."

          Do you create a new instance when coming out? It resets the counter.

          J 1 Reply Last reply Reply Quote 0
          • J Offline
            johncaipa @bmarkus
            last edited by

            @bmarkus this is the example code I'm testing, based on which share @jalperin, I'm missing something?

            from network import LoRa
            import struct
            import binascii
            import time
            import math
            import pycom
            import socket
            from pysense import Pysense

            py = Pysense()
            loraSaved = pycom.nvs_get('loraSaved')
            print(loraSaved)
            if not loraSaved:
            lora = LoRa(mode=LoRa.LORAWAN)
            freq = 902300000
            for channel in range(0, 72):
            lora.remove_channel(channel)
            for chan in range(0, 8):
            lora.add_channel(chan, frequency=freq, dr_min=0, dr_max=3)

            dev_addr = struct.unpack(">l", binascii.unhexlify('************'.replace(' ','')))[0]
            nwk_swkey = binascii.unhexlify('************ 89 F1 74 79 40'.replace(' ',''))
            app_swkey = binascii.unhexlify('************ 3A AA BD E8 A9'.replace(' ',''))
            lora.join(activation=LoRa.ABP, auth=(dev_addr, nwk_swkey, app_swkey))
            while not lora.has_joined():
                machine.idle()
            s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
            s.setsockopt(socket.SOL_LORA, socket.SO_DR, 3)
            s.bind(3) #select the port number
            s.setblocking(False)
            s.send('LoRa Up')
            time.sleep(2)
            lora.nvram_save()
            pycom.nvs_set('loraSaved', 1)
            py.setup_sleep(60)
            py.go_to_sleep()
            

            else:
            lora = LoRa(mode=LoRa.LORAWAN)
            lora.nvram_restore()
            freq = 902300000
            for channel in range(0, 72):
            lora.remove_channel(channel)
            for chan in range(0, 8):
            lora.add_channel(chan, frequency=freq, dr_min=0, dr_max=3)
            s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
            s.setsockopt(socket.SOL_LORA, socket.SO_DR, 3)
            s.bind(3) #select the port number
            s.setblocking(False)
            s.send('LoRa Restored')
            time.sleep(2)
            lora.nvram_save()
            #pycom.nvs_set('loraSaved', 0) # reset for next test
            py.setup_sleep(60)
            py.go_to_sleep()

            1 Reply Last reply Reply Quote 0
            • R Offline
              rloro338
              last edited by

              I am trying to use lora.nvram_save() and lora.nvram_restore() and not works. I set all parameters (LoRaWAN, adr = True, app_eui, app_key and channel configuration) the first time that I boot the device and send a message Loriot server receive it. Then device go to deepsleep for 5 seconds and restore the join state. If I look the state with lora.has_joined() return True value, but when I trying to send the message it isn't received by the gateway.

              It is curious because when I use the node directly with a command line in Putty the restore and save comands works fine.

              What I am doing wrong??

              J 1 Reply Last reply Reply Quote 0
              • J Offline
                johncaipa @rloro338
                last edited by

                @rloro338 I made the following changes to my code and now it works correctly:

                • list item make sure the socket is blocking ( s.setblocking(True) )

                • list item add a time.sleep(2) after sending, before saving and going to deep sleep.

                1 Reply Last reply Reply Quote 0
                • B Offline
                  Bismarck501 @jmarcelino
                  last edited by

                  @jmarcelino Hello, I have read your suggestion carefully and tried in my project. But there was some issues about this solution.
                  My device consists of FiPy+pysense, and I connected to TTN via OTAA. My code with lora,nvram_save() and restore() is:

                  # pysense sensor part
                  from pysense import Pysense
                  from LTR329ALS01 import LTR329ALS01
                  from LIS2HH12 import LIS2HH12
                  
                  # FiPy part
                  from network import LoRa
                  import socket
                  import time
                  import pycom
                  import ubinascii
                  import machine
                  
                  # pysense machine part
                  from machine import RTC
                  from machine import SD
                  import os
                  
                  from network import WLAN, Bluetooth,LTE
                  
                  # set parameters for sensor function
                  py = Pysense()
                  lt = LTR329ALS01(py)  # only use light sensor
                  
                  
                  loraSaved = pycom.nvs_get('loraSaved')  # if join already, it is int 3; or it will be None
                  #-------------------------------- if already join -------------------------------------#
                  if (loraSaved == 11):
                  
                      lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.EU868)
                  
                      lora.nvram_restore()
                      #--------- Remove default channels ----------#
                      for index in range(0, 15):
                          lora.remove_channel(index)
                      lora.add_channel(3, frequency=867100000, dr_min=0, dr_max=5)
                      lora.add_channel(4, frequency=867300000, dr_min=0, dr_max=5)
                      lora.add_channel(5, frequency=867500000, dr_min=0, dr_max=5)
                      lora.add_channel(6, frequency=867700000, dr_min=0, dr_max=5)
                      lora.add_channel(7, frequency=867900000, dr_min=0, dr_max=5)
                  
                      lora.add_channel(8, frequency=868100000, dr_min=0, dr_max=5)
                      lora.add_channel(9, frequency=868300000, dr_min=0, dr_max=5)
                      lora.add_channel(10, frequency=868500000, dr_min=0, dr_max=5)
                      lora.add_channel(11, frequency=868700000, dr_min=0, dr_max=5)
                      lora.add_channel(12, frequency=868900000, dr_min=0, dr_max=5)
                  
                      lora.add_channel(13, frequency=869100000, dr_min=0, dr_max=5)
                      lora.add_channel(14, frequency=869300000, dr_min=0, dr_max=5)
                      lora.add_channel(15, frequency=869500000, dr_min=0, dr_max=5)
                  
                      print("Join already")
                      #--------------------------------------------------------------------------------#
                      #						Set LoRa parameters
                      # create a LoRa socket
                      s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
                      # set the LoRaWAN data rate
                      s.setsockopt(socket.SOL_LORA, socket.SO_DR, 5)
                  
                      #---------- Send uplink & Stroe uplink data ----------------#    
                      uplink_payload = ("Light: " + str(lt.light()))
                      s.setblocking(True)
                      s.send(uplink_payload)
                      lora.nvram_save()
                      print("send finish")
                      
                      #--------- Receive downlink & Stroe downlink data ----------#
                      s.setblocking(False)
                      downlink_message = s.recv(64) # bytes form     and     n is typically < 64 bytes
                      time.sleep(1)
                      print(downlink_message)
                      print(type(downlink_message))
                      print("Receive finish")
                  
                      #----------- Jugde whether there is a downlink -------------#
                      if downlink_message == b'':
                          print("There is no downlink")
                      else:
                          downlink_payload = downlink_message.decode('ascii') # string form
                          print("Downlink message: " + downlink_payload)
                          #-------- Judge downlink message & operate -------------#
                          if downlink_message == b'2': # if ==2, it will light green for 5 seconds
                              print("Hi, Green!")
                              pycom.rgbled(0x007f00) # green
                              time.sleep(3)
                          if downlink_message == b'4': # if ==4, it will light yellow for 5 seconds
                              print("Hi, Yellow!")
                              pycom.rgbled(0x7f7f00) # yellow
                              time.sleep(3)
                      print("####################################")
                      print("\n")
                  
                  #-------------------------------- if never join before -------------------------------------#
                  else:
                      print("Firstly join")
                      #--------------------------------------------------------------------------------#
                      # 					Initialise LoRa in LORAWAN mode.
                      lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.EU868)
                      #--------------------------------------------------------------------------------#
                      #				Set OTAA mode and connect with the gateway
                      # create an OTAA authentication parameters
                      app_eui = ubinascii.unhexlify('70B3D57ED0013E78')
                      app_key = ubinascii.unhexlify('5D87FAB0BC66A45FB0DA07453ED2BC2B')
                      # join a network using OTAA (Over the Air Activation)
                      lora.join(activation=LoRa.OTAA, auth=(app_eui, app_key), timeout=0)
                      # wait until the module has joined the network
                      while not lora.has_joined():
                          time.sleep(2.5)
                          print('Not yet joined...')
                      # join in
                      print('Successfully join in!')
                      #--------------------------------------------------------------------------------#
                      #						Set LoRa parameters
                      # create a LoRa socket
                      s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
                      # set the LoRaWAN data rate
                      s.setsockopt(socket.SOL_LORA, socket.SO_DR, 5)
                  
                      #---------- Send uplink & Stroe uplink data ----------------#
                      uplink_payload = ("Light: " + str(lt.light()))
                      s.setblocking(True)
                      s.send(uplink_payload)
                      lora.nvram_save()
                  
                      #--------- Receive downlink & Stroe downlink data ----------#
                      s.setblocking(False)
                      downlink_message = s.recv(64) # bytes form     and     n is typically < 64 bytes
                      #time.sleep(1)
                      print(downlink_message)
                      print(type(downlink_message))
                  
                      #----------- Jugde whether there is a downlink -------------#
                      if downlink_message == b'':
                          print("There is no downlink")
                      else:
                          downlink_payload = downlink_message.decode('ascii') # string form
                          print("Downlink message: " + downlink_payload)
                  
                          #-------- Judge downlink message & operate -------------#
                          if downlink_message == b'2': # if ==2, it will light green for 5 seconds
                              print("Hi, Green!")
                              pycom.rgbled(0x007f00) # green
                              time.sleep(3)
                          if downlink_message == b'4': # if ==4, it will light yellow for 5 seconds
                              print("Hi, Yellow!")
                              pycom.rgbled(0x7f7f00) # yellow
                              time.sleep(3)
                      print("####################################")
                      print("\n")
                      #---------- store in flush to judge next time ----------------#
                      pycom.nvs_set('loraSaved', 11)  
                  # time sleep
                  py.setup_sleep(9)   # setup a 9 seconds sleep time
                  py.go_to_sleep()
                  
                  
                  

                  And it can work well. However, after one day, when I tried again, there would be an issue when running code at line 65:

                      s.send(uplink_payload)
                  

                  3885de5c-2262-4686-b6bf-bedc703c6446-image.png

                  Where I was wrong? Thanks for giving me some advice!

                  J 1 Reply Last reply Reply Quote 0
                  • J Offline
                    jcaron @Bismarck501
                    last edited by

                    @Bismarck501 You should factorise your code a lot, it would make things a lot easier to maintain.

                    You shouldn't rely on an additional NVRAM variable to determine your LoRaWAN state.

                    Instead, just call nvram_restore, then has_joined. If not true, you need to join. Otherwise, you can go ahead and send/receive.

                    Also, I would call nvram_save after any interaction with the LoRaWAN stack is finished including the recv part. Not sure it currently causes any issues, but it's better to be consistent.

                    B 2 Replies Last reply Reply Quote 0
                    • B Offline
                      Bismarck501 @jcaron
                      last edited by

                      @jcaron Thanks for responsing so quick! I have tried your suggestion and it works now. And I will experiment further to eusure the stability. Now the code is:

                      # pysense sensor part
                      from pysense import Pysense
                      from LTR329ALS01 import LTR329ALS01
                      from LIS2HH12 import LIS2HH12
                      
                      # FiPy part
                      from network import LoRa
                      import socket
                      import time
                      import pycom
                      import ubinascii
                      import machine
                      
                      # pysense machine part
                      from machine import RTC
                      from machine import SD
                      import os
                      
                      from network import WLAN, Bluetooth,LTE
                      
                      # set parameters for sensor function
                      py = Pysense()
                      lt = LTR329ALS01(py)  # only use light sensor
                      
                      lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.EU868)   # itialise LoRa in LORAWAN mode.
                      lora.nvram_restore()
                      #-------------------------------- if never join before -------------------------------------#
                      if not lora.has_joined():
                          print("Firstly join")
                          #-------------------- use OTAA to connect with TTN ------------------------------#
                          app_eui = ubinascii.unhexlify('70B3D57ED0013E78')
                          app_key = ubinascii.unhexlify('5D87FAB0BC66A45FB0DA07453ED2BC2B')
                          lora.join(activation=LoRa.OTAA, auth=(app_eui, app_key), timeout=0) # join a network using OTAA (Over the Air Activation)
                          while not lora.has_joined():    # wait until the module has joined the network
                              time.sleep(2.5)
                              print('Not yet joined...')
                          # join in
                          print('Successfully join in!')
                      
                          #---------- Set LoRa parameters ----------------#
                          # create a LoRa socket
                          s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
                          # set the LoRaWAN data rate
                          s.setsockopt(socket.SOL_LORA, socket.SO_DR, 5)
                      
                          #---------- Send uplink & Stroe uplink data ----------------#
                          uplink_payload = ("Light: " + str(lt.light()))
                          s.setblocking(True)
                          s.send(uplink_payload)
                      
                          #--------- Receive downlink & Stroe downlink data ----------#
                          s.setblocking(False)
                          downlink_message = s.recv(64) # bytes form     and     n is typically < 64 bytes
                          #time.sleep(1)
                          print(downlink_message)
                          print(type(downlink_message))
                          lora.nvram_save()   # store in flush to judge next time
                      
                          #----------- Jugde whether there is a downlink -------------#
                          if downlink_message == b'':
                              print("There is no downlink")
                          else:
                              downlink_payload = downlink_message.decode('ascii') # string form
                              print("Downlink message: " + downlink_payload)
                              #-------- Judge downlink message & operate -------------#
                              if downlink_message == b'2': # if ==2, it will light green for 5 seconds
                                  print("Hi, Green!")
                                  pycom.heartbeat(False)
                                  pycom.rgbled(0x007f00) # green
                                  time.sleep(3)
                                  pycom.heartbeat(True)
                              if downlink_message == b'4': # if ==4, it will light yellow for 5 seconds
                                  print("Hi, Yellow!")
                                  pycom.heartbeat(False)
                                  pycom.rgbled(0x7f7f00) # yellow
                                  time.sleep(3)
                                  pycom.heartbeat(True)
                          print("####################################")
                          print("\n")
                      
                      #-------------------------------- if already join -------------------------------------#
                      else:
                          '''
                          #--------- Remove default channels ----------#
                          for index in range(0, 15):
                              lora.remove_channel(index)
                          lora.add_channel(3, frequency=867100000, dr_min=0, dr_max=5)
                          lora.add_channel(4, frequency=867300000, dr_min=0, dr_max=5)
                          lora.add_channel(5, frequency=867500000, dr_min=0, dr_max=5)
                          lora.add_channel(6, frequency=867700000, dr_min=0, dr_max=5)
                          lora.add_channel(7, frequency=867900000, dr_min=0, dr_max=5)
                      
                          lora.add_channel(8, frequency=868100000, dr_min=0, dr_max=5)
                          lora.add_channel(9, frequency=868300000, dr_min=0, dr_max=5)
                          lora.add_channel(10, frequency=868500000, dr_min=0, dr_max=5)
                          lora.add_channel(11, frequency=868700000, dr_min=0, dr_max=5)
                          lora.add_channel(12, frequency=868900000, dr_min=0, dr_max=5)
                      
                          lora.add_channel(13, frequency=869100000, dr_min=0, dr_max=5)
                          lora.add_channel(14, frequency=869300000, dr_min=0, dr_max=5)
                          lora.add_channel(15, frequency=869500000, dr_min=0, dr_max=5)
                          '''
                          print("Join already")
                          #---------------------------Set LoRa parameters-------------------------------------#
                          # create a LoRa socket
                          s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
                          # set the LoRaWAN data rate
                          s.setsockopt(socket.SOL_LORA, socket.SO_DR, 5)
                      
                          #---------- Send uplink & Stroe uplink data ----------------#
                          uplink_payload = ("Light: " + str(lt.light()))
                          s.setblocking(True)
                          s.send(uplink_payload)
                          print("send finish")
                      
                          #--------- Receive downlink & Stroe downlink data ----------#
                          s.setblocking(False)
                          downlink_message = s.recv(64) # bytes form     and     n is typically < 64 bytes
                          time.sleep(1)
                          print(downlink_message)
                          print(type(downlink_message))
                          lora.nvram_save()
                          print("Receive finish")
                      
                          #----------- Jugde whether there is a downlink -------------#
                          if downlink_message == b'':
                              print("There is no downlink")
                          else:
                              downlink_payload = downlink_message.decode('ascii') # string form
                              print("Downlink message: " + downlink_payload)
                      
                              #-------- Judge downlink message & operate -------------#
                              if downlink_message == b'2': # if ==2, it will light green for 5 seconds
                                  print("Hi, Green!")
                                  pycom.heartbeat(False)
                                  pycom.rgbled(0x007f00) # green
                                  time.sleep(3)
                                  pycom.heartbeat(True)
                              if downlink_message == b'4': # if ==4, it will light yellow for 5 seconds
                                  print("Hi, Yellow!")
                                  pycom.heartbeat(False)
                                  pycom.rgbled(0x7f7f00) # yellow
                                  time.sleep(3)
                                  pycom.heartbeat(True)
                          print("####################################")
                          print("\n")
                      
                      print("Deep sleep begin!")
                      # time sleep
                      py.setup_sleep(9)   # setup a 10 seconds sleep time
                      py.go_to_sleep()
                      #machine.deepsleep(9000)  # machine.deepsleep([milli_sec])
                      

                      Thanks a lot!

                      1 Reply Last reply Reply Quote 0
                      • B Offline
                        Bismarck501 @jcaron
                        last edited by

                        @jcaron The issue has been worked out and it works quite well now! Thanks a lot!

                        1 Reply Last reply Reply Quote 0

                        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
                        • 1 / 1
                        • First post
                          Last post

                        Pycom on Twitter

                        Pycom