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
/* 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
/* 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);
}
}