Storing data from serial

Hello

I am facing a problem in storing data from serial into a variable

What I am trying to do is to receive two signals from two serials (Serial1 and Serial2) and then I would like to compare the two received signals and based on the comparison I will retransmit the signal again.
I tested this by sending one signal twice.

The receiving code:

int x, y;
void setup() {
  // put your setup code here, to run once:
  Serial.begin (115200);
  Serial1.begin(9600);// pin 19(Rx), 18(Tx)
  Serial2.begin(9600);// pin 17(Rx), 16(Tx)

}

void loop() {
    
  
  if (Serial1.available()) {
    x = Serial1.read();
    Serial.write(x); 
    //Serial1.write(x);
  }
  if (Serial.available()) {
    Serial1.write(Serial.read());
  }


   if (Serial2.available()) {
    y = Serial2.read();
    Serial.write(y);
    if (x==y)//This statment never holds true (although the signals are identical) but because x now does not hold the prevoius serial read
    Serial2.write(y); 
    }
    if (Serial.available()) {
      Serial2.write(Serial.read());
    }


  }

So to sum up, based on my observation I found that once the program is outside the if-statement for serial1, the variable x never holds the received value.

I am seeking your kind help, I have read several posts and documents about serial UART but none uses x outside the serial1 block of the code. Is there any other way to that?

Thanks,

What do you see if you print x and y before the comparison ?
How are you sending the values ?
Is there a line ending character (Carriage Return or Linefeed) on the data that you send ?

What do you see if you print x and y before the comparison?

x does not show anything in the block of serial2, however, y shows the received signal

For example, if we used this code:

   if (Serial2.available()) {
    y = Serial2.read();
    Serial.write(y);
    Serial2.write(x); //does not send anything
    Serial2.write(y); //successful transmission
    }
    if (Serial.available()) {
      Serial2.write(Serial.read());
    }

How are you sending the values?

Using another Arduino (wired communication), also, using serial UART

Is there a line-ending character (Carriage Return or Linefeed) on the data that you send?

No, but the received signals are read byte by byte

How are you sending the values?

Using another Arduino (wired communication), also, using serial UART

Please post the code used on the sender

Transmitter code:

#include <SoftwareSerial.h>

SoftwareSerial SerialA(8, 11); // RX, TX
SoftwareSerial SerialB(9, 12); // RX, TX


String x;
void setup() {
  // put your setup code here, to run once:
Serial.begin (115200);
SerialA.begin(9600);
SerialB.begin(9600);
}
void loop() {
    while(Serial.available()==0){
    x=Serial.readStringUntil('\n');
    SerialA.println(x);
    SerialB.println(x);

    }

}
    SerialA.println(x);
    SerialB.println(x);

You said that you are not sending a line ending character but the code says different

I thought you meant if I am utilizing a hand-shaking character. Sorry for the confusion, but I am utilizing the transmitter code as it is.

    SerialA.println(x);  //sends 2 bytes
    SerialB.println(x);  //sends 2 bytes

Do you see the problem ?

Test your project using 3 Arduinos -- MEGA, UNO, NANO in order to understand what is not right in your MEGA Codes. I have run your project using the above setup, and the values of x and y are well received. However, you are messing to read data from the InputBox of the Serial Monitor of your MEGA because you have used if() structure.

Setup:
MEGA UNO
TX1 --------> 2
RX1 <------ 3
GND <------> GND

TX2 --------> 2 (NANO)
RX2 <------- 3 (NANO)
GND <------> GND

MEGA-RX Codes:

byte x, y;
void setup()
{
  Serial.begin (9600);
  Serial1.begin(9600);// pin 19(Rx), 18(Tx)
  Serial2.begin(9600);// pin 17(Rx), 16(Tx)
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);
}

void loop()
{
  if (Serial1.available())
  {
    x = Serial1.read();
    Serial.println(x, HEX);  //x = 12
  }
  if (Serial.available())
  {
    Serial1.print(Serial.read());
  }

  if (Serial2.available())
  {
    y = Serial2.read();
    Serial.println(y, HEX);
    if (x == y) //This statment never holds true (although the signals are identical) but because x now does not hold the prevoius serial read
    {
      digitalWrite(13, HIGH);//Serial2.write(y);
    }
  }
  if (Serial.available())
  {
    Serial2.write(Serial.read());
  }
}

NANO Codes:

#include<SoftwareSerial.h>
SoftwareSerial mySerial1(2, 3); //SRX=2, STX=3

void setup()
{
  Serial.begin(9600);
  mySerial1.begin(9600);
}

void loop()
{
  if(mySerial1.available())
  {
    Serial.println(mySerial1.read());
  }
  byte x = 0x34;
  mySerial1.write(x);
  Serial.println(x, HEX);
  delay(1000);
}

UNO Codes:

#include<SoftwareSerial.h>
SoftwareSerial mySerial2(2, 3); //SRX=2, STX=3

void setup()
{
  Serial.begin(9600);
  mySerial2.begin(9600);
}

void loop()
{
  byte x = 0x34;
  mySerial2.write(x);
  Serial.println(x, HEX);
  delay(1000);
}

UKHeliBob:

    SerialA.println(x);  //sends 2 bytes

SerialB.println(x);  //sends 2 bytes



Do you see the problem ?

Yes. I removed it, now it is SerialA.print(x), but still, I am not receiving it correctly.
If I am sending one letter, I receive it correctly, but when sending a word, I receive the last letter repeated four times.

This is the Rx code:

#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11); // RX, TX (receives from serial2 port of Mega code)


void setup() {
  // put your setup code here, to run once:
Serial.begin (115200);
mySerial.begin(9600);
}

void loop() { // run over and over
  if (mySerial.available()) {
    Serial.write(mySerial.read());
  }
  if (Serial.available()) {
    mySerial.write(Serial.read());
  }

}

Please post the transmitter code as it is now and confirm that you have Serial2 of the Mega (the transmitter) connected to pins 10 and 11 of the receiver and that the two Arduinos have a common GND connection

UKHeliBob:
Please post the transmitter code as it is now and confirm that you have Serial2 of the Mega (the transmitter) connected to pins 10 and 11 of the receiver and that the two Arduinos have a common GND connection

This is the Tx code from the first Arduino (UNO#1):

#include <SoftwareSerial.h>

SoftwareSerial SerialA(8, 11); // RX, TX
SoftwareSerial SerialB(9, 12); // RX, TX


String x;
void setup() {
  // put your setup code here, to run once:
Serial.begin (115200);
SerialA.begin(9600);
SerialB.begin(9600);
}
void loop() {
    while(Serial.available()==0){
    x=Serial.readStringUntil('\n');
    SerialA.print(x);
    SerialB.print(x);

    }

}

The connections are as follows

(uno, 11) - - -(Mega, 19)
(uno, 12) - - -(Mega, 17)
and common gnd connection

Now at the Mega side, we have:

int x, y;
void setup() {
  // put your setup code here, to run once:
  Serial.begin (115200);
  Serial1.begin(9600);// pin 19(Rx), 18(Tx)
  Serial2.begin(9600);// pin 17(Rx), 16(Tx)

}

void loop() {
   
 
  if (Serial1.available()) {
    x = Serial1.read();
    Serial.write(x);
  }
  if (Serial.available()) {
    Serial1.write(Serial.read());
  }


   if (Serial2.available()) {
    y = Serial2.read();
    Serial.write(y);
    if (x==y)//This statment never holds true (although the signals are identical) but because x now does not hold the prevoius serial read
    Serial2.write(x);
    }
    if (Serial.available()) {
      Serial2.write(Serial.read());
    }


  }

A third Arduino is connected to the mega as well. The connection is:
(Mega, 16) - - -(Uno2, 10)
and a common GND
The third Arduino has the following code:

#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11); // RX, TX (receives from serial2 port of Mega code)


void setup() {
  // put your setup code here, to run once:
Serial.begin (115200);
mySerial.begin(9600);
}

void loop() { // run over and over
  if (mySerial.available()) {
    Serial.write(mySerial.read());
  }
  if (Serial.available()) {
    mySerial.write(Serial.read());
  }

}

Have a look at the examples in Serial Input Basics - simple reliable non-blocking 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

Robin2:
Have a look at the examples in Serial Input Basics - simple reliable non-blocking 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

Thank you for your input. Although the post you posted is handy, yet I don't think it serves my problem. I am not trying to use a handshake (start/end markers).

I figured this problem out by merely introducing some delay when I read from each serial, which allows the variables to store the read value a little longer until the comparison happens. Doing such made the communication slower, but in my system, it is not something I care about a lot.
P.S: This solution works even when using println.

Thanks again, everyone, and you can find below my adjusted code in case someone faces the same problem.

int x, y;
void setup() {
  Serial.begin (115200);
  Serial1.begin(9600);// pin 19(Rx), 18(Tx)
  Serial2.begin(9600);// pin 17(Rx), 16(Tx)
}

void loop() {
    if (Serial1.available()) {
delay(10);
    x = Serial1.read();
    Serial.write(x);}
   if (Serial.available()) {
    Serial1.write(Serial.read());}


   if (Serial2.available()) {
delay(10);
  y = Serial2.read();
    Serial.write(y);
    if (x==y)
    Serial2.write(x);}
    if (Serial.available()) {
      Serial2.write(Serial.read());
    } }

Thanks,

I figured this problem out by merely introducing some delay when I read from each serial,

That really should not be necessary. If available() reports that there is something to read then it is available right now. There is no need to wait for a while before reading it.

How is the incoming serial data terminated ? Carriage Return, Linefeed, both, neither ?

Alicefaisal:
Thank you for your input. Although the post you posted is handy, yet I don't think it serves my problem. I am not trying to use a handshake (start/end markers).

The start- and end-markers are not a handshake. Handshaking is a two-way conversation. The markers simply tell the receiver when the message begins and when it ends.

...R