[solved] sending char arry via NRF24L01

hi Guys

i am trying to send a char array using arduino uno board andNRF24L01 modules

Here is the code for both transmitter and receiver

//~ 1 - GND
 //~ 2 - VCC 3.3V !!! NOT 5V
 //~ 3 - CE to Arduino pin 9
 //~ 4 - CSN to Arduino pin 10
 //~ 5 - SCK to Arduino pin 13
 //~ 6 - MOSI to Arduino pin 11
 //~ 7 - MISO to Arduino pin 12
 //~ 8 - UNUSED

#include <SPI.h>
//~ #include <TMRh20nRF24L01.h>
//~ #include <TMRh20RF24.h>
#include <nRF24L01.h>
#include <RF24.h>


#define CE_PIN   9
#define CSN_PIN 10

// NOTE: the "LL" at the end of the constant is "LongLong" type
// These are the IDs of each of the slaves
const uint64_t slaveID[2] = {0xE8E8F0F0E1LL, 0xE8E8F0F0E2LL} ;

RF24 radio(CE_PIN, CSN_PIN); // Create a Radio

char  dataToSend[64]="e7665072be018b6b58ea9e40cf38553d6dc293cda4c9d94cda6e91ca61b3a073";

unsigned long currentMillis;
unsigned long prevMillis;
unsigned long txIntervalMillis = 1000;
int txVal = 0;
float ackMessg[2]={1,2};
byte ackMessgLen = 4; // NB this 4 is the number of bytes in the 2 ints that will be recieved


void setup() {

    Serial.begin(9600);
    Serial.println("Track Control Starting");
    radio.begin();
    radio.setDataRate( RF24_250KBPS );
    radio.enableAckPayload();
    radio.setRetries(3,5); // delay, count
}

//====================

void loop() {

    currentMillis = millis();
    if (currentMillis - prevMillis >= txIntervalMillis) {

    radio.openWritingPipe(slaveID[0]); // calls the first slave
                                        // there could be a FOR loop to call several slaves in turn
    
    bool rslt;
    rslt = radio.write( dataToSend, sizeof(dataToSend) );
    Serial.print("\nRSLT (1 = success) ");
    Serial.println(rslt);
    Serial.print("Data Sent ");
    Serial.print(dataToSend[0]);
    Serial.print("  ");
    Serial.println(dataToSend[1]);
    if ( radio.isAckPayloadAvailable() ) {
        radio.read(ackMessg,ackMessgLen);
        Serial.print("Acknowledge received: ");
        Serial.print(ackMessg[0]);
        Serial.print("  ");
        Serial.println(ackMessg[1]);
    }
    prevMillis = millis();
 }
}
//~ 1 - GND
    //~ 2 - VCC 3.3V !!! NOT 5V
    //~ 3 - CE to Arduino pin 9
    //~ 4 - CSN to Arduino pin 10
    //~ 5 - SCK to Arduino pin 13
    //~ 6 - MOSI to Arduino pin 11
    //~ 7 - MISO to Arduino pin 12
    //~ 8 - UNUSED

#include <SPI.h>
//~ #include <TMRh20nRF24L01.h>
//~ #include <TMRh20RF24.h>
#include <nRF24L01.h>
#include <RF24.h>


#define CE_PIN   9
#define CSN_PIN 10

// NOTE: the "LL" at the end of the constant is "LongLong" type

const uint64_t   deviceID = 0xE8E8F0F0E1LL; // Define the ID for this slave

int valChange = 1;

RF24 radio(CE_PIN, CSN_PIN);

char  dataReceived[64];
int ackData[2] = {12,23};

void setup() {

    Serial.begin(9600);
    delay(1000);
    Serial.println("Hand Controller Starting");
    radio.begin();
    radio.setDataRate( RF24_250KBPS );
    radio.openReadingPipe(1,deviceID);
    radio.enableAckPayload();
    radio.writeAckPayload(1, ackData, sizeof(ackData));
    radio.startListening();
}

void loop() {

    if ( radio.available() ) {
        radio.read( dataReceived, sizeof(dataReceived) );
         for (int x = 0; x <64; x++) {
      //if (dataReceived[x] < 16) {
      //  Serial.write('0');
    // }
      Serial.print(dataReceived[x]);}
      Serial.println();
        radio.writeAckPayload(1, ackData, sizeof(ackData));
        
        ackData[0] += valChange; // this just increments so you can see that new data is being sent
    }
}

the receiver receives half of the array only

here is a copy from the output that i get on my receiver

Hand Controller Starting
e7665072be018b6b58ea9e40cf38553d

how can i receive the full array?

The buffer for the payload is 32 bytes. You will need to split the payload into 32 (or less) byte chunks.

See here.

groundFungus:
The buffer for the payload is 32 bytes. You will need to split the payload into 32 (or less) byte chunks.

See here.

hi
thank u for ur reply
is there a function can do that directly?

Not that Iknow of. I have never had the need to exceed the 32 byte limit. In the link that I posted it is suggested that you split up the data into as many packets as necessary and send, along with the first packet, the number of packets for the receiver to expect.

groundFungus:
Not that Iknow of. I have never had the need to exceed the 32 byte limit. In the link that I posted it is suggested that you split up the data into as many packets as necessary and send, along with the first packet, the number of packets for the receiver to expect.

yes i have read the suggestion in the post but i am asking if there is a tested way to do that

Like I said, not to my knowledge. Maybe Google knows?

groundFungus:
Like I said, not to my knowledge. Maybe Google knows?

i have searched but can not find something helpful that is why i asked for help here

Maybe Robin2, the author of the simple rf24 tutorial, will see your post and have some advice. Patience.

groundFungus:
Maybe Robin2, the author of the simple rf24 tutorial, will see your post and have some advice. Patience.

ok thank u very much

Have a look at this Simple nRF24L01+ Tutorial. The examples send char arrays.

Wireless problems can be very difficult to debug so get the wireless part working on its own before you start adding any other features.

The examples are as simple as I could make them and they have worked for other Forum members. If you get stuck it will be easier to help with code that I am familiar with. Start by getting the first example to work

...R

Robin2:
Have a look at this Simple nRF24L01+ Tutorial. The examples send char arrays.

Wireless problems can be very difficult to debug so get the wireless part working on its own before you start adding any other features.

The examples are as simple as I could make them and they have worked for other Forum members. If you get stuck it will be easier to help with code that I am familiar with. Start by getting the first example to work

...R

hello Robin

thank u very much for ur reply

the problem that i am facing is the payload size as my char array is more 32 ,so is there a way or an example that explains that?

that should not be rocket science with pointers esp. as your array is 64 = 2 x 32

char  dataToSend[] = "e7665072be018b6b58ea9e40cf38553d6dc293cda4c9d94cda6e91ca61b3a073";
...
  char* ptr1 = dataToSend;
  char* ptr2 = dataToSend + 32;
  // then send ptr1 with 32 bytes and then ptr2 with 32 bytes as well (or sizeof(dataToSend)-32
  // You might want to think about sending the trailing null or not

and you need possibly some info to say if this is the first part or second part of the message, so may be need to cut in 3 parts as it won't fit

mestek86:
the problem that i am facing is the payload size as my char array is more 32 ,so is there a way or an example that explains that?

What @J-M-L has suggested is a reasonable approach.

However I would be interested to know where the 64 bytes of the message come from and whether there might be a more natural way to divide it up.

...R

Yea, I'd define a packet struct and send the data in 3 packets with payloads sizes of 21, 21, and 22 bytes. The first byte of the struct would indicate which chunk it is (0, 1, 2). This would also form a sequence number to tell you if you ever drop a packet. In that case, scrap the entire message and wait for the start of the next 3-packet group.

struct packet {
  uint8_t idNumber;
  char payload[22];
};

I think the NRF24L01 frame includes a checksum and the received frame is dropped if it doesn't match. So, you should only receive valid frames. Hence, you don't need to include a checksum in your packet.

Your

char  dataToSend[64]="e7665072be018b6b58ea9e40cf38553d6dc293cda4c9d94cda6e91ca61b3a073";

is ASCII-HEX, it would fit in a single packet if you would send it as raw binary.

gfvalvo:
Yea, I'd define a packet struct and send the data in 3 packets with payloads sizes of 21, 21, and 22 bytes. The first byte of the struct would indicate which chunk it is (0, 1, 2). This would also form a sequence number to tell you if you ever drop a packet. In that case, scrap the entire message and wait for the start of the next 3-packet group.

struct packet {

uint8_t idNumber;
 char payload[22];
};




I think the NRF24L01 frame includes a checksum and the received frame is dropped if it doesn't match. So, you should only receive valid frames. Hence, you don't need to include a checksum in your packet.

interesting method ,but i have not used struct before with nRF
how can i do that?

Whandall:
Your

char  dataToSend[64]="e7665072be018b6b58ea9e40cf38553d6dc293cda4c9d94cda6e91ca61b3a073";

is ASCII-HEX, it would fit in a single packet if you would send it as raw binary.

how to send it in one packet so??

char  dataToSend[32]= {
 0xe7, 0x66, 0x50, 0x72, 0xbe, 0x01, 0x8b, 0x6b,
 0x58, 0xea, 0x9e, 0x40, 0xcf, 0x38, 0x55, 0x3d,
 0x6d, 0xc2, 0x93, 0xcd, 0xa4, 0xc9, 0xd9, 0x4c,
 0xda, 0x6e, 0x91, 0xca, 0x61, 0xb3, 0xa0, 0x73
};

J-M-L:
that should not be rocket science with pointers esp. as your array is 64 = 2 x 32

char  dataToSend[] = "e7665072be018b6b58ea9e40cf38553d6dc293cda4c9d94cda6e91ca61b3a073";

...
 char* ptr1 = dataToSend;
 char* ptr2 = dataToSend + 32;
 // then send ptr1 with 32 bytes and then ptr2 with 32 bytes as well (or sizeof(dataToSend)-32
 // You might want to think about sending the trailing null or not




and you need possibly some info to say if this is the first part or second part of the message, so may be need to cut in 3 parts as it won't fit

how to do that using pointers ?,i am not familiar with pointers at all

mestek86:
interesting method ,but i have not used struct before with nRF
how can i do that?

Check out the prototype for the write() method:

bool write( const void* buf, uint8_t len );

It takes a 'const void *' as a pointer to the data and a 'uint8_t' as the number of bytes to send.

So, you can pass it a pointer to any data structure you want.