Issue sending packets with lopy4 after deep sleep

Hi everyone,
I’ve been through a lot of forum to try and find a solution before posting my problem but didn’t manage to find it.
So here is the deal, I’m trying to send packets via LoRa Wan from my Lopy4 using The Things Indoor Gateway. It works pretty fine if I do it without deep sleep, but I need to use deep sleep because I want my application to run longer. I’m calling lora.nvram_save() before deep sleep and lora.nvram_restore() after instancianting lora object at the begining of my script. The firts time it works well and I can see my data on TTN, but after deep sleep none of my packet arrive to my application in TTN.
Here is my code :

#***********************************************************************
#*****
#*****			INITIALISATION
#*****
#***********************************************************************

#-----------------------------------------------------------------------
#     			IMPORTS / INCLUDE
#-----------------------------------------------------------------------

import pycom
import time
from network import LoRa
import socket
import machine
from machine import Pin
import binascii

import dht

#-----------------------------------------------------------------------
#     			DEFINITION DES CONSTANTES
#-----------------------------------------------------------------------

#-----------------------------------------------------------------------
#     			FONCTIONS COMMUNES QUI SERONT APPELEES
#-----------------------------------------------------------------------
pycom.wifi_on_boot(False) #pour eviter crash
#***********************************************************************
#*****
#*****			CONFIGURATION
#*****
#***********************************************************************
pycom.heartbeat(False)
#-----------------------------------------------------------------------
#     			INSTANCIATIONS
#-----------------------------------------------------------------------

th  = dht.DTH(Pin('P22', mode=Pin.OPEN_DRAIN),1)
# initialize LoRa in LORAWAN mode.
# Please pick the region that matches where you are using the device:
# Asia = LoRa.AS923
# Australia = LoRa.AU915
# Europe = LoRa.EU868
# United States = LoRa.US915
#SF=[7;12] répartir les SF entre les capteurs
LORA_NODE_DR = 5

if machine.reset_cause() == machine.DEEPSLEEP_RESET:
    lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.EU868,sf=7,bandwidth=LoRa.BW_125KHZ)
    lora.nvram_restore()
    s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
    s.setsockopt(socket.SOL_LORA, socket.SO_DR, LORA_NODE_DR)
    s.setblocking(False)
    s.bind(2)

else:
    lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.EU868,sf=7,bandwidth=LoRa.BW_125KHZ)
    app_eui = binascii.unhexlify('70BXXX25718') #unique pour l'application
    app_key = binascii.unhexlify('07A6599XXXXXXXX1') #a changer pour chaque capteur
    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 joined yet first time")

    s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
    s.setsockopt(socket.SOL_LORA, socket.SO_DR, LORA_NODE_DR)
    s.setblocking(False)
    s.bind(1)

# set the 3 default channels to the same frequency (must be before sending the OTAA join request)
lora.add_channel(0, frequency=868100000, dr_min=0, dr_max=5)
lora.add_channel(1, frequency=868100000, dr_min=0, dr_max=5)
lora.add_channel(2, frequency=868100000, dr_min=0, dr_max=5)
# remove all the non-default channels
for i in range(3, 16):
    lora.remove_channel(i)


#***********************************************************************
#*****
#*****			BOUCLE PRINCIPALE
#*****
#***********************************************************************

def run():

    result = th.read()
    s.send(str(result.temperature))
    pycom.rgbled(0xff00) #led verte après envoi de message
    time.sleep(0.4)
    pycom.rgbled(0x0000)
    return 0

run()
#reset au bout de 20 sec
lora.nvram_save()
s.close()
machine.deepsleep(20000)

I feel I have tried everything and done the same thing as everybody in the forums but it doesn’t work for me… I’m a bit lost and hope I have a very stupid mistake, if you could help me it would be very nice :slight_smile:

here is my application on TTN, we can see I receive the first message, but then nothing is received…
ttn

I also tried to use an other SF, but the join request and join accept are always send on SF7 BW125kHz…
If we look at the traffic going through my gateway :
ttn%20bug

Thanks in advance

1 Like

Why are we seeing such different timestamps in the screenshots, 17:00 and 09:50?

First, assuming at least one of the screenshots was indeed captured after the deep sleep: you’re seeing many OTAA Join Requests (which are accepted by TTN, so probably should work), but you should not re-join after a deep sleep. In general, a device should only join once after getting new batteries or new software, so only once or a few times in its lifetime. (Doing a join after every deep sleep is both a waste of airtime, and at some point OTAA join nonces will be re-used, which is not allowed, which will make TTN reject the request.)

Now, given if machine.reset_cause() == machine.DEEPSLEEP_RESET I’d not expect it to re-join at all. Can you somehow confirm which part of the code is executed, like by adding some print statements?

Also, though unrelated to your problem:

This is a full gateway, so there should be no need to limit your node to only 868100000. (Also, the comment “must be before sending the OTAA join request” does not seem to match the actual code?)

Thanks for your answer :wink:

We are seeing such different timestamps because the pictures weren’t taken at the same time cause I’ve been working on it but didn’t manage to find a solution, and as the problem remained the same I took other pictures to proove I did try to find a solution myself…

Yes indeed we see many join request that are almost immediatly accepted but the node continues to send join request and never seemed to know he was accepted…

I have 5 Lopy4 in my possession, 2 worked well with my code, they are all updated to the last firmware. The code is exactly the same except app_key that changes every node. For the nodes that are not working, I also tried with a PySense instead of an expansion board, but still the same issue, the first join accept works and it sends the first packet, but after deep sleep the node believes it’s still connected to LoRa but the gateway doesn’t see his packet.

Here is my updated code :

#***********************************************************************
#*****
#*****			INITIALISATION
#*****
#***********************************************************************

#-----------------------------------------------------------------------
#     			IMPORTS / INCLUDE
#-----------------------------------------------------------------------

import pycom
import time
from network import LoRa
import socket
import machine
from machine import Pin
import binascii

import dht
from pysense import Pysense

#-----------------------------------------------------------------------
#     			DEFINITION DES CONSTANTES
#-----------------------------------------------------------------------

#-----------------------------------------------------------------------
#     			FONCTIONS COMMUNES QUI SERONT APPELEES
#-----------------------------------------------------------------------
pycom.wifi_on_boot(False) #pour eviter crash
#***********************************************************************
#*****
#*****			CONFIGURATION
#*****
#***********************************************************************
pycom.heartbeat(False)
#-----------------------------------------------------------------------
#     			INSTANCIATIONS
#-----------------------------------------------------------------------

py = Pysense()
th  = dht.DTH(Pin('P4', mode=Pin.OPEN_DRAIN),1)
# initialize LoRa in LORAWAN mode.
# Please pick the region that matches where you are using the device:
# Asia = LoRa.AS923
# Australia = LoRa.AU915
# Europe = LoRa.EU868
# United States = LoRa.US915
#SF=[7;12] répartir les SF entre les capteurs
LORA_NODE_DR = 4
lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.EU868,sf=8,bandwidth=LoRa.BW_125KHZ)
lora.nvram_restore()
#if machine.reset_cause() == machine.DEEPSLEEP_RESET:
if lora.has_joined():
    print("join not first time")
    s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
    s.setsockopt(socket.SOL_LORA, socket.SO_DR, LORA_NODE_DR)
    s.setblocking(False)
else:
    app_eui = binascii.unhexlify('XXXXXXX') #unique pour l'application
    app_key = binascii.unhexlify('XXXXXXXXXXXXXX') #a changer pour chaque capteur
    # set the 3 default channels to the same frequency (must be before sending the OTAA join request)
    lora.add_channel(0, frequency=868100000, dr_min=0, dr_max=5)
    lora.add_channel(1, frequency=868100000, dr_min=0, dr_max=5)
    lora.add_channel(2, frequency=868100000, dr_min=0, dr_max=5)
    # remove all the non-default channels
    for i in range(3, 16):
        lora.remove_channel(i)
    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(5)
        print("not joined yet first time")
    s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
    s.setsockopt(socket.SOL_LORA, socket.SO_DR, LORA_NODE_DR)
    s.setblocking(False)

#***********************************************************************
#*****
#*****			BOUCLE PRINCIPALE
#*****
#***********************************************************************

def run():
    result = th.read()
    s.send(str(result.temperature))
    pycom.rgbled(0xff00) #led verte après envoi de message
    time.sleep(0.4)
    pycom.rgbled(0x0000)
    data = s.recv(64)
    print(data)
    return 0

run()

#reset au bout de 20 sec
lora.nvram_save()
#machine.deepsleep(20000)

py.setup_sleep(10) #temps en secondes
py.go_to_sleep()

So, deep sleep works well for those? And you’re sure it’s not doing a new Join Request after deep sleep for those?

That’s not what you showed in the earlier screenshots, which show Join Requests, so the device did not think it was connected.

We need much more detail to help. Like what do the print statements show you now, for both the working nodes and the troublesome ones? And what do you see in TTN Console, related to that print output?

Please show some structured debug information from the first start, successful join, successful first packet, deep sleep, and whatever happens then. And repeat that for both the working node and the non-working one.

(Also, the updated code still limits your device to only 868100000. Even more: it now also does that for the join. All that is not needed with the 8 channel gateway you have.)