LoPy LoraWAN gateway with an ST LoraWAN device
I'm trying to connect a couple of Class-A ST devices to TTN using a LoPy LoraWAN gateway.
From the Gateway management page in TTN I see that the nano gateway receives the join request and forward it. Then it transmits the join confirmation received from TTN. But the ST device never receives it.
Debugging the ST code, I see that the device specifies join answer delays of 5 and 6 seconds, while, looking at the TTN log, the gateway appears to transmit the join answer after slightly more than 4 seconds (so before the 5 seconds). Is the log reliable? It the nano gateway intended to respect transmission windows?
Any other idea which could be the reason for ST device to fail receiving the join confirmation?
@berpast awesome I updated my project with your solution and it is working perfectly.
@berpast Thanks, tried to get it working all day. Your solution made the difference. Time for the next step.....
I think I found the culprit (and possibly this is the root cause of the issue reported in the last comment to: https://forum.pycom.io/topic/884/ttn-join-accept-not-handled-properly)
I'm using the latest firmware, and the error is caused by the lines:
stats = lora.stats()
self._push_data(self._make_node_packet(rx_data, self.rtc.now(), stats.rx_timestamp, stats.sfrx, stats.rssi, stats.snr))
stats.rx_timestamp is usually a time in the future. I added the following print line:
print("Data received, time:", time.ticks_us(), stats.rx_timestamp)
And while soon after reboot, the times are comparable, rx_timestamp tends continuously to drift in the future. As an example output:
Data received, time: 1109195579 1119221332
If you compare them, you have rx_timestamp about 10 seconds larger than the current time. This makes the join answer arrive too late.
I replaced stats.rx_timestamp with time.ticks_us() in the self._push_data function call and now the device is able to join.
It's normal to see the response appear in TTN before actual transmission, the packet includes a tmst field which tells the gateway when to actually transmit it (and starting point is the the tmst of the initial packet) so the time when TTN sends the packet doesn't matter*
(* as long as it's not too late - you must have a fast link from the gateway to TTN backend, any ping latency over 500ms will cause problems)
The nano gateway code then schedules the transmission using an Alarm:
nanogateway.py line 224:
self.uplink_alarm = Timer.Alarm(handler=lambda x: self._send_down_link(binascii.a2b_base64(tx_pk["txpk"]["data"]), tx_pk["txpk"]["tmst"] - 10, tx_pk["txpk"]["datr"], int(tx_pk["txpk"]["freq"] * 1000000)), us=t_us)
However that particular section of the code doesn't seem very 'bulletproof' to me. Would you mind sharing your TTN logs (the join request and accept responses) to help with this?