Transmission acknowledgement

Hello

Has anyone tried to make the communication between for example a pulse counting emontx and a Raspberry Pi two way, so that the Raspberry acknowledges that it received the transmission?

Considering the general flakiness of wireless transmissions, wouldn't this be a good idea? Would complicate things a bit of course, but should be possible.

PaulOckenden's picture

Re: Transmission acknowledgement

The JeeLib library fully supports ACK'ed transmission. Take a look at the RF12 Demo sketch, the 's' command is for normal send and the 'a' command is for a send and ACK.

P.

o_cee's picture

Re: Transmission acknowledgement

Thanks, found some info and will give it a try.

http://jeelabs.org/2010/12/11/rf12-acknowledgements/

Robert Wall's picture

Re: Transmission acknowledgement

I believe it has never been done because the emonTx is designed to be able to run on batteries. If it had to stay awake to receive an acknowledgement, then battery life would suffer. Clearly that is not an issue with mains power.

o_cee's picture

Re: Transmission acknowledgement

Good point, although why can't it go to sleep after receiving ack? There should be a fairly minimal delay, no?

TheBluProject's picture

Re: Transmission acknowledgement

Hi @ll. 

@Rob I'm running my one (EmonTX) with ACKs since the beginning of Dec, and so far so good - 2965mV

@o_cee : That's pretty straightforward. Add this at the beginning of the EmonTX sketch:

#define RETRY_PERIOD 5    // How soon to retry (in seconds) if ACK didn't come in
#define RETRY_LIMIT 5     // Maximum number of times to retry
#define ACK_TIME 10       // Number of milliseconds to wait for an ack

Replace void send_rf_data() in emontx_lib with:

void send_rf_data(){
  
  for (byte i = 0; i <= RETRY_LIMIT; ++i) {  // tx and wait for ack up to RETRY_LIMIT times
    rf12_sleep(-1);              // Wake up RF module
    while (!rf12_canSend())
    rf12_recvDone();
    rf12_sendStart(RF12_HDR_ACK, &emontx, sizeof emontx);
    rf12_sendWait(2);           // Wait for RF to finish sending while in standby mode
    byte acked = waitForAck();  // Wait for ACK
    rf12_sleep(0);              // Put RF module to sleep
    if (acked) { return; }      // Return if ACK received
    Sleepy::loseSomeTime(RETRY_PERIOD * 500);     // If no ack received wait and try again
  }
}

static byte waitForAck() {
MilliTimer ackTimer;
while (!ackTimer.poll(ACK_TIME)) {
   if (rf12_recvDone() && rf12_crc == 0 &&
      rf12_hdr == (RF12_HDR_DST | RF12_HDR_CTL | nodeID))
      return 1;
   }
return 0;
}

.. and it should fly away. Word of warning, tho. You have to have the most recent Martin's  RMF2Pi sketch, the only change that's required is  from ' mySerial.print((int) rf12_hdr); ' to ' mySerial.print((int) rf12_hdr & 0x1F); ' to clear the ACK bit and avoid adding 32 to the node ID for nodes requiring ACK.

There are some (minor) stability issues at the moment with ACKs on the PI, but Martin is working hard to iron the bugs out ;)

https://github.com/mharizanov/RFM2Pi/tree/master/firmware would be your destination of choice..

All the best.

TBP

 

o_cee's picture

Re: Transmission acknowledgement

Thanks, I'll give that a shot!

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.