Serial blocked until disconnected

I have 2 Arduinos (Uno and Mega) connected via serial, and one is sending a string to the other. I am receiving data (because I have a loop testing if Serial.available() > 0), but nothing is displayed UNTIL I physically disconnect the TX wire (red arrow), then it bursts out the previous 10 or so lines, before noticing it is disconnected again (note the "nothing received" is from before connecting it).

It seems to me the receiving arduino stops completely until disconnected. I tried Serial.flush() on both boards, delays of various lenghts, but nothing seems to work.
Here is the receptor code :

String ligne;
void setup() {
  Serial.begin(9600); // open the serial port at 9600 bps:
}

void loop() {
  int delai=500;
  
  


if (Serial.available() > 0) {
                // read the incoming data:
                ligne = Serial.readString();

                // say what you got:
                Serial.println("Data received : "+ligne);
        }
        else{
          Serial.println("nothing received");
        }
        //delay(delai);
        Serial.flush();

}

Post a wiring diagram and the corresponding sender code. Which code is running on which Arduino?

Here is the (crude) wirind diagram :

The Mega is the sender, the Uno the receiver.

The sender code (appears to be working) :

/* CODE PROTOTYPE - CARTE DATALOGGER*/

/*
   Carte Arduino : Arduino Nano. Pensez à changer le type de carte dand Outils->Type de carte
   Microcontrôlleur : Atmega328p. Vérifiez dans Outils->Processeur que l'Atmega328 est bien sélectionné.
   Outils->Programmateur:AVRISP mkll
   N'oubliez de sélectionner un port dans Outils->Port
*/

/*
   Fonctions de cette carte :
    - calculer le PWM moteur et l'envoyer
    - réceptioner les informations de capteurs (ie les valeurs sur 10 bits)
    - écrire les données dans une carte micro SD
*/

/*
   Liste des pins :
    - A0 : tension batterie
    - A1 : tension moteur
    - A2 : température batterie
    - A3 : température mosfet
    - A4 ou A5 : potentiomètre (ie liaison I2C utilisée pour le potentiomètre)
    - A6 : courant moteur
    - A7 : température moteur
    - D2 : vitesse
    - D3 : homme mort
    - D9 : pin PWM
    - D10 : CS (liaison SPI avec datalogger)
    - D11 : MOSI (liaison SPI avec datalogger)
    - D12 : MISO (liaison SPI avec datalogger)
    - D13 : SCK (liaison SPI avec datalogger)
*/

#include <SoftwareSerial.h>

SoftwareSerial mySerial(5, 6); // RX, TX


uint8_t currentdutycycle = 0;
uint32_t actualtime;

// Déclaration des variables de stockage de la valeur des capteurs (valeur sur 10 bits)
uint16_t tensionbatterie;
uint16_t tensionmoteur;
uint16_t temperaturebatterie;
uint16_t temperaturemosfet;
uint16_t courantmoteur;
uint16_t temperaturemoteur;
uint16_t vitesse;

//FOR SD CARD :
#include <SPI.h>
#include <SD.h>
File fichierSD;
String nomFichier = "";

void setup() {
  Serial.begin (9600);
  mySerial.begin (9600);
  // SD CARD
  /*At first we must check if the SD card exists. We use function SD.exists(pinSS), where pinSS is 10 for arduino uno and 53 for arduino mega*/
  if (!SD.begin(10)) {
    Serial.println(F("Initialisation impossible !"));
    return;
  }
  Serial.println(F("Initialisation OK"));
  int  index = 1;
  while (SD.exists("data" + String(index) + ".csv")) {
    index++;
  }
  nomFichier = "data" + String(index) + ".csv";
  Serial.println(nomFichier);
  InitialisationEcriture (fichierSD);
}

void loop() {
  delay(500);
  uint8_t pota =  analogRead(A4) >> 2;
  uint8_t courant = analogRead(A6) >>2;
if (analogRead (A2) < 307)//correspond to 90°C, that is the temperature limit of the motor
  { 
    if ( courant < 110)//valeur du capteur de courant
    {
      if (currentdutycycle < 255 && pota > currentdutycycle)
      {
        currentdutycycle++;
      }
      if (currentdutycycle > 0 && pota <= currentdutycycle)
      {
        currentdutycycle--;
      }
    }
    else
    {
      if (currentdutycycle > 0)
      {
        currentdutycycle--;
      }
    }
  }
  else
  {
    currentdutycycle=0;
  }
  if (pota < 5) 
  {
    currentdutycycle =0;
  }
  analogWrite (9, currentdutycycle);
  //Serial.println(pota);
  //Serial.println(currentdutycycle);

  mySerial.print(String(actualtime)+";"+String(tensionbatterie)+";"+String(tensionmoteur)+";"+String(temperaturebatterie)+";"+String(temperaturemosfet)+";"+String(courantmoteur)+";"+String(temperaturemoteur)+";"+String(vitesse)+";"+String(currentdutycycle));
  mySerial.println();

  Serial.print(String(actualtime)+";"+String(tensionbatterie)+";"+String(tensionmoteur)+";"+String(temperaturebatterie)+";"+String(temperaturemosfet)+";"+String(courantmoteur)+";"+String(temperaturemoteur)+";"+String(vitesse)+";"+String(currentdutycycle));
  Serial.println();

  Serial.flush();
  mySerial.flush();
  
  EcritureCarteSD(fichierSD);
}

void InitialisationEcriture (File actualfichierSD)
{
  fichierSD = SD.open(nomFichier, FILE_WRITE);
  if (fichierSD) {
    fichierSD.print ("temps");
    fichierSD.print(";");
    fichierSD.print ("tension batterie");
    fichierSD.print(";");
    fichierSD.print ("tension moteur");
    fichierSD.print(";");
    fichierSD.print ("temperature batterie");
    fichierSD.print(";");
    fichierSD.print ("temperature mosfet");
    fichierSD.print(";");
    fichierSD.print("courant moteur");
    fichierSD.print(";");
    fichierSD.print ("temperature moteur");
    fichierSD.print(";");
    fichierSD.print("vitesse");
    fichierSD.print(";");
    fichierSD.print("rapport cyclique");
    fichierSD.print(";");
    fichierSD.print("\n");
    fichierSD.close();
  }
}

void EcritureCarteSD (File actualfichierSD)
{
  tensionbatterie = analogRead (A0);
  tensionmoteur = analogRead (A1);
  temperaturebatterie = analogRead (A2);
  temperaturemosfet = analogRead (A3);
  courantmoteur = analogRead (A6);
  temperaturemoteur = analogRead (A7);
  actualtime = millis();
  //mySerial.print(String(actualtime)+";"+String(tensionbatterie)+";"+String(tensionmoteur)+";"+String(temperaturebatterie)+";"+String(temperaturemosfet)+";"+String(courantmoteur)+";"+String(temperaturemoteur)+";"+String(vitesse)+";"+String(currentdutycycle));
  //mySerial.println();
  // SENDING DATA TO SD CARD
  actualfichierSD = SD.open(nomFichier, FILE_WRITE);
  if (actualfichierSD) {
    Serial.println(F("Ecriture en cours"));
    actualfichierSD.print(actualtime);
    actualfichierSD.print(";");
    actualfichierSD.print(tensionbatterie);
    actualfichierSD.print(";");
    actualfichierSD.print(tensionmoteur);
    actualfichierSD.print(";");
    actualfichierSD.print(temperaturebatterie);
    actualfichierSD.print(";");
    actualfichierSD.print(temperaturemosfet );
    actualfichierSD.print(";");
    actualfichierSD.print(courantmoteur);
    actualfichierSD.print(";");
    actualfichierSD.print (temperaturemoteur);
    actualfichierSD.print(";");
    actualfichierSD.print(vitesse);
    actualfichierSD.print(";");
    actualfichierSD.print(currentdutycycle);
    actualfichierSD.print(";");
    actualfichierSD.print("\n");
    actualfichierSD.close();
   }
}

VinciEcoDrive:
Here is the (crude) wirind diagram :

No picture.

See this Simple Image Guide

The Mega is the sender, the Uno the receiver.

There is no need to use SoftwareSerial on a Mega as it has 3 spare HardwareSerial ports that work much better. And it would be good idea to use SoftwareSerial on the Uno so that Serial is free for uploading programs and sending debug messages to the PC.

Have a look at the examples in Serial Input Basics - simple reliable ways to receive data. There is also a parse example to illustrate how to extract numbers from the received text.

The technique in the 3rd example will be the most reliable. It is what I use for Arduino to Arduino and Arduino to PC communication.

You can send data in a compatible format with code like this (or the equivalent in any other programming language)

Serial.print('<'); // start marker
Serial.print(value1);
Serial.print(','); // comma separator
Serial.print(value2);
Serial.println('>'); // end marker

...R

Sorry, here it is :


The examples work fine, I think it i the nature of the string i'm trying to send that is problematic (but I can't understand why).

VinciEcoDrive:
The examples work fine, I think it i the nature of the string i'm trying to send that is problematic (but I can't understand why).

Try my examples.

It is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. This can happen after the program has been running perfectly for some time. Just use cstrings - char arrays terminated with '\0' (NULL).

...R

Do NOT use Serial.flush(). It does not do what you think it does and is completely useless in the context of your project.

Thank you, I tried adding start and end markers and it works !
I just had to increase the length of the input string (numChars in your example).

Thanks for the update.

...R

Do NOT use Serial.flush(). It does not do what you think it does and is completely useless in the context of your project.

What do you think it does?
In the current IDE it waits until the send buffer is completely transmitted. So why is it useless?

pylon:
What do you think it does?

Most people think it flushes the input buffer, when, as you mentioned, it flushes the output buffer.

pylon:
So why is it useless?

I think you didn't finish reading my post:

Power_Broker:
useless in the context of your project.

Basically, for OP's project, flush() isn't needed. Other project might have a use for it...