Caracteres raros en lcd usando comunicacion serial

Hola de nuevo!, tengo otro problema con la comunicación serial y mi lcd, les doy un poco de contexto, tengo 3 arduinos conectados entre si, el arduino de entrada y salida, recibe datos por un teclado de matriz 4x4, y muestra por un lcd i2c 16x2, el envia dos numeros y un operador, (como una calculadora) al arduino de control, este arduino hace unas decisiones y le envia los numeros y el operador al arduino de calculo, que este finalmente opera con los numeros, yo se que todo esto se puede hacer en un solo arduino, pero pues asi me pidieron el proyecto, el caso es que uso Software serial para gestionar la comunicacion entre los arduinos y funciona, el problema es que cuando el lcd me muestra el resultado, me aparecen carecteres raros en vez del mensaje correcto, y cada vez que pruebo salen caracteres raros, a veces si sale el mensaje que tiene que salir, ahora les muestro el código de los tres arduinos, la cosa es que el mensaje que tiene que salir en el lcd es: en la primera linea: "la respuesta es". y en la segunda linea debe salir pues el resultado, pero en la primera linea salen caracteres raros y en la segunda me sale "\n" es que un delimitador que use para organizar la comunicacion entre los arduinos, ahora lo veran en el codigo, la cosa es que no deberia salir ahi y no se porque aparece, en serio espero que me puedan ayudar :c
Codigo arduino de entrada y salida (pueden ignorar toda la parte de recepción de datos al usuario, van hasta el final donde se envían los datos y se espera a recibir la respuesta).

#include <LiquidCrystal_I2C.h>
#include <Key.h>
#include <Keypad.h>
#include <Wire.h>
#include <SoftwareSerial.h>

SoftwareSerial serialC(11, 10); // RX, TX

// Dirección I2C de la pantalla LCD (comúnmente 0x27 o 0x3F, dependiendo del módulo)
LiquidCrystal_I2C lcd(0x27,16,2); // LCD de 6x2, con dirección I2C 0x27

// Configuración del teclado 4x4
const byte numRows = 4;
const byte numCols = 4;
char keymap[numRows][numCols] =
 {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};

byte rowPins[numRows] = {13, 12, 9, 8}; 
byte colPins[numCols] = {7, 6, 5, 4}; 

Keypad myKeypad = Keypad(makeKeymap(keymap), rowPins, colPins, numRows, numCols);
int delayScroll = 300;
String mensaje = "Proyecto Final Infraestructura  ";
int cantPantalla = 1;
int contOp=0;
String entrada = "";
char operador = "";
float num1 , num2, result;

void setup() 
{
  pinMode(1, OUTPUT);//envia
  pinMode(0, OUTPUT);//recibe
  pinMode(11, INPUT);
  pinMode(10, OUTPUT);
  Serial.begin(9600);
  serialC.begin(9600);
  lcd.init();
  lcd.backlight(); 
  lcd.setCursor(2,1);
  lcd.print("continuar = #");
}

void loop() {
  num1 = 0;
  num2 = 0;
  operador = 'z';
  char keypressed = myKeypad.getKey();

  
  if (cantPantalla == 1) {
    lcd.setCursor(2,1);
    lcd.print("continuar = #");
    lcd.setCursor(0, 0);
    lcd.print("                "); 
    for (int i = 0; i < mensaje.length(); i++) {
      // Verificamos continuamente si se ha presionado '#'
      keypressed = myKeypad.getKey();
      if (keypressed == '#') {
        menu1();
        return; 
      }

      // Mostramos el mensaje desplazado en la primera línea
      lcd.setCursor(0, 0);
      lcd.print(mensaje.substring(i));
      delay(delayScroll);

      // Añadimos el texto inicial si llega al final
      if (i + 16 > mensaje.length()) {
        lcd.print(mensaje.substring(0, (i + 16) - mensaje.length()));
      }
    }
  }
}

void menu1(){
  lcd.clear();
  cantPantalla = 0;
  contOp = 0;
  
  while(cantPantalla == 0){
  	delay(10);
  	lcd.setCursor(2, 0);
  	lcd.print("Select numero:");
  	delay(100);
  
  	char key = myKeypad.getKey();
  
  	if (key) {

      if (key >= '0' && key <= '9'){
        lcd.clear();
        entrada += key;
        lcd.setCursor(2,1);
        lcd.print(key);

      }else if(key == '#'){
        if(entrada.toFloat() >= 15){
          lcd.setCursor(2, 0);
          lcd.print("Numero menores");
          lcd.setCursor(2, 1);
          lcd.print("a 15 porfavor");
          delay(1000);
          lcd.clear();
        }

        if(contOp == 0){
          num1 = entrada.toFloat();
          entrada = "";
          lcd.clear();
          contOp++;

        }else if(contOp == 1){
          num2 = entrada.toFloat();
          entrada = "";
          contOp++;
          menu3();
          return;
        }
      }
    }
  } 
}

void menu3(){
  lcd.clear();
  contOp = 0;
  while(cantPantalla == 0){
    delay(10);
    lcd.setCursor(0, 0);
  	lcd.print("Select operacion");
  	delay(100);

    char key = myKeypad.getKey();
    if(key){
      if(key == 'A' || key == 'B'|| key == 'C'|| key == 'D' && contOp == 0){
        lcd.clear();
        entrada += key;
        operador = key;
        lcd.setCursor(2,1);
        lcd.print(key);
        contOp++;
      }else if(key == '#' && contOp == 1){
        lcd.setCursor(0,1);
        lcd.print("Envio...");
        lcd.clear();

        serialC.print(num1);
        serialC.print(",");
        serialC.print(num2);
        serialC.print(",");
        serialC.print(operador);
        serialC.print("/n");
        lcd.setCursor(0,1);
        lcd.print("Enviado!");
        encenderEnviado();
        delay(100);
        lcd.clear();


        limpiarBuffer(serialC);
        serialC.listen();
        while(!serialC.available()){
          lcd.clear();
          lcd.setCursor(3,0);
          lcd.print("Carburando.");
          delay(100);
          lcd.setCursor(3,0);
          lcd.print("Carburando..");
          delay(100);
          lcd.setCursor(3,0);
          lcd.print("Carburando...");
          delay(100);
        }
        if(serialC.available()){
          String mensaje = serialC.readStringUntil("/n");

          int index1 = mensaje.indexOf(',');          // Encuentra la primera coma

          String resultado = mensaje.substring(0, index1);
          String resultado2 = mensaje.substring(index1 + 1);
          
          encenderRecibir();

          lcd.clear();
          lcd.setCursor(0,0);
          lcd.print(resultado);
          lcd.setCursor(0,1);
          lcd.print(resultado2);
        

        
        }
        delay(3000);
        lcd.clear();
        cantPantalla = 1;
        
      }
    }
  }
}
void encenderEnviado(){
  digitalWrite(1, HIGH);
  delay(1000);
  digitalWrite(1, LOW);
}
void encenderRecibir(){
  digitalWrite(0, HIGH);
  delay(1000);
  digitalWrite(0, LOW);
}
void limpiarBuffer(SoftwareSerial &serial) {
    while (serial.available()) {
        serial.read(); // Descartar datos residuales
    }
}

Codigo arduino de control

#include <SoftwareSerial.h>
//serialA = comunicacion con la unidad de entrada y salida
//serialB = comunicacion con la ALU
//serialD = comunicacion con la memoria
SoftwareSerial serialA(11, 10);
SoftwareSerial serialB(9, 8);
SoftwareSerial serialD(13, 12);
//recibe,envia
String op = "";
void setup() {
  pinMode(3, OUTPUT); //led enviado
  pinMode(2, OUTPUT); //led recibido
  pinMode(11, INPUT);
  pinMode(10, OUTPUT);
  pinMode(9, INPUT);
  pinMode(8, OUTPUT);
  pinMode(13, INPUT);
  pinMode(12, OUTPUT);
  serialA.begin(9600);
  serialB.begin(9600);
  serialD.begin(9600);  
  Serial.begin(9600);   
}

void loop() {
  limpiarBuffer(serialA);
  serialA.listen();
  if (serialA.available()) {
    String mensaje = serialA.readStringUntil("/n");

    int index1 = mensaje.indexOf(',');          // Encuentra la primera coma
    int index2 = mensaje.indexOf(',', index1 + 1); // Encuentra la segunda coma

    float num1 = mensaje.substring(0, index1).toFloat();
    float num2 =  mensaje.substring(index1 + 1, index2).toFloat();
    String operador = mensaje.substring(index2 + 1);

    digitalWrite(2, HIGH);
    delay(500);
    digitalWrite(2, LOW);

    if(operador == "A"){
      op = "suma";  
    }else if(operador == "B"){
      op = "resta";
    }else if(operador == "C"){
      op = "and";
    }else if(operador == "D"){
      op = "or";
    }

    serialB.print(num1);
    serialB.print(",");
    serialB.print(num2);
    serialB.print(",");
    serialB.print(op);
    serialB.print("/n");
    encenderEnviado();
    //serialD.println(operador);

    //if(serialD.available()){
      //String op = serialD.readString();
      //serialB.println(op);

      //if(serialB.available()){
        //String resultado = serialB.readString();
        //serialA.println(resultado);

      //}
    //}
  }
  limpiarBuffer(serialB);
  serialB.listen();
  if(serialB.available()){
    serialB.read();
    String resultadoTexto = serialB.readString();
  	digitalWrite(2, HIGH);
  	delay(500);
  	digitalWrite(2, LOW);
    serialA.print(resultadoTexto);
    serialA.print("/n");

  	encenderEnviado();
  }
}
void encenderEnviado(){
  digitalWrite(3, HIGH);
  delay(500);
  digitalWrite(3, LOW);
}
void limpiarBuffer(SoftwareSerial &serial) {
    while (serial.available()) {
        serial.read(); // Descartar datos residuales
    }
}

Código Arduino de calculo

#include <SoftwareSerial.h>

SoftwareSerial serialC(9, 8);
String resultado = "El resultado es";
String resultado2 = "";
float temporal = 0;

void setup() {
  serialC.begin(9600);
  pinMode(2, OUTPUT); // LED recibido
  pinMode(3, OUTPUT); // LED enviado
}

void loop() {
  if (serialC.available()) {
    String mensaje = serialC.readStringUntil('\n'); // Lee hasta el salto de línea

    int index1 = mensaje.indexOf(',');          // Encuentra la primera coma
    int index2 = mensaje.indexOf(',', index1 + 1); // Encuentra la segunda coma

    float num1 = mensaje.substring(0, index1).toFloat();
    float num2 = mensaje.substring(index1 + 1, index2).toFloat();
    String operador = mensaje.substring(index2 + 1);

    limpiarBuffer(serialC);

    digitalWrite(2, HIGH);
    delay(500);
    digitalWrite(2, LOW);

    // Operador Suma
    if (operador == "suma") {
      temporal = num1 + num2;
      resultado2 = String(temporal);
    }
    // Operador Resta
    else if (operador == "resta") {
      temporal = num1 - num2;
      resultado2 = String(temporal);
    }
    // Operadores AND y OR
    else if (operador == "and" || operador == "or") {
      int binarioNum1 = static_cast<int>(num1);  // Convertir a entero explícitamente
      int binarioNum2 = static_cast<int>(num2);
      int resultadoBinario;

      if (operador == "and") {
        resultadoBinario = binarioNum1 & binarioNum2;
      } else if (operador == "or") {
        resultadoBinario = binarioNum1 | binarioNum2;
      }

      resultado2 = String(resultadoBinario); // Convertir a String
    }

    serialC.print(resultado);  // "El resultado es"
    serialC.print(",");
    serialC.print(resultado2); // Imprime el resultado final
    serialC.print('\n');       // Salto de línea

    digitalWrite(3, HIGH);
    delay(500);
    digitalWrite(3, LOW);
  }
}
void limpiarBuffer(SoftwareSerial &serial) {
    while (serial.available()) {
        serial.read(); // Descartar datos residuales
    }
}

Y por ultimo les dejo unas fotos de como salen los mensajes:




Y pues si ven las imágenes, yo pienso que en la segunda linea no sale nada por un problema del calculo de los numeros, pero igualmente no deberia aparecer esos "/n"
y de la segunda linea de todo el mensaje que debe aparecer siempre independientemente de lo que se haga, solo queda el "es".

Comprate un MEGA que tiene 4 puertos serie y no tendras ese problema.
3 puertos SoftwareSerial? mmm
Yo usaría otra manera de comunicarme, usa SPI o usa I2C entre los arduinos pero si quieres algo serial deberia ser usando interfaz 485.
Dime si entiendes que te estoy recomendando.

Dos SoftwareSerial funcionan bien, 3 no puedo asegurarlo.

La verdad no entiendo mucho de lo que me dices, solo se que pues vi el software serial como una comunicación ideal para el proyecto y de hecho me la recomendó mi profesora.


Tiene 4 puertos series físicos, no usa Software Serial,
Se llaman Serial, Serial1, Serial2, y Serial3

Algo similar a tu proyecto

Perfecto, voy a considerar la opción de conseguir un Mega, pero porque daría problemas tener más de 2 puertos software serial?

Revisa porque en los dos primeros códigos está mal escrito el caracter "NL" (nueva línea), escribiste /n en lugar de \n.

Obviamente, .readStringUntil('\n') no va a encontrar el caracter "NL" y va a salir por timeout.

Bueno probe unas cosas que me recomendaron aqui, pero descubri que es lo que pasa, y es que el Sofware serial no esta transmitiendo la informacion correctamente, arduino de entrada y salida, envia bien los datos, pero el arduino de control los recibe o incompletos o incomprensibles y ya desde ahi se daña el mensaje y por eso al final muestra caracteres raros, probe usando serial.flush pero no funciona, entonces no se que podria estar causando el error de transmisión.

¿Pero corregiste lo que te marqué sobre los fines de línea?

No le da el cuero, 2 SoftwareSerial usando listen puede ser, mas no. Usa un Arduino MEGA