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?

Hello,

receivedChars is used since it stores the values to send through wireless communication. Please note that the Arduino receives a message from the Serial Port and this message is stored in receivedChars.

I'm checking out for readBytesUntil() and keeping you up to date.

For the Tx, both println() and write() give the same result, since I'm not printing the message directly on the port but rather reading the Serial Port with an alternative Python code. Whether it is printed or just send to the Serial Port doesn't change anything (or at least it seems so when running).

try this way (in the Transceiver)

void loop() {
  recvWithEndMarker();
  if (newData) {
    showNewData();
    radio.write(receivedChars, strlen(receivedChars)+1);
  }
}

You probably need to study Serial Input Basics again

Thank you, it's working well !
However, I don't understand how changing the Tx code affects what the Rx sends to the Serial Monitor. Could you please explain ?

Have you read the tutorial again?

Look at how you were acquiring the data, you are emptying the serial buffer and leaving the function without having received the end marker but you still send the whole buffer and the null char had not been added…

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.