How to use ACKReceived?

Started by evh, April 23, 2015, 02:48:59 AM

evh

In the code posted below,  if the node received an ACK, it is supposed to call do_flicker() to give an indication on the LED.  If no ACK, it runs do_bigflash(), to give a different indication.

But it is not working, and I am not sure if I am using ACKReceived() correctly.  Can someone give me a clue?

Thanks!

// Sample RFM69 sender/node sketch, with ACK and optional encryption
// Sends periodic messages of increasing length to gateway (id=1)
// It also looks for an onboard FLASH chip, if present
// Library and code by Felix Rusu - [email protected]
// Get the RFM69 and SPIFlash library at: https://github.com/LowPowerLab/

#include <RFM69.h>    //get it here: https://www.github.com/lowpowerlab/rfm69
#include <SPI.h>
#include <SPIFlash.h> //get it here: https://www.github.com/lowpowerlab/spiflash
#include <Wire.h>


#include <LowPower.h>
#include <avr/io.h>
#include <avr/wdt.h>

#define NODEID        68    //unique for each node on same network
#define NETWORKID     100  //the same on all nodes that talk to each other
#define GATEWAYID     1
//Match frequency to the hardware version of the radio on your Moteino (uncomment one):
//#define FREQUENCY   RF69_433MHZ
//#define FREQUENCY   RF69_868MHZ
#define FREQUENCY     RF69_915MHZ
#define ENCRYPTKEY    "sampleEncryptKey" //exactly the same 16 characters/bytes on all nodes!
#define IS_RFM69HW    //uncomment only for RFM69HW! Leave out if you have RFM69W!
#ifdef __AVR_ATmega1284P__
  #define LED           15 // Moteino MEGAs have LEDs on D15
  #define FLASH_SS      23 // and FLASH SS on D23
#else
  #define LED           9 // Moteinos have LEDs on D9
  #define FLASH_SS      8 // and FLASH SS on D8
#endif

#define SERIAL_BAUD   1200

     char inbuffer[50];
     int loopcounter=0;



char highbyte, lowbyte;

int temp_address = 72;

  char out_temp[40];
int TRANSMITPERIOD = 1500; //transmit a packet to gateway so often (in ms)
char payload[] = "123 ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char buff[20];
byte sendSize=0;
boolean requestACK = false;
SPIFlash flash(FLASH_SS, 0xEF30); //EF30 for 4mbit  Windbond chip (W25X40CL)
RFM69 radio;



int get_275_text(char *inbuffer )
{
 
word t;
int my_temp;
char tempHighByte;
char tempLowByte;
float temperature1;
float temperature2; 
Wire.beginTransmission(0x48);
  Wire.write(1);
  Wire.write(B11100001);
  Wire.endTransmission();
  Wire.beginTransmission(0x48);
  Wire.write(0);
  Wire.endTransmission();
  Wire.requestFrom(0x48,2);
  delay(250);
  tempHighByte = Wire.read();
  tempLowByte  = Wire.read();
  t = word(tempHighByte,tempLowByte)/16;
  temperature1=t/16.0;
  //Serial.println(temperature1,4);
  my_temp = temperature1*100;
  
  sprintf(inbuffer,"{%x}*%x*",tempHighByte,(tempLowByte & 0xf0)>>4   );
  //sprintf(outtemp,"{%d}",my_temp);
  return my_temp;

 
}






void do_bigflash()
{
  
   
  int j;
  
  for(j=1;j<10;j++)
  {
    
     pinMode(9, OUTPUT);
  digitalWrite(9,HIGH);
  delay(1000);
   digitalWrite(9,LOW);
  delay(250);
    
  }
  
  
}








void do_flicker()
{
  
   
  int j;
  
  for(j=1;j<10;j++)
  {
    
     pinMode(9, OUTPUT);
  digitalWrite(9,HIGH);
  delay(1);
   digitalWrite(9,LOW);
  delay(50);
    
  }
  
  
}



void setup() {
  
 
     
  
  
  
  //Create a Wire Object
  Wire.begin();

  radio.initialize(FREQUENCY,NODEID,NETWORKID);
#ifdef IS_RFM69HW
  radio.setHighPower(); //uncomment only for RFM69HW!
#endif
  radio.encrypt(ENCRYPTKEY);
  //radio.setFrequency(919000000); //set frequency to some custom frequency
  char buff[50];
  //sprintf(buff, "\nTransmitting at %d Mhz...", FREQUENCY==RF69_433MHZ ? 433 : FREQUENCY==RF69_868MHZ ? 868 : 915);
  //Serial.println(buff);
  
   flash.initialize();
   
    
    //sprintf(out_temp,"{LFP AAAD %d}",get_275());
    get_275_text(inbuffer);
    inbuffer[17]=0;
    sprintf(out_temp,"nodeW%s@",inbuffer);

    out_temp[17]=0;
     
    radio.sendWithRetry(GATEWAYID, out_temp, 14,5,2000 );
    if( radio.ACKReceived(NODEID) )
    {
      
      do_flicker();
      
    }
    
    else  do_bigflash();
    
    
    
      
    radio.sleep();
    flash.sleep();
   
   
    LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
     LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
      LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
       LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
        LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
                    
    //LowPower.idle(SLEEP_1S, ADC_OFF, TIMER2_OFF, TIMER1_OFF, TIMER0_OFF, 
    //            SPI_OFF, USART0_OFF, TWI_OFF);    
    Serial.println("loop");    
  
    asm volatile ("  jmp 0");    
   
   
   
}

void loop() {
 
 //no code
}







TomWS

You will probably NEVER receive an Ack from NODEID (since its YOUR ID).  However, assuming the sendWithRetry didn't fail (which you can determine by checking its return code) you would have received an Ack from GATEWAYID.

Also, I have no idea what you are trying to accomplish with:
    asm volatile ("  jmp 0");   


Tom

evh


The jmp 0 is intended to reset the Moteino ... there is some problem with crashing after a day or so of successful running ....  I am trying to use a debugger to figure it out ....

I will try a different ID ...

Thanks!

DonpK

I am working with the Gateway.ino and Node.ino and am also trying to understand better the ACKReceived.

Here is a fragment from Gateway.ino:

if (radio.ACKRequested())
    {
      byte theNodeID = radio.SENDERID;
      radio.sendACK();
      Serial.print(" - ACK sent.");
    }


And here is a fragment from the Node.ino:

      if (radio.sendWithRetry(GATEWAYID, payload, sendSize))
      {
       Serial.println(" ok!");
       
         if (radio.ACKReceived(GATEWAYID))
              Serial.println ("ACK Received");
         else Serial.println ("ACK Not Received"); 
         
       }       
      else Serial.println(" nothing...");


I added the radio.ACKReceived section. The Gateway sketch prints " - ACK sent.", however at the Node end "(radio.ACKReceived(GATEWAYID)) apparently returns false and prints "ACK Not Received". When the Node runs (radio.sendWithRetry(GATEWAYID, payload, sendSize)) doesn't this send the payload including an ACK request? When the Gateway receives the Node's payload, it appears to send an ACK. Why doesn't the ACKReceived return true?

What am I missing?

Felix

Quote from: DonpK on December 21, 2017, 09:16:23 PM
What am I missing?
Doesn't sendWithRetry()=true automatically imply you got your wanted ACK?

DonpK

When the Node successfully does a (radio.sendWithRetry(GATEWAYID, payload, sendSize)), it returns a True resulting in Serial.println(" ok!");. Does this true also indicate that Gateway has not only received the payload, but has also returned and ACK to the node?

I guess that's what you're saying, so there's no need to use (radio.ACKReceived(GATEWAYID)). It's redundant.  Still why does my (radio.ACKReceived(GATEWAYID)) return false after an ACK was just received by the Node?

Felix

Yes, redundant, because the return package would have the ACK bit=1, which means you just got your ACK.
That's the whole purpose of using sendWithRetry. It repeats sending the package until it gets an ACK.

DonpK

Thanks for the answer.

And thanks for a great product!  As a newbie, the fact that I've been able to get several Moteinos/MoteinoMEGAs to successfully communicate with each other sending sensor data is a tribute to the product's solid hardware and code. Still, I realize I've got to learn more about "what's under the hood", thus my questions.


Felix

Quote from: DonpK on December 22, 2017, 02:44:52 PM
And thanks for a great product!  As a newbie, the fact that I've been able to get several Moteinos/MoteinoMEGAs to successfully communicate with each other sending sensor data is a tribute to the product's solid hardware and code. Still, I realize I've got to learn more about "what's under the hood", thus my questions.
Thanks for the feedback, glad you've found it easy to work with my products :)
The forum is here for such questions, and hopefully I and others can answer and help.

kni

Quote from: evh on April 23, 2015, 01:36:25 PM
The jmp 0 is intended to reset the Moteino ... there is some problem with crashing after a day or so of successful running ....  I am trying to use a debugger to figure it out ....

I will try a different ID ...

Thanks!

I had the same symptoms on a moteino w/ the flash chip installed.

See here::
https://lowpowerlab.com/forum/moteino/one-solution-to-moteino-failure-to-return-from-sleep/msg21274/#msg21274

TL;DR - (inadvertently) calling flash.sleep when the flash chip was already asleep caused my moteino to go silent. I changed the code to not do that and have not a single lockup since.