Understanding radio.sendWithRetry

Started by hokahonay, December 23, 2015, 07:25:16 AM

hokahonay


Hi all
i am having problems understanding radio.sendWithRetry and hoping someone can shed some light.
in the library radio.sendWithRetry looks for ACK_RECEIVED to return either true or false, retryWaitTime is the period between sends / retrys
Question:
does the RFM69 use the same internal buffer for both send and receive, it apears from my findings that it does.
If i answer with ACK before reading data etc then when i come to read the data the buffers are empty so this is fundamental to my question

if i read the buffers before sending ACK this means that the first and subsequent retrys must be dependant
on the time it takes to read the buffers on the receiver i.e. if the time to read buffers is greater than retryWaitTime the
retry will be sent before ACk can be sent by the receiver.
depending on time taken to read the buffers this can mean that sendWithRetry will always return false ??
is this right or do i have a hole in my knowledge
i feel i must be missing something ..... somewhere
RFM is a brilliant bit of kit and i would like to understand both it and the library better

thanks
Dave

TomWS

Quote from: hokahonay on December 23, 2015, 07:25:16 AM

Hi all
i am having problems understanding radio.sendWithRetry and hoping someone can shed some light.
in the library radio.sendWithRetry looks for ACK_RECEIVED to return either true or false, retryWaitTime is the period between sends / retrys
Question:
does the RFM69 use the same internal buffer for both send and receive, it apears from my findings that it does.
If i answer with ACK before reading data etc then when i come to read the data the buffers are empty so this is fundamental to my question

if i read the buffers before sending ACK this means that the first and subsequent retrys must be dependant
on the time it takes to read the buffers on the receiver i.e. if the time to read buffers is greater than retryWaitTime the
retry will be sent before ACk can be sent by the receiver.
depending on time taken to read the buffers this can mean that sendWithRetry will always return false ??
is this right or do i have a hole in my knowledge
i feel i must be missing something ..... somewhere
RFM is a brilliant bit of kit and i would like to understand both it and the library better

thanks
Dave
It seems your question is more about the receiving end than the sending of the connection.  But, to answer your question, IF you receive a packet that requests ACK, your MUST save the data prior to sending the ACK.  Since the packets are small, SAVING the data for later processing is no problem.  DOING something with the data prior to sending ACK will potentially lose the retry timeout race.  In that case, IF the sender is using sendWithRetry() the sender will, in fact, resend the packet.   Now you've really got a dilemma!

So, the best thing is, tuck away incoming data as soon as it come in - that includes all relevant information like DATA, DATALEN, SENDERID, etc.  before sending ACK because, as you've observed, once you send the ACK, the received data gets dumped.  Do this quickly - (I don't know why we continue to provide examples that show serial printing incoming data BEFORE sending ACK, it's a very bad practice.) - send the ACK, and then process the incoming data at your leisure.    You will save a lot of time and power doing this - on the receiving end you don't get multiple packets and on the sending end you get your ACK as soon as possible and you don't do multiple TX.

Tom

hokahonay

#2
hi Tom
thank you for the reply
What you describe is what I was seeing, i.e. a second packet being received.
This led me to looking deeper and doing some measurements, the lines of code:
  source = radio.SENDERID;  target = radio.TARGETID;
  rssi = radio.RSSI; messageR = "";
  for (uint8_t i=0; i<radio.DATALEN; i++) {
  messageR += char(radio.DATA[i]); }

takes less than 1mS at 16Mhz, a lot quicker than I expected so even 5mS is plenty for retryWaitTime
while I agree about the Serial.prints in the examples it could be said that they are there only as examples
once you get into it with a little deeper you soon start learning the finer points which makes them easier to remember
thanks again
Dave

syrinxtech

Quote from: TomWS on December 23, 2015, 07:56:50 AM
Quote from: hokahonay on December 23, 2015, 07:25:16 AM

Hi all
i am having problems understanding radio.sendWithRetry and hoping someone can shed some light.
in the library radio.sendWithRetry looks for ACK_RECEIVED to return either true or false, retryWaitTime is the period between sends / retrys
Question:
does the RFM69 use the same internal buffer for both send and receive, it apears from my findings that it does.
If i answer with ACK before reading data etc then when i come to read the data the buffers are empty so this is fundamental to my question

if i read the buffers before sending ACK this means that the first and subsequent retrys must be dependant
on the time it takes to read the buffers on the receiver i.e. if the time to read buffers is greater than retryWaitTime the
retry will be sent before ACk can be sent by the receiver.
depending on time taken to read the buffers this can mean that sendWithRetry will always return false ??
is this right or do i have a hole in my knowledge
i feel i must be missing something ..... somewhere
RFM is a brilliant bit of kit and i would like to understand both it and the library better

thanks
Dave
It seems your question is more about the receiving end than the sending of the connection.  But, to answer your question, IF you receive a packet that requests ACK, your MUST save the data prior to sending the ACK.  Since the packets are small, SAVING the data for later processing is no problem.  DOING something with the data prior to sending ACK will potentially lose the retry timeout race.  In that case, IF the sender is using sendWithRetry() the sender will, in fact, resend the packet.   Now you've really got a dilemma!

So, the best thing is, tuck away incoming data as soon as it come in - that includes all relevant information like DATA, DATALEN, SENDERID, etc.  before sending ACK because, as you've observed, once you send the ACK, the received data gets dumped.  Do this quickly - (I don't know why we continue to provide examples that show serial printing incoming data BEFORE sending ACK, it's a very bad practice.) - send the ACK, and then process the incoming data at your leisure.    You will save a lot of time and power doing this - on the receiving end you don't get multiple packets and on the sending end you get your ACK as soon as possible and you don't do multiple TX.

Tom

Thanks TomWS.  No matter how many times it gets said, sometimes hearing the basics, clearly stated, helps reinforce good habits.