Author Topic: Two way messaging - Adding a payload in ACKs [solution]  (Read 2430 times)

Creotom

  • NewMember
  • *
  • Posts: 21
Two way messaging - Adding a payload in ACKs [solution]
« on: November 23, 2018, 05:07:07 AM »
Hi all, I'm new to coding and I could do with being pointed in the right direction here.

I have a bank of relays that I am controlling successfully with 2 Moteino Megas.
The remote has the "struct_send" code on it and the receiver tied to the relays has the "struct_recieve" code on it.
With some relatively simple modification I have buttons I can press (momentary and latching) that will trigger the relays to drive a series of valves.

The receiver also has some sensors tied to it that are monitoring temperatures and pressures and valve states.
I would periodically like this sensor data relayed back to the transmitter so that I can display them to the operator.
This does not need to be updated as regularly as the button commands.
Once a second would be more than adequate.

From browsing this forum it looks like the best way to send this data back is to attach it to the "ACK".
Is this correct? I can't find an example of how this is done, I'm wondering if I have to tinker in the library which may be a bit above my skill set?

Thanks for hearing me out  :)


« Last Edit: November 26, 2018, 03:10:43 PM by Felix »

Felix

  • Administrator
  • Hero Member
  • *****
  • Posts: 6866
  • Country: us
    • LowPowerLab
Re: 2way messaging?
« Reply #1 on: November 23, 2018, 11:34:18 AM »
Did you see the TXRXBlinky example?

Creotom

  • NewMember
  • *
  • Posts: 21
Re: 2way messaging?
« Reply #2 on: November 24, 2018, 07:51:05 AM »
Hi Felix,

Thanks for your response. I just experimented with the code in TXRXBlinky and I feel I understand what it is doing.
However it leaves me with the same problem as before.
It is only sending an "ACK" back to the reciever.
I want to attach data to that "ACK". Unfortunately I can't find an example or description of how that is done yet.

Ideally I would like the receiver to say...
"Yes I got your instruction. Also here is some data that I have you might need to know about"

I'll keep trying though I know it's possible.

Creotom

  • NewMember
  • *
  • Posts: 21
Re: 2way messaging?
« Reply #3 on: November 24, 2018, 01:55:25 PM »
I think what I'm trying to do is in this post https://lowpowerlab.com/forum/moteino/sending-data-back-with-ack/.
I can't figure out how to implement it though.
Any ideas?


TomWS

  • Hero Member
  • *****
  • Posts: 1930
Re: 2way messaging?
« Reply #4 on: November 24, 2018, 02:12:15 PM »
I think what I'm trying to do is in this post https://lowpowerlab.com/forum/moteino/sending-data-back-with-ack/.
I can't figure out how to implement it though.
Any ideas?
The cited thread shows the side that receives the data in the Ack.  You also need to know how to send data with the Ack.  The good news is that this is pretty clear if you look, in the RFM69 library, at the method prototype for sendAck();   You will see that it optionally has databuf and datalen as arguments.  The node that 'Acks' simply fills this buffer (and length) to the returned data.

Tom

Creotom

  • NewMember
  • *
  • Posts: 21
Re: 2way messaging?
« Reply #5 on: November 24, 2018, 02:30:56 PM »
Thanks Tom,
Do you know if there is an example of this anywhere?
I've been at this all day and I'm still lost.
The code I cited wont compile so I'm sure there is something I'm missing.

Felix

  • Administrator
  • Hero Member
  • *****
  • Posts: 6866
  • Country: us
    • LowPowerLab
Re: 2way messaging?
« Reply #6 on: November 26, 2018, 01:20:42 PM »
Dear Creotom,
The prototype of the sendACK function is below:

Code: [Select]
virtual void sendACK(const void* buffer = "", uint8_t bufferSize=0);

The parameters are optional and empty by default. So when you call radio.sendACK() it simply sends back to the last sender, an empty message with the header ACK bit=1, so that original sender knows their sent message was received OK.

To send back a payload along with your ACK, simply do this:

Code: [Select]
radio.sendACK("myString", myStringLength)  //for a simple string
radio.sendACK(buffer, bufferLength)  //for any byte buffer

If you have a struct, then use it like this:

Code: [Select]
radio.sendACK((const void*)(&theData), sizeof(theData))

Note that for sending important data, it would be recommended to first send your empty ACK, then use sendWithRetry(...) to ensure it gets transmitted using retries.
The ACKs are special 1 time empty messages (no retries to ACKs) that should be kept as short as possible (ie not loaded with a lot of data), to help ensure they get transmitted as quickly as possible and don't spend a "lot of time" in the air (even a few ms extra can make a difference).

On the other end, provided the ACK message is received OK, you will can now check if you have a message using the usual ACKReceived() method:

Code: [Select]
if (radio.ACKReceived(toNodeId) && radio.DATALEN > 0) ...
where toNodeId is the node Id of the node that the original message was sent to, and from which the ACK was requested.
This call includes a check to receiveDone() so no need to call that again.
So you'd first call your send(toNodeId, buffer, length, 1), then check ACKReceived for up to 30-40 ms (should be sufficient). When the ACK is received, and it contains a payload then proceed to reading the payload as usual, using the radio.DATALEN and radio.DATA[ i ] buffer.

I hope this helps.
« Last Edit: November 26, 2018, 02:04:36 PM by Felix »

Creotom

  • NewMember
  • *
  • Posts: 21
Re: Two way messaging - Including payload in ACK
« Reply #7 on: November 26, 2018, 02:38:02 PM »
Thank you!