LowPowerLab Forum

Hardware support => Moteino => Topic started by: JimJim on July 23, 2014, 07:16:23 PM

Title: I would like to know how to smooth out ACK_REQUESTED
Post by: JimJim on July 23, 2014, 07:16:23 PM
Hi

I have two Moteino.

One Moteion has A piezo disk, on pin A5 and GND.
There is A resistor on pin A5, as A pull down to GND.
Pin 9,  blinks the led when the piezo is moving.


The other Moteion,  pin 9 allso  shows when the piezo is moving.
Pin 6 there is A buzzer. (+Pin 6 and - to GND).

It all works great.......(piezo disk,Moteino's,and buzzer)

What I need some help with,  is with getting all the ACK working right,
on the (buzzer side of the  (RX). 
I am new at all of this,  but I want to learn some new things.

I will post the Arduino sketches.


piezo disk

#include <RFM69.h>
#include <SPI.h>


#define NODEID      99
#define NETWORKID   100
#define GATEWAYID   1
#define FREQUENCY   RF69_915MHZ //Match this with the version of your Moteino! (others: RF69_433MHZ, RF69_868MHZ)
#define KEY         "thisIsEncryptKey" //has to be same 16 characters/bytes on all nodes, not more not less!
#define SERIAL_BAUD 115200
#define ACK_TIME    30  // # of ms to wait for an ack

int TRANSMITPERIOD = 200; //transmit a packet to gateway so often (in ms)
byte sendSize=0;
boolean requestACK = false;

RFM69 radio;

int counter = 0 ;
int counter1 = 0 ;

// analog pin used to connect the potentiometer
int potpin0 = 0; 
int potpin1 = 0;

const int ledPin =  9;
int inputPin = A5;

int maxnum = 200;
int time = 50;

int sensorValue;
//int counter = 0;

int count = 0;
byte state;
byte realtime;

const int numReadings = 10;
int readings[numReadings];     
int index = 0;                 
int total = 0;                 
int average = 0;       

typedef struct
{
  int Pot_0,Pot_1;    //store this potentiometer 0
}
Payload;
Payload theData;

void setup()
{
  Serial.begin(SERIAL_BAUD);
  radio.initialize(FREQUENCY,NODEID,NETWORKID);
  radio.setHighPower(); //uncomment only for RFM69HW!
  radio.encrypt(KEY);
  char buff[50];
  sprintf(buff, "\nTransmitting at %d Mhz...", FREQUENCY==RF69_433MHZ ? 433 : FREQUENCY==RF69_868MHZ ? 868 : 915);
  Serial.println(buff);

  for (int thisReading = 0; thisReading < numReadings; thisReading++)
    readings[thisReading] = 0;     

  pinMode(ledPin, OUTPUT);
}

long lastPeriod = -1;

void loop()
{

  //process any serial input
  if (Serial.available() > 0)
  {
    char input = Serial.read();
    if (input >= 48 && input <= 57) //[0,9]
    {
      TRANSMITPERIOD = 100 * (input-48);
      if (TRANSMITPERIOD == 0) TRANSMITPERIOD = 1000;
      Serial.print("\nChanging delay to ");
      Serial.print(TRANSMITPERIOD);
      Serial.println("ms\n");
    }

  }

  //check for any received packets
  if (radio.receiveDone())
{
   Serial.print('['); Serial.print(radio.SENDERID, DEC); Serial.print("] ");
    for (byte i = 0; i < radio.DATALEN; i++)
    Serial.print((char)radio.DATA[i]);
   Serial.print("   [RX_RSSI:");Serial.print(radio.readRSSI());Serial.print("]");

    if (radio.ACK_REQUESTED)
   {
     radio.sendACK();
     Serial.print(" - ACK sent");
     delay(10);
   }

    //  Serial.println();
}

  int currPeriod = millis()/TRANSMITPERIOD;
  if (currPeriod != lastPeriod)
  {
    //fill in the struct with new values
    theData.Pot_0 = realtime;
    theData.Pot_1 = state;



   Serial.print("Sending struct (");
   Serial.print(sizeof(theData));
   Serial.print(" bytes) ... ");
    if (radio.sendWithRetry(GATEWAYID, (const void*)(&theData), sizeof(theData)))
     Serial.print(" ok!");
   else Serial.print(" nothing...");
   Serial.println();

    lastPeriod=currPeriod;


    //Serial.print("Input ON Pin 5:  ");
    // Serial.println(sensorValue);

    //Serial.print("Led State:  ");
    Serial.print(" Piezo Sensor ");
    Serial.println(realtime);

    Serial.print(" Beeps ");
    Serial.println(state);

    //Serial.print("Counter:  ");
    //Serial.println(counter);

    // Serial.print("Led State:  ");
    // Serial.println(realtime);

    total= total - readings[index];       

    readings[index] = analogRead(inputPin);

    total= total + readings[index];     
    index = index + 1; 

    if (index >= numReadings)             

      index = 0;                         
    average = total / numReadings;   

    // Serial.println(average); 
    // delay(1);       

    sensorValue = average;

    if (state == 0)
    {
      counter++;
    }

    if (sensorValue > 0) {   
      // turn LED on: 

      digitalWrite(ledPin, HIGH);
      realtime = 1;
      counter = 0;
    }
    else {
      // turn LED off:

      digitalWrite(ledPin, LOW);
      realtime = 0;
      delay(1);
    } 

    if  (counter > maxnum)
    {
      if (count < time) {
        // trun LED on
        state = !state;
        delay(10); 
        count++;
      }
    }
    else {
      // turn LED off:
      state = 0;
      delay(1);
    } 
  }
}
 




buzzer

#include <RFM69.h>
#include <SPI.h>



#define NODEID      1
#define NETWORKID   100
#define FREQUENCY   RF69_915MHZ //Match this with the version of your Moteino! (others: RF69_433MHZ, RF69_868MHZ)
#define KEY         "thisIsEncryptKey" //has to be same 16 characters/bytes on all nodes, not more not less!
#define SERIAL_BAUD 115200
#define ACK_TIME    30  // # of ms to wait for an ack

RFM69 radio;

const int realtime =  9;
const int ledPin =  6;



bool promiscuousMode = false; //set to 'true' to sniff all packets on the same network

//  Setup Servo Objects
//Servo Servo1;

// variable to read the value from the potentiometer analog pin
int val0 = 0;   
int val1 = 0;


typedef struct
{
  int Pot_0,Pot_1;                 //recall this potentiometer 0 value
}
Payload;
Payload theData;

void setup()
{

  // Attach Servo Objects to respective PWM pins
  // Servo1.attach(5);                         

  Serial.begin(SERIAL_BAUD);
  delay(10);
  radio.initialize(FREQUENCY,NODEID,NETWORKID);
  radio.setHighPower(); //uncomment only for RFM69HW!
  radio.encrypt(KEY);
  radio.promiscuous(promiscuousMode);
  char buff[50];
  sprintf(buff, "\nListening at %d Mhz...", FREQUENCY==RF69_433MHZ ? 433 : FREQUENCY==RF69_868MHZ ? 868 : 915);
  Serial.println(buff);



  pinMode (realtime, OUTPUT);
  pinMode (ledPin, OUTPUT);


}

byte ackCount=0;

void loop() {

  //process any serial input
  if (Serial.available() > 0) {
    char input = Serial.read();
  }

  if (radio.receiveDone())
  {

    Serial.print('[');
    Serial.print(radio.SENDERID, DEC);
    Serial.print("] ");
    Serial.print(" [RX_RSSI:");
    Serial.print(radio.readRSSI());
    Serial.println("]");
    if (promiscuousMode)
    {
      Serial.print("to [");
      Serial.print(radio.TARGETID, DEC);
      Serial.print("] ");
    }

    if (radio.DATALEN != sizeof(Payload))
      Serial.print("Invalid payload received, not matching Payload struct!");
    else
    {
      theData = *(Payload*)radio.DATA; //assume radio.DATA actually contains our struct and not something else

   

  if (radio.ACK_REQUESTED) {

    byte theNodeID = radio.SENDERID;
    radio.sendACK();
    Serial.println(" - ACK sent.");

    // When a node requests an ACK, respond to the ACK
    // and also send a packet requesting an ACK (every 3rd one only)
    // This way both TX/RX NODE functions are tested on 1 end at the GATEWAY
    if (ackCount++%1==0)

      //  Output to Serial Monitor       
      Serial.println();
    Serial.print(" Pinging node ");
    Serial.print(theNodeID);
    Serial.print(" - ACK...");
    delay(3); //need this when sending right after reception .. ?
    if (radio.sendWithRetry(theNodeID, "ACK TEST", 8, 0))  // 0 = only 1 attempt, no retries
      Serial.println("ok!");
    else Serial.print("nothing");
  }
}



  // Adjust RF data for Servo Output
      val0 = theData.Pot_0;       // Translate RF into Servo Degrees


      val1 = theData.Pot_1;       // Translate RF into Servo Degrees




      Serial.print(" Piezo Sensor ");
      Serial.println(val0);


      Serial.print(" Beeps ");
      Serial.println(val1);

      if (theData.Pot_0 == HIGH) {     
        // turn LED on:   
        digitalWrite(realtime, HIGH); 

      }
      else {
        // turn LED off:
        digitalWrite(realtime, LOW);

      }

      if (theData.Pot_1 == HIGH) {     
        //turn LED on:   
        digitalWrite(ledPin, HIGH); 

      }
      else {
        // turn LED off:
        digitalWrite(ledPin, LOW);
        // delay(1);
      }
    }
}
Title: Re: I would like to know how to smooth out ACK_REQUESTED
Post by: Felix on July 24, 2014, 08:01:39 AM
JimJim,
Without really digging into the code, you might want to increase the ACK time to around 30-40ms when you send longer packets.
Also a very common pitfall is not calling radio.receiveDone() often enough. Some people go do other things for a few hundred ms and then when they finally check the radio again it's too late, and  (even if a packet is still in the buffer) a remote node is done waiting for the ACK it requested.
Hope this helps.