Author Topic: Node payload clash  (Read 1112 times)

jsalloneword

  • NewMember
  • *
  • Posts: 2
  • Country: gb
Node payload clash
« on: November 06, 2016, 02:30:36 PM »
Hello,
I'm using the RFM69 library to create a communication tree. I have 4 nodes transmitting data back to the receiver/gateway node. Each node (except the gateway) has an accelerometer attached to them. The aim is to transmit a constant stream of accelerometer data from each node back to the gateway node. However, currently I get 3 transmitting at the beginnning this then shortly goes down to 2 transmitting as one powers off then finally only 1 is transmitting.

I think this is to do with my data packets clashing when received  by the gateway node but I'm unsure of the bets way to resolve it. i have increased the ACK time but it does not improve things.

Thanks for your time.
below is my code.

Transmit code
Code: [Select]
/* RFM69 library and code by Felix Rusu - felix@lowpowerlab.com
  // Get libraries at: https://github.com/LowPowerLab/
  // Make sure you adjust the settings in the configuration section below !!!
  // **********************************************************************************
  // Copyright Felix Rusu, LowPowerLab.com
  // Library and code by Felix Rusu - felix@lowpowerlab.com
  // **********************************************************************************
  // License
  // **********************************************************************************
  // This program is free software; you can redistribute it
  // and/or modify it under the terms of the GNU General
  // Public License as published by the Free Software
  // Foundation; either version 3 of the License, or
  // (at your option) any later version.
  //
  // This program is distributed in the hope that it will
  // be useful, but WITHOUT ANY WARRANTY; without even the
  // implied warranty of MERCHANTABILITY or FITNESS FOR A
  // PARTICULAR PURPOSE. See the GNU General Public
  // License for more details.
  //
  // You should have received a copy of the GNU General
  // Public License along with this program.
  // If not, see <http://www.gnu.org/licenses></http:>.
  //
  // Licence can be viewed at
  // http://www.gnu.org/licenses/gpl-3.0.txt
  //
  // Please maintain this license information along with authorship
  // and copyright notices in any redistribution of this code
  // **********************************************************************************/

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

//*********************************************************************************************
// *********** IMPORTANT SETTINGS - YOU MUST CHANGE/ONFIGURE TO FIT YOUR HARDWARE *************
//*********************************************************************************************
#define NETWORKID     100  // The same on all nodes that talk to each other
#define NODEID        2    // The unique identifier of this node
#define RECEIVER      1    // The recipient of packets

//Match frequency to the hardware version of the radio on your Feather
#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_RFM69HCW   true // set to 'true' if you are using an RFM69HCW module
#define ACK_TIME    60  // # of ms to wait for an ack
//*********************************************************************************************
#define SERIAL_BAUD   115200

/* for Feather 32u4 Radio
  #define RFM69_CS      8
  #define RFM69_IRQ     7
  #define RFM69_IRQN    4  // Pin 7 is IRQ 4!
  #define RFM69_RST     4
*/

//for Feather M0 Radio
#define RFM69_CS      8
#define RFM69_IRQ     3
#define RFM69_IRQN    3  // Pin 3 is IRQ 3!
#define RFM69_RST     4


/* ESP8266 feather w/wing
  #define RFM69_CS      2
  #define RFM69_IRQ     15
  #define RFM69_IRQN    digitalPinToInterrupt(RFM69_IRQ )
  #define RFM69_RST     16
*/

/* Feather 32u4 w/wing
  #define RFM69_RST     11   // "A"
  #define RFM69_CS      10   // "B"
  #define RFM69_IRQ     2    // "SDA" (only SDA/SCL/RX/TX have IRQ!)
  #define RFM69_IRQN    digitalPinToInterrupt(RFM69_IRQ )
*/

/* Feather m0 w/wing
  #define RFM69_RST     11   // "A"
  #define RFM69_CS      10   // "B"
  #define RFM69_IRQ     6    // "D"
  #define RFM69_IRQN    digitalPinToInterrupt(RFM69_IRQ )
*/

/* Teensy 3.x w/wing
  #define RFM69_RST     9   // "A"
  #define RFM69_CS      10   // "B"
  #define RFM69_IRQ     4    // "C"
  #define RFM69_IRQN    digitalPinToInterrupt(RFM69_IRQ )
*/

/* WICED Feather w/wing
  #define RFM69_RST     PA4     // "A"
  #define RFM69_CS      PB4     // "B"
  #define RFM69_IRQ     PA15    // "C"
  #define RFM69_IRQN    RFM69_IRQ
*/
int potpin0 = A1;                                    // analog pin used to connect the potentiometer
int val0 = 0;                                       // variable initialized for storing potpin0 value

typedef struct
{
  int           Pot_0;                              //create transmit variable & store data potentiometer 0 data
} Payload;
Payload theData;                                    // create transmission package 'theData'.

#define LED           13  // onboard blinky
//#define LED           0 //use 0 on ESP8266

int16_t packetnum = 0;  // packet counter, we increment per xmission

RFM69 radio = RFM69(RFM69_CS, RFM69_IRQ, IS_RFM69HCW, RFM69_IRQN);

void setup() {
  //while (!Serial); // wait until serial console is open, remove if not tethered to computer. Delete this line on ESP8266
  Serial.begin(SERIAL_BAUD);

  Serial.println("Feather RFM69HCW Transmitter");

  // Hard Reset the RFM module
  pinMode(RFM69_RST, OUTPUT);
  digitalWrite(RFM69_RST, HIGH);
  delay(75);
  digitalWrite(RFM69_RST, LOW);
  delay(75);

  // Initialize radio
  radio.initialize(FREQUENCY, NODEID, NETWORKID);
  if (IS_RFM69HCW) {
    radio.setHighPower();    // Only for RFM69HCW & HW!
  }
  radio.setPowerLevel(31); // power output ranges from 0 (5dBm) to 31 (20dBm)

  radio.encrypt(ENCRYPTKEY);

  pinMode(LED, OUTPUT);
  Serial.print("\nTransmitting at ");
  Serial.print(FREQUENCY == RF69_433MHZ ? 433 : FREQUENCY == RF69_868MHZ ? 868 : 915);
  Serial.println(" MHz");
}


void loop() {
  delay(1000);  // Wait 1 second between transmits, could also 'sleep' here!

  // Output to serial some communications information - Data length, RSSI
  for (byte i = 0; i < radio.DATALEN; i++)
    Serial.print((char)radio.DATA[i]);
  Serial.print("   [RX_RSSI:"); Serial.print(radio.readRSSI()); Serial.print("]");
  Serial.println();


  // initialise pot pin
  theData.Pot_0 = analogRead(potpin0);



  if (radio.sendWithRetry(RECEIVER, (const void*)(&theData), sizeof(theData))) { //target node Id, message as string or byte array, message length
    Serial.println("OK");
    Blink(LED, 50, 3); //blink LED 3 times, 50ms between blinks
  }
  // Output to serial information of # bytes sent.
  Serial.print("Sending struct (");
  Serial.print(sizeof(theData));
  Serial.println(" bytes) ");
  Serial.println();
//  radio.receiveDone(); //put radio in RX mode
 // Serial.flush(); //make sure all serial data is clocked out before sleeping the MCU
}

void Blink(byte PIN, byte DELAY_MS, byte loops)
{
  for (byte i = 0; i < loops; i++)
  {
    digitalWrite(PIN, HIGH);
    delay(DELAY_MS);
    digitalWrite(PIN, LOW);
    delay(DELAY_MS);
  }
}


Receive code
Code: [Select]
/* RFM69 library and code by Felix Rusu - felix@lowpowerlab.com
  // Get libraries at: https://github.com/LowPowerLab/
  // Make sure you adjust the settings in the configuration section below !!!
  // **********************************************************************************
  // Copyright Felix Rusu, LowPowerLab.com
  // Library and code by Felix Rusu - felix@lowpowerlab.com
  // **********************************************************************************
  // License
  // **********************************************************************************
  // This program is free software; you can redistribute it
  // and/or modify it under the terms of the GNU General
  // Public License as published by the Free Software
  // Foundation; either version 3 of the License, or
  // (at your option) any later version.
  //
  // This program is distributed in the hope that it will
  // be useful, but WITHOUT ANY WARRANTY; without even the
  // implied warranty of MERCHANTABILITY or FITNESS FOR A
  // PARTICULAR PURPOSE. See the GNU General Public
  // License for more details.
  //
  // You should have received a copy of the GNU General
  // Public License along with this program.
  // If not, see <http://www.gnu.org/licenses></http:>.
  //
  // Licence can be viewed at
  // http://www.gnu.org/licenses/gpl-3.0.txt
  //
  // Please maintain this license information along with authorship
  // and copyright notices in any redistribution of this code
  // **********************************************************************************/

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

//*********************************************************************************************
// *********** IMPORTANT SETTINGS - YOU MUST CHANGE/ONFIGURE TO FIT YOUR HARDWARE *************
//*********************************************************************************************
#define NETWORKID     100  //the same on all nodes that talk to each other
#define NODEID        1

//Match frequency to the hardware version of the radio on your Feather
#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_RFM69HCW    true // set to 'true' if you are using an RFM69HCW module

//*********************************************************************************************
#define SERIAL_BAUD   115200

/* for Feather 32u4
  #define RFM69_CS      8
  #define RFM69_IRQ     7
  #define RFM69_IRQN    4  // Pin 7 is IRQ 4!
  #define RFM69_RST     4
*/
/* for Feather M0 */
#define RFM69_CS      8
#define RFM69_IRQ     3
#define RFM69_IRQN    3  // Pin 3 is IRQ 3!
#define RFM69_RST     4


/* ESP8266 feather w/wing
  #define RFM69_CS      2
  #define RFM69_IRQ     15
  #define RFM69_IRQN    digitalPinToInterrupt(RFM69_IRQ )
  #define RFM69_RST     16
*/

/* Feather 32u4 w/wing
  #define RFM69_CS      10   // "B"
  #define RFM69_RST     11   // "A"
  #define RFM69_IRQ     2    // "SDA" (only SDA/SCL/RX/TX have IRQ!)
  #define RFM69_IRQN    digitalPinToInterrupt(RFM69_IRQ )
*/

/* Feather m0 w/wing
  #define RFM69_CS      10   // "B"
  #define RFM69_RST     11   // "A"
  #define RFM69_IRQ     6    // "D"
  #define RFM69_IRQN    digitalPinToInterrupt(RFM69_IRQ )
*/

/* Teensy 3.x w/wing
  #define RFM69_RST     9   // "A"
  #define RFM69_CS      10   // "B"
  #define RFM69_IRQ     4    // "C"
  #define RFM69_IRQN    digitalPinToInterrupt(RFM69_IRQ )
*/

/* WICED Feather w/wing
  #define RFM69_RST     PA4     // "A"
  #define RFM69_CS      PB4     // "B"
  #define RFM69_IRQ     PA15    // "C"
  #define RFM69_IRQN    RFM69_IRQ
*/
#define ACK_TIME    60  // # of ms to wait for an ack
#define LED           13  // onboard blinky
//#define LED           0 //use 0 on ESP8266

int16_t packetnum = 0;  // packet counter, we increment per xmission

RFM69 radio = RFM69(RFM69_CS, RFM69_IRQ, IS_RFM69HCW, RFM69_IRQN);

typedef struct
{
  int           Pot_0;                                 //designate transmitted data for this potentiometer 0 value
} Payload;
Payload theData;

void setup() {
  //while (!Serial); // wait until serial console is open, remove if not tethered to computer. Delete this line on ESP8266
  Serial.begin(SERIAL_BAUD);

  Serial.println("Feather RFM69HCW Receiver");

  // Hard Reset the RFM module
  pinMode(RFM69_RST, OUTPUT);
  digitalWrite(RFM69_RST, HIGH);
  delay(100);
  digitalWrite(RFM69_RST, LOW);
  delay(100);

  // Initialize radio
  radio.initialize(FREQUENCY, NODEID, NETWORKID);
  if (IS_RFM69HCW) {
    radio.setHighPower();    // Only for RFM69HCW & HW!
  }
  radio.setPowerLevel(31); // power output ranges from 0 (5dBm) to 31 (20dBm)

  radio.encrypt(ENCRYPTKEY);

  pinMode(LED, OUTPUT);

  Serial.print("\nListening at ");
  Serial.print(FREQUENCY == RF69_433MHZ ? 433 : FREQUENCY == RF69_868MHZ ? 868 : 915);
  Serial.println(" MHz");
}

void loop() {

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


  //check if something was received (could be an interrupt from the radio)
  if (radio.receiveDone())
  {
    //print message received to serial
    Serial.print('['); Serial.print(radio.SENDERID,DEC); Serial.print("] ");
    Serial.print((char*)radio.DATA);
    Serial.print("   [RX_RSSI:"); Serial.print(radio.readRSSI()); Serial.print("]");

    //check if received message
    if (radio.DATALEN != sizeof(Payload))
      Serial.print("Invalid payload received, not matching Payload struct!");
    else
    {
      //check if sender wanted an ACK
      if (radio.ACKRequested())
      {
        radio.sendACK();
        Serial.println(" - ACK sent");
        theData = *(Payload*)radio.DATA;                       //assume radio.DATA actually contains our struct and not something else

   

      // Print to Serial Terminal to verify RF data
      Serial.print(" Data_Pot ");
      Serial.println(theData.Pot_0);
      Serial.println();

      }
      Blink(LED, 40, 3); //blink LED 3 times, 40ms between blinks
    }
  }

  radio.receiveDone(); //put radio in RX mode
  Serial.flush(); //make sure all serial data is clocked out before sleeping the MCU
}

void Blink(byte PIN, byte DELAY_MS, byte loops)
{
  for (byte i = 0; i < loops; i++)
  {
    digitalWrite(PIN, HIGH);
    delay(DELAY_MS);
    digitalWrite(PIN, LOW);
    delay(DELAY_MS);
  }
}

jsalloneword

  • NewMember
  • *
  • Posts: 2
  • Country: gb
Re: Node payload clash
« Reply #1 on: November 06, 2016, 02:46:46 PM »

I'm now using the struct_send and receive examples rather than Adafruits' example. This has improved the issue but one send node still freezes or stops sending after 10 minutes.

Also Additional question:
Is there a way to call the same data payload but on a specific node. For example if I wanted to set the pwm value to digital pin 9 but only the data payload coming from node 2. Then node 3's data payload to digital pin 10.

I'm not too sure of the argument structure for this.

Thanks
« Last Edit: November 06, 2016, 02:56:05 PM by jsalloneword »