Author Topic: How to enforce and read ACK? [solved]  (Read 2919 times)

overlord

  • NewMember
  • *
  • Posts: 27
  • Country: de
How to enforce and read ACK? [solved]
« on: October 26, 2016, 02:43:57 PM »
Hello,

mayeb a stupid question, but how do I enforce an ACK by the sender from the receiver.
And how can I read the ACK? Lets say the receiver responds with some session Key?
Best Regards,
Rene

Felix

  • Administrator
  • Hero Member
  • *****
  • Posts: 6867
  • Country: us
    • LowPowerLab
Re: How to enforce and read ACK?
« Reply #1 on: October 26, 2016, 04:33:50 PM »
Look at the many RFM69 library examples. There is no ACK for an ACK.
Actually an ACK is just a regular (empty payload by default) packet with a special bit=TRUE which tells the sender the sent message was received.
You typically just use sendWithRetry(...) which allows you to retry a message several times (overridable) to ensure it is delivered.
A listening node that sees the ACK request bit = TRUE, will have to respond with an ACK packet.
If the link is good a single exchange will ensure the packet is delivered and ACK is returned to sender.
The end node can always send it's own packet and request an ACK from the main node, there is no constraint on who can send or request ACKs.

TomWS

  • Hero Member
  • *****
  • Posts: 1930
Re: How to enforce and read ACK?
« Reply #2 on: October 26, 2016, 08:13:47 PM »
Hello,

mayeb a stupid question, but how do I enforce an ACK by the sender from the receiver.
And how can I read the ACK? Lets say the receiver responds with some session Key?
Best Regards,
Rene
Not a stupid question at all.  There is virtually no documentation on ACK protocol so the 'good news is' you could invent your own.   The RFM69_ATC library uses ACK to send back the RSSI from the sender's last packet so that the original sender knows how much signal is getting through and adjust accordingly.  In another library, ACK is used to include a packet that tells the sender that the other end point has 'something' for it.  This allows the sender to contact the other end point and ask for whatever it may have to send, setting up a convenient two way conversation.

The method is simple, when a receiver sees a 'requestACK', it can send back a full packet along with the 'ACK'.  The original sender will be able to read that in the radio.DATA/radio.DATALEN tuple received with the ACK.

Tom


ssmall

  • Full Member
  • ***
  • Posts: 158
  • Country: us
Re: How to enforce and read ACK?
« Reply #3 on: November 13, 2016, 03:09:00 PM »
I am trying to do something similar in that I am sending data from a weather station to a gateway that receives the data.  The weather station uses radio.sendWithRetry.  The gateway receives the data and sends an ACK with no data and the weather station receives the ACK.  That all works great.  What I would like to do now is send data in the ACK and have the weather station receive the data in the ACK from the gateway.  So far I have not been able to receive the data in the ACK.

What am I missing?  radio.DATALEN is always zero.

Gateway code snippet
Code: [Select]
    if (radio.ACKRequested())
    {
        radio.sendACK("RST");
    }

Weather station code snippet
Code: [Select]
    if (radio.sendWithRetry(GATEWAYID, (const void*)(&remoteWeather),
                            sizeof(remoteWeather), 2, 75))
    {
      Serial.println("ACK received");

      Serial.println(radio.DATALEN);

      // Did a command to reset the rain amount arrive
      if (radio.DATALEN == 3)
      {
        Serial.println("ACK Data");
        if (radio.DATA[0]=='R' && radio.DATA[1]=='S' && radio.DATA[2]=='T')
        {
          // Reset the rain amount to zero
          rainAmount = 0.0;
        }
      }
    }

TomWS

  • Hero Member
  • *****
  • Posts: 1930
Re: How to enforce and read ACK?
« Reply #4 on: November 13, 2016, 06:37:06 PM »
To send data back with an ACK (and receive it) here is what I do:

On the Gateway side:
Code: [Select]
   radio.sendACK(&reqSomething,reqSomething.h.len);  // note that my packets have a header that includes a length field...

On the receive side:
Code: [Select]
  rc = radio.sendWithRetry(to, pkt, pkt->len);
  if (rc)
  {
    noInterrupts();  // this is necessary to prevent loss of data while copying
    // tranmission ok, see if any data was Ack'd
    if (radio.DATALEN && radio.DATALEN==radio.DATA[0]) // got a valid packet?  (validates packet if length field matches)
    {
      // yup, save it
      for (int i=0; i<radio.DATALEN; i++)
        sendAckData[i] = radio.DATA[i];
    }
      else
        sendAckData[0]=0;
    interrupts();
  } else
  {
    sendAckData[0]=0;
  }


Tom

ssmall

  • Full Member
  • ***
  • Posts: 158
  • Country: us
Re: How to enforce and read ACK?
« Reply #5 on: November 13, 2016, 08:31:13 PM »
Tom,

Thanks for the reply.  I can't believe I missed sending the length of the string.  :-[
I had been staring at the sendACK function for a 1/2 hr wondering why the string in the ACK wasn't show up!
I am receiving the data in the ACK now and I switched my code to copy the data to another variable.

Thanks!