[(not)Solved] LoRa timing of LoPy and FiPy
-
Having seen a quite big variation in timing,m when it comes to the as nanogateway, I added a few markers in the code in the path from starting a socket send up to the point, when RF shows. For test I used both messages sent by a LoPy1/FiPy in LORA mode, and a LoPy as nanogateway. The table of results is below (all times in ms):
Most of the timing is consistent and has little variation. Two aspects are interesting:- at a certain point the message to be sent is placed in message queue, and pulled out of that by the LoraTask to be sent. This time between putting it into the queue and taking it out is consuming the variable time in the nanogateway (column 6 an 7). The LoraTask has a 1ms slice time, so that would be expected as variation (column 4 and 5).
- between the call of lora_send and adding a message of the queue, some extra code is executed on FiPy and LoPy4, configuring it to LoRa mode. This consumes 3-5 ms.
So the question is, why is dealing with the message queue so different between a simple sender and the nanogateway?
-
@sympatron ACK, so my tendency is to close that attempt.
-
@robert-hh To be fair the SX1276 is a bad choice for a gateway anyway because of it's limitations and I don't think the xxPy devices were designed for this use case...
-
@sympatron The idea was not to solve that problem in Python, but with a python call to cause a faster response to the internal message queue handling. At first glance, that seemed to work. But now I think that the message queue mechanism has to be re-done.
Alternatively we agree, that when using the xxPy devices as a gateway this is another limitation. The list would be:- single channel
- single datarate/coding settings
- no support for CFList
- downlink only with slow datarates (DR0 or DR1), or expected at the RX2 window, which uses a slow datarate.
- ......
-
@robert-hh So you are trying to get the timing right in Python? I thought it was something in the firmware.
I found Python to be extremely slow and too unreliable for anything timing related. And I don't think it will be possible to meet timing requirements of <10ms reliably with Python, because a lot of things happen in the background which have a higher priority, especially in the FiPy.Maybe an additional API function to send a packet with a delay would be a better solution? Although I don't know how complicated it would be to implement this.
-
@robert-hh Update: It looks as if this issue is actuall NOT solved, or it came back with a new firmware revision.
-
@robert-hh
Masterfully done. Thank you so much.
-
@robert-hh The issue closes. I had observed, that the send delays for responses on the nanogateway depends from the message size way more than expected, which is strange. A simple change to the nanogateway script changes that behavior (practically adding one line). The changed function is the one used for sending:
def _send_down_link(self, data, tmst, datarate, frequency): """ Transmits a downlink message over LoRa. """ self.lora.init( mode=LoRa.LORA, region=LoRa.EU868, frequency=frequency, bandwidth=self._dr_to_bw(datarate), sf=self._dr_to_sf(datarate), preamble=8, coding_rate=LoRa.CODING_4_5, tx_iq=True ) while utime.ticks_diff(utime.ticks_cpu(), tmst) > 0: pass self.lora_sock.settimeout(1) self.lora_sock.send(data) self.lora_sock.setblocking(False) self._log( 'Sent downlink packet scheduled on {:.3f}, at {:,d} Hz using {}: {}', tmst / 1000000, frequency, datarate, data )
The gamechanger is the line:
self.lora_sock.settimeout(1)
which changes the way the message queue deals with messages. With that change, the send delay only varies between 600µs and 1600µs, which is not perfect, but good enough for the moment, since the window the node waits for a response is ETA +/- 10ms, in which it must at least receive 5 bytes of the preamble.
Edit: For LoPy4 and FiPy the delay is between 5 and 7 ms, but still almost not dependent on the message length. That aligns with the table of times taken previously.