LoPy and nanogateway example: Inaccurate timing prevent OTAA join
-
This is a continuation of this post https://forum.pycom.io/topic/2676/abp-mode-and-frame-counters/18
It drifted away from the initial topic too far. The result form this topic was:
The node had pretty good timing, but the gateway delivers downlink messages from the TTN server too late. Some further obervations:
a) The downlink message form the TTN server with the join accept arrives at the gateway early enough (like 1 second before it's about to be sent)
b) A simple timing test using utime.ticks_us() and and utime.ticks_diff() to create a 5000ms pulse creates a 5025ms pulse, too late for the tight TTN timing constraints.
c) Additionally, the gateway determines time difference by subtracting time stamps, instead of using ticks_diff(). That may lead to lockouts. But that's another story. -
@robert-hh @jmarcelino Problem solved. The reason was the inaccurate timing of ticks_us(). I changed that to use the CPU clock. It reads now as:
#define CLK_FREQ (APB_CLK_FREQ / 2) STATIC mp_obj_t time_ticks_us(void) { return mp_obj_new_int_from_uint((uint32_t)(get_timer_counter_value()/(CLK_FREQ / 1000000))); } STATIC MP_DEFINE_CONST_FUN_OBJ_0(time_ticks_us_obj, time_ticks_us);Since the sx127x drivers need the same clock source, these drivers also have to be changed accordingly. As a result, join now works even with the default 10ms RxError setting.
Picture below. Greed is the receive window, with the raising edge at the start of the 26 ms window (since join is successful, it does not go low). Yellow is the RF at the gateway antenna.

There is still some variation, but all joins worked, at least at the second attempt. -
@robert-hh
Really good finding as always -
Hi Robert,
That is awesome, thanks for the investigation. I guess the change also needs to be applied here:
https://github.com/pycom/pycom-micropython-sigfox/blob/master/drivers/sx127x/sx1272/sx1272.c#L1076
and here:
https://github.com/pycom/pycom-micropython-sigfox/blob/master/drivers/sx127x/sx1276/sx1276.c#L1241
Correct?
Cheers,
Daniel -
@daniel Yes, these are the two places which I changed too.
-
@daniel While changing tick_us(), we could also change ticks_ms() to be based on the same timer. It's a 64 bit quantity, so the basic timer will not overflow, before ticks_ms() does. Actually, it will not overflow within ~ 14000 years, at which time it might not matter.
-
@daniel Yes, these are the two places which I changed too.
You are right, I read it too quickly and missed it.
@daniel While changing tick_us(), we could also change ticks_ms() to be based on the same timer. It's a 64 bit quantity, so the basic timer will not overflow, before ticks_ms() does. Actually, it will not overflow within ~ 14000 years, at which time it might not matter.
Makes sense!
-
@daniel @jmarcelino Jose suggested another approach for the ticks_us() function, similar to the ticks_ms() one, which is:
STATIC mp_obj_t time_ticks_us(void) { struct timeval tv; gettimeofday(&tv, NULL); return mp_obj_new_int_from_uint(((tv.tv_sec * 1000000) + tv.tv_usec)); }But since that one is already implemented in esp32_mphal.c, one could simply use:
STATIC mp_obj_t time_ticks_us(void) { return mp_obj_new_int_from_uint(mp_hal_ticks_us()); }As simple loop test, creating square wave with 5 s period, resulted in period times of 5.00015 to 5.00020 s for all three variants. Besides the extra call level, then using what's already there seems most elegant.
The test with the nanogateway also succeeded.
Edit: There are also a mp_hal_ticks_ms() and mp_hal_ticks_s() -
Can you please tell me which file should i change for the gateway ?
This issue drives me mad in the last half an year. -
@kiromn The timing issue in the firmware should be solved in V1.17.3.b1. At least that one works for me. It needs the updated nanogateway example form the lib repository, which according to my tests is still off by 10 ms.
You can also try the version I am using myself, which is here:
https://github.com/robert-hh/pycom-libraries/blob/nanogateway/examples/lorawan-nano-gateway/nanogateway.py
You might have to adapt it to your region. There is a definition of WINDOW_COMPENSATION at the begin, which is set to -10ms, to cope with the 10 ms delay I see. The standard code would have that set to 0 (if it would exist). -
@robert-hh Thanks for the reply. Now the client associates with the gateway, but after that the packets are not relayed to the network. I get like every 16th packet relayed. The gateway and the client are 5 meters away and the client works with other gateways without issues (esp8266+RN2483A)
In the gateway console i cant see the packet from the client.
Also there is no Window_compensation in the code.
The only related code here is:
UDP_THREAD_CYCLE_MS = const(10)
WDT_TIMEOUT = const(120000)
COMPENSATION_SLOPE = const(-4176)
COMPENSATION_OFFSET = const(-1667) -
@kiromn That's antoher effect, cause by the gateway being singel channel only. After joining, you have to delete in the node script every channel but the first. There was some communication about that in the forum, maybe hard to find. Like:
# remove all channels but the first for i in range(1, 3): lora.remove_channel(i)Edit: I changed the gateway script yesterday, such that the delay compensation adapts to different downlink message lengths.
-
No luck with disabling channels also.
-
@kiromn Interesting. I can try this evening again.
For my tests, I usually use ABP join, by transferring the device ID and keys from a previous OTAA join. The keys can be taken form the TTN server console. -
@kiromn I can confirm your observation. After OTAA join, only few of the messages are captured by the Lopy gateway. A second gateway based on an IC880a receives all messages.
using ABP activation and disabling all channels but one, all messages are receievd by the LoPy gateway. -
@robert-hh I have tried disabling channels, changing port, but it does not work. Do you think you will be able to fix it? I can help with testing :)
-
@kiromn did you use OTAA join or ABP join?
-
@robert-hh i use OTAA
-
@kiromn I have again used OTAA join and have sent 10 packets. Below if a screen dump of the TTN console. Only 5 of the 10 packets were seen by my Lopy based gateway. The IC880A gateway has seen them all. You see, that the other packets have been sent at other frequencies, which have been submitted in the join response. At least its SF7BW125. So unless the node cannot be forced to ignore these other frequencies, the nanogateway will not catch them.

-
@robert-hh Yep i see. So, this gateway is not very usable.
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