Variable transmission delay even when UART buffer is empty

I’m working with the XBee-Pro 900HP S3B modules for setting up a triggered sensor telemetry. I’m using a remote AT command request to set an IO pin on a remote trigger device. Critically, these AT remote requests have ACK off in the config bits in the hopes that the remote module stays silent. Also, along the lines of Disabling ACK and throughput , all frame IDs are 0, to avoid any Transmit Status API return frames.

To get reliable trigger timing, I’ve enabled CTS on the IO pin settings (DIO2) and set the smallest FT=0x11 (Flow control threshold) so that, to my understanding, CTS will go low when the XBee UART Rx buffer is empty. Theoretically, if I send my UART data packets after a CTS falling edge, the XBee’s UART Rx buffer is totally empty and I should get deterministic delay between the last byte of the remote AT command request leaving my sensor and the request arriving at my remote trigger.

And I do get this, but only if I send triggers at low frequency (~1Hz). The trigger delay is very reliable, consistent to about 0.5ms. Also, CTS never goes high when I use a 115200-baud serial link.

However, if I increase the data load on the module, the timing becomes much less reliable. As a simple example, sending trigger signals at high frequency (~50Hz) destabilizes this delay. In fact, only then does CTS start to go high, even when I obey CTS. Therefore, if FT is working as I expect, even though I always send to the XBee when its Rx buffer is empty and it’s totally idle, it slows down for no reason.

To me, there are only two things that can explain this:

  1. I’m misunderstanding the FT behavior: somehow, my configuration doesn’t pull CTS low when the buffer is totally empty. The docs read “It re-asserts CTS when less than FT-16 bytes are in the UART receive buffer.”, so I understood that as “it reasserts CTS (pulls it low) when the UART buffer has <(17-16)=1 byte in it, aka when the UART buffer is empty.”
  2. There is something causing delay in transmission, e.g. the antenna switches to receive when it needs to receive the ACK. That’s why I was trying to remove the ACK transmissions from the remote, but maybe I’ve missed something.

I’ve also confirmed that the remote triggers right as the local XBee’s UART Rx buffer empties (probing CTS on the local and the trigger IO pin on the remote: the remote triggers right as the local CTS goes low), so I am leaning to the second explanation. But I have no leads on what could be causing this delay.

There will be a delay in your packets being transmitted when you take into account the time it takes for the radio to packetize the data, check for clear airways, transmit the packet, receive the packet, verify that the packet is for that radio and process the data.

You may also need to look at the packet and make sure you are telling the radio to use it in the proper context. That is to say, if this is a simple point to point, then set the options bit to 0x40.

Thanks Eric. I completely understand that there is a delay, but the consistency of the delay is what I’m trying to control. When packets are sparse, the delay is very consistent. What I don’t understand is why the delay consistency suffers when the packet become denser, even when I only send when the UART Rx buffer is empty.

Correct my mental model, but if the transmitter doesn’t expect any return packets, and the receivers don’t send any, then once the transmission is done, I would like to be able to transmit immediately in the same way that I would if the transmission finished a second ago. The difference between those is what I’m trying to reconcile.

I also unset mesh unicast retries (MR=0), which I think has helped with the queue consumption. But there is still a send rate dependency on the delay.

As for transmission mode, for remote AT commands I don’t believe there is one. It confused me too, I assume that must be P2P?

Setting MR to 0 will not turn off retries. What over writes the modules Mesh function is the TO command and the options bit in the TX request frame. Setting these functions to a value of 0x40 tells the radio to use Point to point/multi-point mode. Also set RR to 0.