Serial sending once, printing only once

Hi,

I'm currently trying to write a message on the Serial monitor of a Uno, receive the message on a Nano (through wireless transmission) and print it back on the Nano's Serial monitor.

However, though I only send the message once (which I can confirm), the Nano's Serial monitor print it dozens of times, and I can't find a topic with a solution that fits my project. I'm sure it's a simple trick but I can't figure it out.
Can you help me ?
Here are the codes :
Transceiver :

#include <SPI.h>
#include <RF24.h>

#define pinCE   7             // On associe la broche "CE" du NRF24L01 à la sortie digitale D7 de l'arduino
#define pinCSN  8             // On associe la broche "CSN" du NRF24L01 à la sortie digitale D8 de l'arduino
#define tunnel  "PIPE1"       // On définit un "nom de tunnel" (5 caractères), pour pouvoir communiquer d'un NRF24 à l'autre

RF24 radio(pinCE, pinCSN);    // Instanciation du NRF24L01

const byte adresse[6] = tunnel;               // Mise au format "byte array" du nom du tunnel
                    // Message à transmettre à l'autre NRF24 (32 caractères maxi, avec cette librairie)

const byte numChars = 32;
char receivedChars[numChars];   // an array to store the received data

boolean newData = false;

void setup() {
    Serial.begin(9600);
    radio.begin();                      // Initialisation du module NRF24
    radio.openWritingPipe(adresse);     // Ouverture du tunnel en ÉCRITURE, avec le "nom" qu'on lui a donné
    radio.setPALevel(RF24_PA_MIN);      // Sélection d'un niveau "MINIMAL" pour communiquer (pas besoin d'une forte puissance, pour nos essais) 
    radio.stopListening();// Arrêt de l'écoute du NRF24 (signifiant qu'on va émettre, et non recevoir, ici
    
}
char message[32] = "Mon message à envoyer !"; 


void loop() {
if (Serial.available()){
  recvWithEndMarker();
  radio.write(&receivedChars, sizeof(receivedChars));
  showNewData();
  } 
}

void recvWithEndMarker() {
    static byte ndx = 0;
    char endMarker = '>';
    char rc;
    
    while (Serial.available() > 0 && newData == false) {
        rc = Serial.read();

        if (rc != endMarker) {
            receivedChars[ndx] = rc;
            ndx++;
            if (ndx >= numChars) {
                ndx = numChars - 1;
            }
        }
        else {
            receivedChars[ndx] = '\0'; // terminate the string
            ndx = 0;
            newData = true;
        }
    }
}
void showNewData() {
    if (newData == true) {
        Serial.print(receivedChars);
        newData = false;
    }
}

Receiver :

#include <SPI.h>
#include <RF24.h>

#define pinCE   7             // On associe la broche "CE" du NRF24L01 à la sortie digitale D7 de l'arduino
#define pinCSN  8             // On associe la broche "CSN" du NRF24L01 à la sortie digitale D8 de l'arduino
#define tunnel  "PIPE1"       // On définit le "nom de tunnel" (5 caractères) à travers lequel on va recevoir les données de l'émetteur

RF24 radio(pinCE, pinCSN);    // Instanciation du NRF24L01

const byte adresse[6] = tunnel;       // Mise au format "byte array" du nom du tunnel  
char message[32];
boolean newData = false;
const byte numChars = 32;
char receivedChars[numChars];
char add = '\0';

void setup() {
  // Initialisation du port série (pour afficher les infos reçues, sur le "Moniteur Série" de l'IDE Arduino)
  Serial.begin(9600);

  // Partie NRF24
  radio.begin();                      // Initialisation du module NRF24
  radio.openReadingPipe(0, adresse);  // Ouverture du tunnel en LECTURE, avec le "nom" qu'on lui a donné
  radio.setPALevel(RF24_PA_MIN);      // Sélection d'un niveau "MINIMAL" pour communiquer (pas besoin d'une forte puissance, pour nos essais)
  radio.startListening();             // Démarrage de l'écoute du NRF24 (signifiant qu'on va recevoir, et non émettre quoi que ce soit, ici)
  
}

void loop() {
  if (radio.available()) {        // On vérifie si un message est en attente de lecture
  radio.read(&message, sizeof(message));             // Si oui, on le charge dans la variable "message"
newData = true;
showNewData();
}
}

void showNewData() {
    if (newData == true) {
        Serial.write(message);
        newData = false;
    }

}

I tried to put showNewData() out of the if condition (receiver) but it does not change anything.

Thank you !

i doubt these comments will fix your problem, but the code has some unnecessary code

in RX

  • there's no need for "newData" since showNewData() is only called when a message is received
  • receivedChars is unused
  • does radio.read() return the # of bytes received and does a NULL need to be appended to message[] before being printed?
  • should showData() do println() instead of write()?

in TX

  • would readBytesUntil() replace recvWithEndMarker(), eliminating any possible bugs in that code?
  • again, is there a need for "newData"?
  • should radio.write() be given the length of the string in received chars, not the length of the buffer?