File transfer Arduino DUE and nRF24L01+

Hello,
I have written a code that transfers the file between two Arduinos with SD Card an nRF24L01+.
I'm not very experienced in programming so it might be wrong. It Works, but Randomly looses some bytes. Can you please help me to understand if i did it right? And if the last buffer is smaller that 32 Bytes, it is not transmitted... How would you solve this?

Transmitter

#include <SPI.h>
#include <SD.h>
#include "RF24.h"
bool radioNumber = 0;
RF24 radio(7, 8);
byte buf[32] = {0};
File myFile;
byte addresses[][6] = {"1Node", "2Node"};
bool role = 0;
void setup() {

  pinMode(53, OUTPUT);
  digitalWrite(53, LOW);
  Serial.begin (115200) ;

  if (!SD.begin(4))
  {
    Serial.println("initialization of SD failed!");
    return;
  }
  Serial.println("initialization done.");
  digitalWrite(53, HIGH);

  Serial.println(F("E M I S S O R"));
  radio.begin();
  radio.setPALevel(RF24_PA_MAX);
  radio.setPayloadSize(32);
  radio.setDataRate(RF24_2MBPS);
  radio.setChannel(0x7d);
  radio.printDetails();
    radio.setAutoAck(1);                     // Ensure autoACK is enabled
  radio.setRetries(3,15); 
  if (radioNumber) {
    radio.openWritingPipe(addresses[1]);
    radio.openReadingPipe(1, addresses[0]);
  }
  else
  { radio.openWritingPipe(addresses[0]);
    radio.openReadingPipe(1, addresses[1]);
  }
sendfile();
}

void readfile() {
  int i = 0;

  while (myFile.available())
  {
    buf[i] = myFile.read();
    i++;
    if (i == 32)
    {
     Serial.println(F(buf));
      radio.writeFast(buf,sizeof(buf));
      delay(50);
      i = 0;
    }
  }
}

void sendfile() {
   myFile = SD.open("1.txt");
  if (myFile)
  {
    readfile ();// Função que vai fazer o envio
    myFile.close();
    radio.powerDown();
  }
  else
  {
    // if the file didn't open, print an error:
    Serial.println("error opening file");
  }
}
void loop() {
   
 //  delay(15000);
}

Receiver

#include "RF24.h"


#include <SPI.h>
#include <SD.h>

const int chipSelect = 4;
const int fileclose = 6;
File myFile;

bool radioNumber = 1;
RF24 radio(7, 8);

byte buf[32] = {0};
byte addresses[][6] = {"1Node", "2Node"};
bool role = 0;



void setup()
{ pinMode(53, OUTPUT);
  digitalWrite(53, LOW);
  pinMode(2, OUTPUT);
  pinMode(fileclose, INPUT_PULLUP);

  Serial.begin (115200) ;

  if (!SD.begin(4))
  {
    Serial.println("initialization of SD failed!");
    return;
  }
  Serial.println("initialization done.");
  // digitalWrite(53, HIGH);

  Serial.println(F("R E C E T O R"));
  radio.begin();
  radio.setPALevel(RF24_PA_LOW);
  radio.setPayloadSize(32);
  radio.setDataRate(RF24_2MBPS);
  radio.setChannel(0x7d);
  radio.setAutoAck(1);                     // Ensure autoACK is enabled
  radio.setRetries(3, 15);
  digitalWrite(13, LOW);
  radio.printDetails();
  radio.startListening();
  if (radioNumber)
  {
    radio.openWritingPipe(addresses[1]);
    radio.openReadingPipe(1, addresses[0]);
  }
  else
  {
    radio.openWritingPipe(addresses[0]);
    radio.openReadingPipe(1, addresses[1]);
  }
  recebedados();
}

void recebedados ()
{
  myFile = SD.open("11.txt", FILE_WRITE);


}

void loop()

{

  int i = 0;

  if (radio.available()) {
    //
    radio.read(buf, sizeof(buf));

    Serial.println(F(buf));

    myFile.write(buf, sizeof(buf));

    // recebedados();
    //
  }
  if (digitalRead(fileclose) == LOW)
  { delay(500);
    digitalWrite(2, HIGH);
    Serial.println(F("File closed"));
    myFile.close();
  }
}

I can't see any obvious issue, I guess you did the correct selection of radio parameters from an example sketch.

Only thing I would change is Serial.println(F(buf));

Since buf is a variable, not a constant string, plus you have plenty of memory available with the DUE so "F" is useless.

You are using radio.writeFast() command, is there any radio.write() command that you could try to write more slowly and reduce the chance of an issue ?

I have no experience of DUEs. Maybe writing to the SDCard is slow on occasions. If so, perhaps the sender should only send when a request for more data comes from the receiver. If it was my project I think I would put what you call the receiver in charge of the communication.

...R
Simple nRF24L01+ Tutorial

@ard_newbie, Thanks :slight_smile: Well, For the moment, chosen radio.write() instead of radio.Fastwrite(), and now is much better. Ack is now working :slight_smile:

I've changed also the code for checking the last stream of data (when smaller than 32 Bytes) and from sender side is correct now. However I still don't know how to get this result in the receiver side. Maybe using dinamic payload? Also Thank you Robin2 for your idea, but for now I will keep trying to solve this :slight_smile:

Final version here:
Transmitter

#include <SPI.h>
#include <SD.h>
#include "RF24.h"
bool radioNumber = 0;
RF24 radio(7, 8);
byte buf[32] = {0};
File myFile;
byte addresses[][6] = {"1Node", "2Node"};
bool role = 0;
void setup() {
  pinMode(53, OUTPUT);
  digitalWrite(53, LOW);
  Serial.begin (115200) ;
  if (!SD.begin(4))
  {
    Serial.println("initialization of SD failed!");
    return;
  }
  Serial.println("initialization done.");
  digitalWrite(53, HIGH);

  Serial.println(F("E M I S S O R"));
  radio.begin();
  radio.setPALevel(RF24_PA_MAX);
  radio.setPayloadSize(32);
  radio.setDataRate(RF24_250KBPS);
  //  radio.setDataRate(RF24_2MBPS);
  radio.setChannel(0x60);
  radio.printDetails();
  radio.setAutoAck(1);                     // Ensure autoACK is enabled
  radio.setRetries(2, 15);
  if (radioNumber) {
    radio.openWritingPipe(addresses[1]);
    radio.openReadingPipe(1, addresses[0]);
  }
  else
  { radio.openWritingPipe(addresses[0]);
    radio.openReadingPipe(1, addresses[1]);
  }
  sendfile();
}
void readfile() {
  int i = 0;
  while (myFile.available())
  {
    buf[i] = myFile.read();

    i++;
    if (i == 32)
    {
      Serial.println(F(buf));
      radio.write(buf, sizeof(buf));
      delay(10);
      i = 0;
    }
  }
  if (i > 0) {
    radio.flush_tx();
    radio.write(buf, i);
    Serial.write(buf, i); //Output results at serial port
    delay(1);
    i = 0;
    // Serial.println(F(buf));
    Serial.println("");
    Serial.println("Last stream of less than 32 bytes");
    digitalWrite(53, LOW);
  }
}
void sendfile() {
  myFile = SD.open("1.txt");
  if (myFile)
  {
    readfile ();// Função que vai fazer o envio
    myFile.close();
    radio.powerDown(); //desliga o rádio
  }
  else
  {
    Serial.println("error opening file"); // se não abre file, erro
  }
}
void loop() {
  // nada a fazer aqui
}

receiver

#include "RF24.h"


#include <SPI.h>
#include <SD.h>

const int chipSelect = 4;
const int fileclose = 6;
File myFile;
unsigned long tempo;
unsigned long tempo2;
int flag = 0;
bool radioNumber = 1;
RF24 radio(7, 8);

byte buf[32] = {0};
byte addresses[][6] = {"1Node", "2Node"};
bool role = 0;



void setup()
{ pinMode(53, OUTPUT);
  digitalWrite(53, LOW);
  pinMode(2, OUTPUT);
  pinMode(fileclose, INPUT_PULLUP);

  Serial.begin (115200) ;

  if (!SD.begin(4))
  {
    Serial.println("initialization of SD failed!");
    return;
  }
  Serial.println("initialization done.");
  // digitalWrite(53, HIGH);

  Serial.println(F("R E C E T O R"));
  radio.begin();
  radio.setPALevel(RF24_PA_MAX);
  radio.setPayloadSize(32);
  //  radio.setDataRate(RF24_2MBPS);
  radio.setChannel(0x60);
  radio.setDataRate(RF24_250KBPS);
  radio.setAutoAck(1);                     // Ensure autoACK is enabled
  radio.setRetries(1, 15);
  digitalWrite(13, LOW);
  radio.printDetails();
  radio.startListening();
  if (radioNumber)
  {
    radio.openWritingPipe(addresses[1]);
    radio.openReadingPipe(1, addresses[0]);
  }
  else
  {
    radio.openWritingPipe(addresses[0]);
    radio.openReadingPipe(1, addresses[1]);
  }
}

void openfile()
{
  myFile = SD.open("11.txt", FILE_WRITE);
  flag = 1;
}

void loop()

{ 
  if (radio.available()) {
  if (flag == 0) {
    openfile();
    }
    
    radio.read(buf, sizeof(buf));
    radio.flush_rx();
    Serial.println(F(buf));
    myFile.write(buf, sizeof(buf));
    tempo = millis();

  }
  tempo2 = millis();
  if(tempo2-tempo > 5000 && flag == 1){
    digitalWrite(2, HIGH);
    Serial.println(F("File closed"));
    myFile.close();
    flag = 0;
  }
}