sending structs, need clarification on some things.

You might want to consider looking over Bill Porter's excellent EasyTransfer library. He uses a similar method of using defined structures for both the sender and receiver and includes error detection in the packets sent and received. He has versions for both using serial and I2C buss transfers, and there is something in his cover sheet about using simple RF links?

So it may not be a complete replacement for what you are doing, but you may certainly learn a lot by checking out his source code.

Lefty

Cyric:
so how do i go about flushing the buffer?

imuBuff.imuRoll = 0;
imuBuff.imuPitch = 0;
imuBuff.imuYaw= 0;

PeterH:

Cyric:
so how do i go about flushing the buffer?

imuBuff.imuRoll = 0;

imuBuff.imuPitch = 0;
imuBuff.imuYaw= 0;

smacks head on keyboard.

%100 fail now

TX

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"

RF24 radio(48,49);
void setup(){
  Serial.begin(57600); 
  //**************Start Transiever (NRF24L01) config**************
  printf_begin();
  printf("\n\rRadio Setup\n\r");
  radio.begin();
  radio.setDataRate(RF24_250KBPS);
//radio.setCRCLength(RF24_CRC_16);
//radio.setPayloadSize(14 * sizeof(byte));
//radio.setChannel(2);
  radio.setAutoAck(true);
  radio.setRetries(5,1000);
  radio.openReadingPipe(1,0xF0F0F0F0E1LL);
  radio.openWritingPipe(0xF0F0F0F0D2LL);
  radio.stopListening();
  radio.printDetails();

  //**************End Transiever (NRF24L01) config**************
}  
struct imuBuff_t{
  float imuRoll;
  float imuPitch;
  float imuYaw;
}
imuBuff;
//**************************************************
//************* Start Main Loop section ************
//**************************************************
void loop()
{
  //////////////////////////////  
  imuBuff.imuRoll  = 31.99;   //
  imuBuff.imuPitch = -150.82; //Temp Values
  imuBuff.imuYaw   = 3.60;    //
  //////////////////////////////
  TransStruct();
}
//**************************************************
//************* END Main Loop section***************
//**************************************************
//-+-+-+>>>> Start Struct Transmit section<<<<<<-+-+-+
void TransStruct(){

  bool ok = radio.write((byte *) &imuBuff, sizeof(imuBuff));
  if (ok) 
    printbuffs();
  else  
    printf("failed.\n\r");
  delay(10);
}
//-+-+-+>>>> END Struct Transmit section<<<<<<-+-+-+
void printbuffs(){
  Serial.print(imuBuff.imuRoll);
  Serial.print(",");
  Serial.print(imuBuff.imuPitch);
  Serial.print(",");
  Serial.print(imuBuff.imuYaw);
  Serial.println();
}

RX

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"
RF24 radio(48,49);
void setup(){
  Serial.begin(57600); 
  //**************Start Transiever (NRF24L01) config**************
  printf_begin();
  printf("\n\rRadio Setup\n\r");
  radio.begin();
  radio.setDataRate(RF24_250KBPS);
//radio.setCRCLength(RF24_CRC_16);
//radio.setPayloadSize(14 * sizeof(byte));
//radio.setChannel(2);
  radio.setAutoAck(true);
  radio.setRetries(5,1000);
  radio.openReadingPipe(1,0xF0F0F0F0D2LL);
  radio.openWritingPipe(0xF0F0F0F0E1LL);
  radio.startListening();
  radio.printDetails();
  //**************End Transiever (NRF24L01) config**************
}  
struct IMU_t{
  float imuRoll;
  float imuPitch;
  float imuYaw;
}
imuBuff;
//**************************************************
//************* Start Main Loop section ************
//**************************************************
void loop()
{
  imuBuff.imuRoll = 0;
  imuBuff.imuPitch = 0;
  imuBuff.imuYaw= 0;
  RecStruct();
}
//**************************************************
//************* END Main Loop section***************
//**************************************************
//-+-+-+>>>> Start Struct Transmit section<<<<<<-+-+-+
void RecStruct(){
  if ( radio.available() )
  {
    bool ok = radio.read((byte *)&imuBuff, sizeof(imuBuff));
    if (ok) 
      printbuffs();
    else  
      printf("failed.\n\r");
     }
  delay(10);

}
//-+-+-+>>>> END Struct Transmit section<<<<<<-+-+-+
void printbuffs(){
  Serial.print(imuBuff.imuRoll);
  Serial.print(",");
  Serial.print(imuBuff.imuPitch);
  Serial.print(",");
  Serial.print(imuBuff.imuYaw);
  Serial.println(); 
}

Cyric:
%100 fail now

Failing how? Does the transmit return success? Does the receive trigger once per transmitted packet? Does it return success? Does the received packet contain what you expected?

I'd suggest slowing the transmission down from 10ms (100Hz) to 1000ms (1Hz).

Have you successfully run the example sketches such as PingPair that come with the RF24 library? This would prove that you are using the correct SPI and CE/CS pins and that the hardware was working. (Out of a batch of nRF24L01+, I had several duds.)

Where did these values come from?

radio.setRetries(5,1000);

I checked my hardware after i was just gunna say yeah i can use the examples and noticed the connector i made was not holding tight to the NRF so i swaped out for a new one on my UNO and ran ping and worked fine. changing delay(10) will fail transmit/rec both even (11) or no delay. the 5,1000 was from trying to achieve less fail by telling it not to retransmit more than 5 times and wait 1 sec in between tries.

TX (uno)

Now sending 87...ok...Got response 87, round-trip delay: 24
Now sending 1112...ok...Got response 1112, round-trip delay: 22
Now sending 2135...ok...Got response 2135, round-trip delay: 21
Now sending 3158...ok...Got response 3158, round-trip delay: 21
Now sending 4179...ok...Got response 4179, round-trip delay: 23
Now sending 5202...ok...Got response 5202, round-trip delay: 23

RX(Mega2560)

Got payload 87...Sent response.
Got payload 1112...Sent response.
Got payload 2135...Sent response.
Got payload 3158...Sent response.
Got payload 4179...Sent response.
Got payload 5202...Sent response.

so i got excited and tried the old code.
but when i got back to the previous TX/RX code it is choppy send/rec and some fails. also if i chage it to even 11ms much less 1000 it is %100 fail agin.
Full code as it sits.

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"

RF24 radio(48,49);
void setup(){
  Serial.begin(57600); 
  //**************Start Transiever (NRF24L01) config**************
  printf_begin();
  printf("\n\rRadio Setup\n\r");
  radio.begin();
  radio.setDataRate(RF24_2MBPS);
 // radio.setCRCLength(RF24_CRC_16);
//  radio.setPayloadSize(14 * sizeof(byte));
//  radio.setChannel(80);
  radio.setAutoAck(true);
//  radio.setRetries(15,15);
  radio.openReadingPipe(1,0xF0F0F0F0E1LL);
  radio.openWritingPipe(0xF0F0F0F0D2LL);
  radio.stopListening();
  radio.printDetails();

  //**************End Transiever (NRF24L01) config**************
}  
struct imuBuff_t{
  float imuRoll;
  float imuPitch;
  float imuYaw;
}
imuBuff;
//**************************************************
//************* Start Main Loop section ************
//**************************************************
void loop()
{
  //////////////////////////////  
  imuBuff.imuRoll  = 31.99;   //
  imuBuff.imuPitch = -150.82; //Temp Values
  imuBuff.imuYaw   = 3.60;    //
  //////////////////////////////
  TransStruct();
}
//**************************************************
//************* END Main Loop section***************
//**************************************************
//-+-+-+>>>> Start Struct Transmit section<<<<<<-+-+-+
void TransStruct(){

  bool ok = radio.write((byte *) &imuBuff, sizeof(imuBuff));
  if (ok) 
    printbuffs();
  else  
    printf("failed.\n\r");
  delay(10);
}
//-+-+-+>>>> END Struct Transmit section<<<<<<-+-+-+
void printbuffs(){
  Serial.print(imuBuff.imuRoll);
  Serial.print(",");
  Serial.print(imuBuff.imuPitch);
  Serial.print(",");
  Serial.print(imuBuff.imuYaw);
  Serial.println();
}

RX

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"
RF24 radio(8,9);
void setup(){
  Serial.begin(57600); 
  //**************Start Transiever (NRF24L01) config**************
  printf_begin();
  printf("\n\rRadio Setup\n\r");
  radio.begin();
  radio.setDataRate(RF24_2MBPS);
//  radio.setCRCLength(RF24_CRC_16);
 // radio.setPayloadSize(14 * sizeof(byte));
 // radio.setChannel(80);
  radio.setAutoAck(true);
  //radio.setRetries(15,15);
  radio.openReadingPipe(1,0xF0F0F0F0D2LL);
  radio.openWritingPipe(0xF0F0F0F0E1LL);
  radio.startListening();
  radio.printDetails();
  //**************End Transiever (NRF24L01) config**************
}  
struct IMU_t{
  float imuRoll;
  float imuPitch;
  float imuYaw;
}
imuBuff;
//**************************************************
//************* Start Main Loop section ************
//**************************************************
void loop()
{
  imuBuff.imuRoll = 0;
  imuBuff.imuPitch = 0;
  imuBuff.imuYaw= 0;
  RecStruct();
}
//**************************************************
//************* END Main Loop section***************
//**************************************************
//-+-+-+>>>> Start Struct Transmit section<<<<<<-+-+-+
void RecStruct(){
  if ( radio.available() )
  {
    bool ok = radio.read((byte *)&imuBuff, sizeof(imuBuff));
    if (ok) 
      printbuffs();
    else  
      printf("failed.\n\r");
     }
  delay(10);

}
//-+-+-+>>>> END Struct Transmit section<<<<<<-+-+-+
void printbuffs(){
  Serial.print(imuBuff.imuRoll);
  Serial.print(",");
  Serial.print(imuBuff.imuPitch);
  Serial.print(",");
  Serial.print(imuBuff.imuYaw);
  Serial.println(); 
}

TX

failed.
31.99,-150.82,3.60
31.99,-150.82,3.60
31.99,-150.82,3.60
31.99,-150.82,3.60
31.99,-150.82,3.60
31.99,-150.82,3.60
31.99,-150.82,3.60
failed.
31.99,-150.82,3.60
failed.
31.99,-150.82,3.60
31.99,-150.82,3.60
31.99,-150.82,3.60
31.99,-150.82,3.60
31.99,-150.82,3.60
failed.
31.99,-150.82,3.60
31.99,-150.82,3.60
failed.
failed.
31.99,-150.82,3.60
31.99,-150.82,3.60
31.99,-150.82,3.60
failed.
31.99,-150.82,3.60
31.99,-150.82,3.60
failed.
failed.
failed.
31.99,-150.82,3.60

RX

31.99,-150.82,3.60
31.99,-150.82,3.60
31.99,-150.82,3.60
31.99,-150.82,3.60
31.99,-150.82,3.60
31.99,-150.82,3.60
31.99,-150.82,3.60
31.99,-150.82,3.60
31.99,-150.82,3.60
31.99,-150.82,3.60
31.99,-150.82,3.60
31.99,-150.82,3.60
31.99,-150.82,3.60
31.99,-150.82,3.60
31.99,-150.82,3.60
31.99,-150.82,3.60

So it seems you know the hardware is sound, and it is capable of sending and receiving reliably.

As the next step, I suggest you make the radio settings in your sketches identical to the ones in the demo that worked.

I'm skeptical about your changes to the retry interval given this comment in the header:

  /**
   * Set the number and delay of retries upon failed submit
   *
   * @param delay How long to wait between each retry, in multiples of 250us,
   * max is 15.  0 means 250us, 15 means 4000us.
   * @param count How many retries before giving up, max 15
   */
 void setRetries(uint8_t delay, uint8_t count);

had never used .setRetries it before and saw it in a demo and looked it up on github had not saw the last statement about 15 max.

i did setup the radios like the pingpair example and they failed %100 of the time. it's a packet size issue so i had to change the packets and if i dont have * sizeof(byte) in there it fails. so as it stands only thing that works for the following sketchs is. SetpayloadSize(20 * sizeof(byte)); {anything above 20 works so 21 22 23 24}

TX

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"

RF24 radio(48,49);
void setup(){
  Serial.begin(57600); 
  //**************Start Transiever (NRF24L01) config**************
  printf_begin();
  printf("\n\rRadio Setup\n\r");
  radio.begin();
  radio.setRetries(15,15);
  radio.setDataRate(RF24_2MBPS);
  radio.setCRCLength(RF24_CRC_16);
  radio.setPayloadSize(24 * sizeof(byte));
  radio.setChannel(100);
  radio.setAutoAck(true);
  radio.openReadingPipe(1,0xF0F0F0F0E1LL);
  radio.openWritingPipe(0xF0F0F0F0D2LL);
  radio.stopListening();
  radio.printDetails();
  //**************End Transiever (NRF24L01) config**************
}  
struct StructBuff_t {
  float imuRoll;
  float imuPitch;
  float imuYaw;
  unsigned int AP;
}
StructBuff;
//**************************************************
//************* Start Main Loop section ************
//**************************************************

void loop()
{
float roll = random(-150,150);
float pitch = random(-150,150);
float yaw = random(0,360);
unsigned int ap = random(0,75);

  StuffStructBuff(roll,pitch,yaw,ap);  
   TransStruct();
 }
//**************************************************
//************* END Main Loop section***************
//**************************************************
//-+-+-+>>>> Start Struct Transmit section<<<<<<-+-+-+
void TransStruct(){
  bool ok = radio.write((byte *) &StructBuff, sizeof(StructBuff));
  if (ok) 
    printbuffs();
    //printf("ok...\n\r"); 
  else  
    printf("failed.\n\r");
   delay(10);
}
//-+-+-+>>>> END Struct Transmit section<<<<<<-+-+-+

void printbuffs(){
  Serial.print(StructBuff.imuRoll);
  Serial.print(",");
  Serial.print(StructBuff.imuPitch);
  Serial.print(",");
  Serial.print(StructBuff.imuYaw);
  Serial.print(",");
  Serial.print(StructBuff.AP);
  Serial.println();
 }
void StuffStructBuff(float inRoll, float inPitch, float inYaw, unsigned int inAP){//**Working**
  StructBuff.imuRoll = inRoll;  
  StructBuff.imuPitch = inPitch;  
  StructBuff.imuYaw = inYaw;  
  StructBuff.AP = inAP;  
}

RX

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"
RF24 radio(8,9);
void setup(){
  Serial.begin(57600); 
  //**************Start Transiever (NRF24L01) config**************
  printf_begin();
  printf("\n\rRadio Setup\n\r");
  radio.begin();
  radio.setRetries(15,15);
  radio.setDataRate(RF24_2MBPS);
  radio.setCRCLength(RF24_CRC_16);
  radio.setPayloadSize(24 * sizeof(byte));
  radio.setChannel(100);
  radio.setAutoAck(true);
  radio.openReadingPipe(1,0xF0F0F0F0D2LL);
  radio.openWritingPipe(0xF0F0F0F0E1LL);
  radio.startListening();
  radio.printDetails();
  //**************End Transiever (NRF24L01) config**************
}  
struct StructBuff_t {
  float imuRoll;
  float imuPitch;
  float imuYaw;
  unsigned int AP;
}
StructBuff;
//**************************************************
//************* Start Main Loop section ************
//**************************************************
void loop()
{
    RecStruct();
    }

//**************************************************
//************* END Main Loop section***************
//**************************************************
//-+-+-+>>>> Start Struct Transmit section<<<<<<-+-+-+
void RecStruct(){
  if ( radio.available() )
    {
  bool ok = radio.read((byte *)&StructBuff, sizeof(StructBuff));
  if (ok) 
    printbuffs();
  //    printf("ok...\n\r"); 
  else  
    printf("failed.\n\r");
    }
  delay(10);

}

//-+-+-+>>>> END Struct Transmit section<<<<<<-+-+-+
void printbuffs(){
  Serial.print(StructBuff.imuRoll);
  Serial.print(",");
  Serial.print(StructBuff.imuPitch);
  Serial.print(",");
  Serial.print(StructBuff.imuYaw);
  Serial.print(",");
  Serial.print(StructBuff.AP);
  Serial.println();

}

TX output

-127.00,-41.00,0.00,65
failed.
-23.00,79.00,160.00,37
failed.
failed.
-34.00,85.00,97.00,26
failed.
-71.00,-101.00,99.00,21
failed.
35.00,95.00,308.00,16
failed.
58.00,94.00,28.00,65
failed.
-128.00,16.00,189.00,74
failed.

RX

-127.00,-41.00,0.00,65
-23.00,79.00,160.00,37
-34.00,85.00,97.00,26
-71.00,-101.00,99.00,21
35.00,95.00,308.00,16
58.00,94.00,28.00,65
-128.00,16.00,189.00,74

so size of the struct is 20 it seems. as for the timing man it's slow bout 1.5 updates per sec was hoping for 3 or 4 per sec.

The send failures suggest that your radio connection may be marginal and not working reliably with the bigger payload sizes. You could try reducing the data rate and increasing the power levels on both sides. (I seem to remember that your earlier code already did this without success, but I'm not sure.)

When setting the payload size I suggest you use sizeof(StructBuff) rather than hard-coding the size.

You're filling the buffer the hard way. Wouldn't it be easier to just assign values to the fields directly?

StructBuff.imuRoll = random(-150,150);
StructBuff.imuPitch = random(-150,150);
StructBuff.imuYaw = random(0,360);
StructBuff.AP = random(0,75);

I'm at a loss to explain why the transmission is taking so long. You could put code in to measure the elapsed time for the call to radio.write() and see if the delay is happening there? I don't see any other sources of delay except the serial output so I would have expected it to run much more frequently than that, unless you've added delays you haven't shown us.

so size of the struct is 20 it seems. as for the timing man it's slow bout 1.5 updates per sec was hoping for 3 or 4 per sec.

I would also use sizeof to determine data type sizes ( no need to fix hard-coded values when you add stuff to the struct ):

struct IMU_t{
  float imuRoll;
  float imuPitch;
  float imuYaw;
};

Is 12 bytes,

struct StructBuff_t {
  float imuRoll;
  float imuPitch;
  float imuYaw;
  unsigned int AP;
};

Is 14 bytes.

You can't have a string in a struct. If you need characters, you need a fixed-size array of characters, not a string.

Your RX code is also wrong.

When you have radio.available() true, you do not necessarily have a full struct of bytes available.

If your struct is 50 bytes ( whatever ) and your radio serial port has received 20 bytes, then radio.available() will
be true and you will attempt to read 50 bytes and there is only 20 bytes received so far and your data will
therefore be wrong in some way.

You need to not attempt to read() the data until it is all there. Or else read the data which you have
and then wait for the rest to arrive.

michinyon:
You need to not attempt to read() the data until it is all there. Or else read the data which you have
and then wait for the rest to arrive.

got any examples on how would i go about doing that?

michinyon:
When you have radio.available() true, you do not necessarily have a full struct of bytes available.

I think you're mistaken about how the RF24 library works. This is not a streaming interface; the radio sends and receives complete packets and returns the whole packet via a single read operation.

PeterH:

michinyon:
When you have radio.available() true, you do not necessarily have a full struct of bytes available.

I think you're mistaken about how the RF24 library works. This is not a streaming interface; the radio sends and receives complete packets and returns the whole packet via a single read operation.

right get that part but how do i tell if the packet is complete so i can read it. or is simply calling radio.read() doing that?

From the post I made here sending structs, need clarification on some things. - #5 by pYro_65 - Programming Questions - Arduino Forum

There is a function called: isAvailable()

It possibly returns the number of bytes available, or maybe just a true/false, anyway check it out.

Edit, these two functions below tell me that the data is 'payload' size, if the data you put in it is smaller it will be padded upto 'payload' size:

  /**
   * Get Static Payload Size
   *
   * @see setPayloadSize()
   *
   * @return The number of bytes in the payload
   */
  uint8_t getPayloadSize(void);

  /**
   * Get Dynamic Payload Size
   *
   * For dynamic payloads, this pulls the size of the payload off
   * the chip
   *
   * @return Payload length of last-received dynamic payload
   */
  uint8_t getDynamicPayloadSize(void);

The max payload size will be 32 bytes IIRC. Once you fix your string issue you need to make sure a single payload doesn't exceed that or it will be truncated.

When using the RF24Network library it uses 12 bytes for the header so that leaves only 20 bytes for the rest of the payload, something that took a while to realise.

pYro_65:
From the post I made here sending structs, need clarification on some things. - #5 by pYro_65 - Programming Questions - Arduino Forum

There is a function called: isAvailable()

It possibly returns the number of bytes available, or maybe just a true/false, anyway check it out.

Edit, these two functions below tell me that the data is 'payload' size, if the data you put in it is smaller it will be padded upto 'payload' size:

I do not quite understand what your trying to get me to do with the payload size. i define payload size at the size of StructBuff so no matter what size StructBuff is payload is always the size of it.
How ever it seems there might be an "overflow" issue with it given what Tack said.
Unless it auto breaks up the payload and sends them in pieces if that is the case i dont know how the struct on the RX will like that.

this is all new territory for me
michinyon wrote:

Your RX code is also wrong.

When you have radio.available() true, you do not necessarily have a full struct of bytes available.

If your struct is 50 bytes ( whatever ) and your radio serial port has received 20 bytes, then radio.available() will
be true and you will attempt to read 50 bytes and there is only 20 bytes received so far and your data will
therefore be wrong in some way.

You need to not attempt to read() the data until it is all there. Or else read the data which you have
and then wait for the rest to arrive.

and i cheked it comes back true if there is payload. but as Tack pointed out.

The max payload size will be 32 bytes IIRC. Once you fix your string issue you need to make sure a single payload doesn't exceed that or it will be truncated.

When using the RF24Network library it uses 12 bytes for the header so that leaves only 20 bytes for the rest of the payload, something that took a while to realize.

i am going to need to figure out how to break down my block of data to smaller ones so it does not get truncated before i even continue trying to send any more data the 3 floats from my IMU are already to much data at 24 bytes.

tack:
When using the RF24Network library it uses 12 bytes for the header so that leaves only 20 bytes for the rest of the payload, something that took a while to realise.

The library seems to be Maniacbug's RF24 library, which does not have that behaviour. The maximum payload size here is 32 bytes.