Please help with promini/rfm69/photon gateway

I am new to this forum.
I am new to the rfm69 chips. I would greatly appreciate any help.
I have followed the example codes and have been able to
send data struct successfully between two pro min 3.3v 8mhz boards and two rfm69 915 mhz boards.
Now I am trying to send data from one of these (pro mini) nodes to a particle photon to use it like a gateway to mqtt.
COULD ANYONE PLEASE HELP ME WITH GETTING THE DATA TO SEND PROPERLY.
From searches on the net I did find one post but no examples on changing the ? bit structure to get the payload to match so the photon can receive the data.

I am getting this message. “Invalid payload received, not matching Payload struct!”.

I found this reply in a particle forum
"I had a similar issue. It is caused by differences in data type lengths between the arduino and photon e.g. INT is 2 bytes on the arduino and 4 on the Photon. There also appear to be issues with data types. I eventually did the following:

  1. Changed to uint8_t amd int16_t on both Arduino and Photon
  2. kept number of bytes to <= 12
  3. Avoided floats etc
  4. Added code to debug number of bytes sent and received e.
    ------------------------>

I am not sure how to do this.
Could anyone help me with a example struct on either side, pro mini side (sender of data from dht11 sensor ) to photon (receiver of the data).

I can get it to work between two pro mini, as stated above.
when I try from a pro mini to to a photon I just gets 00 where the data should be?

My sender struct looks like this.

// CREATE STRUCT FOR WIRELESS TRANSMISSION ON RFM69.
///////////////////////////////////////////////////////////////////////////////////////////////////////////THIS IS THE STRUCT TO SEND/////////////////////
  
  
  

typedef struct {      

  int nodeID;  // NODE ID THIS NODE
  int deviceID;  // sensor ID 
  float var2_float;  // sensor data
  float var3_float; //  other sensor data 
  
} Payload;
Payload theData;

//------------------------------------------->>>>>>>
//sending

theData.nodeID = 1;
 theData.deviceID = NODEID;
 theData.var2_float = f;
 theData.var3_float = h; 
 radio.sendWithRetry(TONODEID,(const void*)(&theData), sizeof(theData));

THANKS SO MUCH FOR YOUR HELP.

Try as outlined in the other post

typedef struct {      
  // int is 16bit on Arduino and 32bit on Particle, so use explicit int16_t (16bit on both)
  int16_t nodeID;  // NODE ID THIS NODE (if you only need 0~255 go for uint8_t to save space) 
  int16_t deviceID;  // sensor ID   (if you only need 0~255 go for uint8_t to save space)
  // avoid floats, by converting to int16 and multiply by powers of 10
  int16_t var2_float;  // sensor data
  int16_t var3_float; //  other sensor data 
} Payload;

You could also try int32_t to allow for bigger float values (e.g. int32Var = floatVar * 1000 allows for 3 decimal places)

Thanks so much for taking the time to help me.
I tried this. still getting 0,0,0,0 RSSI = 0
Works with the pro mini together. but pro min to the phton this is what I am getting . SO CLOSE.
This is my code. I know it is a chop job but it is working, just the start.

sensor side/ pro min.

// Example testing sketch for various DHT humidity/temperature sensors
// Written by ladyada, public domain
// TESTED WITH PRO MIN CLONE RED 3.3V 8MHZ
// Uncomment whatever type you're using!
#define DHTTYPE DHT11   // DHT 11
//define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321
//#define DHTTYPE DHT21   // DHT 21 (AM2301)

// Connect pin 1 (on the left) of the sensor to +5V
// NOTE: If using a board with 3.3V logic like an Arduino Due connect pin 1
// to 3.3V instead of 5V!
// Connect pin 2 of the sensor to whatever your DHTPIN is
// Connect pin 4 (on the right) of the sensor to GROUND
// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor

// Initialize DHT sensor.
// Note that older versions of this library took an optional third parameter to
// tweak the timings for faster processors.  This parameter is no longer needed
// as the current DHT reading algorithm adjusts itself to work on faster procs.

// TEMPERATURE/ HUMIDITY INFO------------------------>>>>>
// INCLUDE DHT11 LIBRARIES
#include "DHT.h"
#define DHTPIN 4    // what digital pin we're connected to
DHT dht(DHTPIN, DHTTYPE);

//_____________________________________________________________________
// RFM69 SET UP
// Include the RFM69 and SPI libraries:
#include <RFM69.h>
#include <RFM69registers.h>
#include <RFM69_ATC.h>
#include <SPI.h>

// Addresses for this node. CHANGE THESE FOR EACH NODE!

#define NETWORKID     100   // Must be the same for all nodes
#define NODEID      1   // My node ID
#define TONODEID      2   // Destination node ID

// RFM69 frequency, uncomment the frequency of your module:

//#define FREQUENCY   RF69_433MHZ
#define FREQUENCY     RF69_915MHZ

// AES encryption (or not):

#define ENCRYPT       false // Set to "true" to use encryption
#define ENCRYPTKEY    "TOPSECRETPASSWRD" // Use the same 16-byte key on all nodes

// Use ACKnowledge when sending messages (or not):

#define USEACK        false // Request ACKs or not

// Packet sent/received indicator LED (optional):

#define LED           13 // LED positive pin
//#define GND           8 // LED ground pin

// CREATE STRUCT FOR WIRELESS TRANSMISSION ON RFM69.
///////////////////////////////////////////////////////////////////////////////////////////////////////////THIS IS THE STRUCT TO SEND/////////////////////
  
  
  
  // swithed it to uint8-t to talk to photon// we will see ???
typedef struct {		
  uint16_t nodeID; // changed from int
  uint16_t sensorID;// changed from int
  //unsigned long          var1_usl; 
  uint16_t var2_float; //changed from float  var2_float
  uint16_t var3_float;	//hanged from float  var3_float
} Payload;
Payload theData;


  //int nodeID;  // NODE ID THIS NODE
  //int deviceID;  // sensor ID ex. temp is sensory 1 on this NODE.(NODE IS THE SENSOR POND LIKE 12 CAN BE THE NODE FOR GREEN HOUSE)
  //float var2_float;  // sensor data
  //float var3_float; //  other sensor data 
  
//} Payload;
//Payload theData;

char buff[20];  // I THINK THIS CREATES BUFF FOR DATA
byte send=0;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Create a library object for our RFM69HCW module:

RFM69 radio;



void setup() {
  
  
pinMode(13, OUTPUT);// blink led 

// START SERIAL --------------------------------------------------
  Serial.begin(9600);
  Serial.println("DHTxx test!");
  
//-------------------------------------------------------------
// START dht SENSORE

  dht.begin();


 //RFM69 initialize-------------------------------------------
 
  radio.initialize(FREQUENCY,NODEID,NETWORKID);
  //#ifdef IS_RFM69HW
    radio.setHighPower(); //uncomment only for RFM69HW!
  //#endif
  //radio.encrypt(ENCRYPTKEY);
  char buff[50];
  sprintf(buff, "\nTransmitting at %d Mhz...", FREQUENCY==RF69_433MHZ ? 433 : FREQUENCY==RF69_868MHZ ? 868 : 915);
  Serial.println(buff);
  //theData.nodeID = NODEID;  //this node id should be the same for all devices in this node
  //end RFM--------------------------------------------

}

void loop() {
  
  
  
  // DEVICE # TEMP/HUMIDITY // SENSOR #1 
  
  // Wait a few seconds between measurements.
  //delay(2000);

  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht.readHumidity();
  // Read temperature as Celsius (the default)
  float t = dht.readTemperature();
  // Read temperature as Fahrenheit (isFahrenheit = true)
  float f = dht.readTemperature(true);

  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t) || isnan(f)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }

  // Compute heat index in Fahrenheit (the default)
  float hif = dht.computeHeatIndex(f, h);
  // Compute heat index in Celsius (isFahreheit = false)
  float hic = dht.computeHeatIndex(t, h, false);

  Serial.print("Humidity: ");
  Serial.print(h);
  Serial.print(" %\t");
  Serial.print("Temperature: ");
  Serial.print(t);
  Serial.print(" *C ");
  Serial.print(f);
  Serial.print(" *F\t");
  Serial.print("Heat index: ");
  Serial.print(hic);
  Serial.print(" *C ");
  Serial.print(hif);
  Serial.println(" *F");
  
  delay(1000);
 // NOW SEND THE DAM TEMP/HUMIDTY DATA!!!!!!!
 theData.nodeID = 1;
 theData.sensorID = NODEID;
 theData.var2_float = f;// changed from .var2_float if .var3 if sending to photon. 
 theData.var3_float = h;// changed from .var3_float if .var3 if sending to photon. 
 radio.sendWithRetry(TONODEID,(const void*)(&theData), sizeof(theData));
 
 digitalWrite(13,HIGH);
 delay(300);
 digitalWrite(13,LOW);
 
}


RX SIDE / PHOTON.

#include <SPI.h>

#include <RFM69.h>
#include <RFM69registers.h>
#include <RFM69_ATC.h>



// NODE 2 RX. 


// RFM69HCW Example Sketch
// Send serial input characters from one RFM69 node to another
// Based on RFM69 library sample code by Felix Rusu
// http://LowPowerLab.com/contact
// Modified for RFM69HCW by Mike Grusin, 4/16

// This sketch will show you the basics of using an
// RFM69HCW radio module. SparkFun's part numbers are:
// 915MHz: 

// See the hook-up guide for wiring instructions:


// Uses the RFM69 library by Felix Rusu, LowPowerLab.com
// Original library: 
// SparkFun repository: 

// Include the RFM69 and SPI libraries:

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

// Addresses for this node. CHANGE THESE FOR EACH NODE!

#define NETWORKID     100   // Must be the same for all nodes
#define MYNODEID      2   // My node ID
#define TONODEID      1   // Destination node ID

// RFM69 frequency, uncomment the frequency of your module:

//#define FREQUENCY   RF69_433MHZ
#define FREQUENCY     RF69_915MHZ

// AES encryption (or not):

#define ENCRYPT       false // Set to "true" to use encryption
#define ENCRYPTKEY    "TOPSECRETPASSWRD" // Use the same 16-byte key on all nodes

// Use ACKnowledge when sending messages (or not):

#define USEACK        false // Request ACKs or not

// Packet sent/received indicator LED (optional):

#define LED           13 // LED positive pin
#define GND           8 // LED ground pin

// Create a library object for our RFM69HCW module:

RFM69 radio;


//////////////////////////////////////////STRUCT TO RECEIVE, SAME ON OTHERSIDE///////////////////

//typedef struct {		
//  int                  nodeID; 
 // int			sensorID;
  //unsigned long         var1_usl; 
//  float                 var2_float;
 // float		  var3_float;
//} Payload;
//Payload theData;


typedef struct {		
  uint16_t nodeID; // changed from int
  uint16_t sensorID;// changed from int
  //unsigned long          var1_usl; 
  uint16_t var2_float; //changed from float  var2_float
  uint16_t var3_float;	//hanged from float  var3_float
} Payload;
Payload theData;

//////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup()
{
  // Open a serial port 

  Serial.begin(9600);
  Serial.print("Node ");
  Serial.print(MYNODEID,DEC);
  Serial.println(" ready");  

  // Set up the indicator LED (optional):

  pinMode(LED,OUTPUT);
  digitalWrite(LED,LOW);
  pinMode(GND,OUTPUT);
  digitalWrite(GND,LOW);

 // Initialize the RFM69HCW:
//RFM69 initialize-------------------------------------------
 
  radio.initialize(FREQUENCY,MYNODEID,NETWORKID);
  //#ifdef IS_RFM69HW
    radio.setHighPower(); //uncomment only for RFM69HW!
  //#endif
  //radio.encrypt(ENCRYPTKEY);
  char buff[50];
  sprintf(buff, "\nTransmitting at %d Mhz...", FREQUENCY==RF69_433MHZ ? 433 : FREQUENCY==RF69_868MHZ ? 868 : 915);
  Serial.println(buff);
  
  //---------------------------------------------------------------------
  
 //byte ackCount=0;
 
}

void loop()
{
  
  if (radio.receiveDone())
  {
    
    if (radio.DATALEN != sizeof(Payload))
      {
      Serial.println("Invalid payload received, not matching Payload struct!");
      
      }
    else
    {
      theData = *(Payload*)radio.DATA; //assume radio.DATA actually contains our struct and not something else
      
      Serial.print(theData.nodeID);
      Serial.print(", ");
      Serial.print(theData.sensorID);
      Serial.print(", ");
      //Serial.print(theData.var1_usl);
      //Serial.print(", ");
      Serial.print(theData.var2_float); 
      Serial.print(", ");
      //Serial.print(" var2(temperature)=");
      //Serial.print(", ");
      Serial.print(theData.var3_float);
      
      //printFloat(theData.var2_float, 5); Serial.print(", "); printFloat(theData.var3_float, 5);
      
      Serial.print(", RSSI= ");
      Serial.println(radio.RSSI);
           
    }//
	
	
    if (radio.ACK_REQUESTED)
    {
      byte theNodeID = radio.SENDERID;
      radio.sendACK();
      //Serial.print(" - 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++%3==0)
    //  {
        //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.print("ok!");
        //else Serial.print("nothing");
      }//
    }//end if radio.ACK_REQESTED
    
  

    Blink(LED,10);
}

void Blink(byte PIN, int DELAY_MS)
// Blink an LED for a given number of ms
{
  digitalWrite(PIN,HIGH);
  delay(DELAY_MS);
  digitalWrite(PIN,LOW);
}

________________________________________________________________++++++
THANKS AGAIN FOR YOUR HELP.

I'm not convinced that this does what you expect.
IMHO you might rather want to use

  memcpy((void*)&theData, (const void*)radio.DATA, sizeof(Payload));

AGAIN THANKS SO MUCH,

I plugged in
memcpy((void*)&theData, (const void*)radio.DATA, sizeof(Payload));

on the receiver side.

else
    {
        memcpy((void*)&theData, (const void*)radio.DATA, sizeof(Payload));
      
      Serial.print(theData.nodeID);
      Serial.print(", ");
      Serial.print(theData.sensorID);
      Serial.print(", ");
      //Serial.print(theData.var1_usl);
      //Serial.print(", ");
      Serial.print(theData.var2_float); 
      Serial.print(", ");
      //Serial.print(" var2(temperature)=");
      //Serial.print(", ");
      Serial.print(theData.var3_float);
      
      //printFloat(theData.var2_float, 5); Serial.print(", "); printFloat(theData.var3_float, 5);
      
      Serial.print(", RSSI= ");
      Serial.println(radio.RSSI);
           
    }//

now I get
same response on receiver (PHOTON) side.
I get a very larg number on the RSSI value -123
0,0,0,0, RSSI + -123

looks like the numbers are still off.
any suggestings.
Thanks again.

Try to print out byte by byte of radio.DATA. Maybe it’s got to do with the endianness of the two controllers.
Also have a printout of sizeof(theData) if this matches the expected 16byte - if not, it might be due to mem padding to 32bit boundaries.

But the RSSI has nothing to do with the actual payload?

ok,
thanks for your help.
This is what I am getting now. reading the size of the data.
when I use the same code to receive on a pro-mini 3.3v 8ghz.
size of the data is 8 bytes
stuct print out is. 1,1,80,32 rssi -23
data prints out
1
0
1
0
80
0
32
0

which is correct.

On receiver side using the (photon) I am getting
getting 0,0,0,0 rssi-23
It says receiving 8 bytes and see this change to 16bytes by manipulating on the sender side to 16_t.
it dose not print out the individual data

I am using
theData = (Payload)radio.DATA; //assume radio.DATA actually contains our struct and not something else
Serial.print(" receiving data “);
Serial.print(sizeof(theData));
Serial.print(” bytes) … ");
Serial.println();
for (byte i = 0; i < radio.DATALEN; i++)
Serial.println((int)radio.DATA[i]);

If I use this exact same data on a receiving pro - mini I get the correct date and it works normally.

It looks like it is only taking the 0 ( little endian) not the big endian. particle documentation notes photon and core work with the little endian. it looks like the photon is getting the data since it is printing out the number of bytes correct???
not sure why it doesn’t print out the individual data.

Any suggestions on how to switch this?
I am just starting out on this coding stuff, I not sure if I want to get into pointers or byte shifting.
Seams like it shouldn’t be this difficult.

Would it be easier to use the pro min as the receiver node and I2c the data over to the photo to use the wifi chip to mqtt?.

Any help is appreciated.
Thanks so much.

@Webzter30 Sorry for reviving an old post. Hope you came right.

I’m also trying to use a Pro Mini with RFM69 sending sensor data to a Photon. I’m including the RFM69 library in the Web IDE and wired up the photon using the Photon SPI pinouts. But I’m not having success. While you received data…I’m not receiving any data (an Arduino with the same code receives data successfully).

Can you recall or share more about the RFM69 library you used (any modifications?) and any special wiring changes?

Thank you

@bloukingfisher,
Check out the wiring used in this board - it works for me:
http://hallard.me/particle-gateway/

Thanks @bpr. I confirmed based on the schematic in that project that my wiring is the same (referenced with code in my post).

So the wiring works for you (and I have the same) so I have that right.

Are you using the Web IDE or local Particle Atom IDE as referenced in the project?

I compiled in the Web ide

Thanks @bpr - See my post - it doesn’t work for me but perhaps it is due to the fact that I’m using “H” high power modules? I’ve created and published RFM69-Particle that works with “H” (and others). Examples included that work, and you can use the stock “Hello World” example on Arduino and the library example on Photon to communicate between Promini and RFM69 on Photon if anyone is interested.

1 Like