Mega 2560 Serial3 Comms cross talk of sorts?

I have two mega 2560's talking to each other via Serial3. I have TX3/RX3 crossed over between them.

Mega A does Serial3.write("A") to Mega B and then waits until Serial3.Available() has data before continuing.

Once Mega B gets the message, it replies on the next loop with Serial3.write("A") back to Mega A, and then transmits 75 bytes or so of data. Mega A waits and reads to see if the first byte is an "A" and then processes the rest of the data as it comes in.

The above works, I can parse my data and all is well. The issue comes when Mega B is turned off... Mega A will still continuously send "A" until it gets a response, I want it to do this so that's fine as Mega B can turn on/off whenever. But what it's actually doing is Mega A Sends "A" and then instantaneously receives "A" and prints it out, From a device that's turned off... If I disconnect the TX3 pin from Mega B, it stops doing this. If I disconnect the RX3 pin from Mega B, it stops doing this.

If I connect them both back, it starts doing it again, if I connect the TX3 pin to literally any other pin on Mega B, it still does it... If I connect RX3 to literally any other pin on Mega B, it still does this lol... So it's not some sort of internal connection between TX3/RX3

There is nothing else connected to the megas, just the RX3/TX3 pins crossed over between both megas. Why is this happening? Is this some sort of cross talk? Has anyone else experienced this? I saw this other guys post but it didn't look like there was any resolution, I get that having a start and end character, or even just having Mega B reply with a different initial character would resolve this, but I was more just curious as to why it was happening..

Did you also connect the GNDs of both boards ?

The UART signals are idle high. As soon as the Arduino RX pins sees the level going down, that is the start bit, and the Arduino starts to read the 8 following bits. So if you power off one Arduino board, then the other one thinks it is sending data.

I suppose that you don't have ten meter cable between the Arduino boards. Are they both next to each other on your table ? Then there is no crosstalk.

We would like to see the sketch of both boards. Please put a sketch between code-tags. The </> button is for code-tags.

Did you know that you can have two instances of the Arduino IDE, each connected to their own Arduino board and each with their own serial monitor. The new Arduino IDE 2.0 beta can do that with just one instance of the Arduino IDE.

Not a fix to the problem, but a work around of sorts, why send "A" and reply "A", if you send "B" and reply "A" woud not the spurious reply just be ignored?

countrypaul:
Not a fix to the problem, but a work around of sorts, why send "A" and reply "A", if you send "B" and reply "A" woud not the spurious reply just be ignored?

I said something similar in the last bit of the post. This would definitely fix it but I was just really curious as to why it was happening to be honest haha! Seemed strange.

guy1195:
I said something similar in the last bit of the post. This would definitely fix it but I was just really curious as to why it was happening to be honest haha! Seemed strange.

Whoops sorry, I obviously missed that at the end of your original post - my mistake.

@Koepel (not sure how to reply to you)

I just tried connecting the grounds, and it goes VERY weird... Eventually I believe it crashes the Mega A. The "ON LED" on Mega B starts to light up Red, and the "L LED" starts to slowly light up then turns off, does this a few times before the Mega A crashes. This is with literally no other cables connected to the Mega B, just TX3/RX3 so presumably those are powering the leds.

Just using some DuPont jumper pins, 10cm or so.

This is the code from Mega A, Mega B code shouldn't really matter since it's literally turned off. But It basically does exactly the same though, waits for an "A" then replies.

// counters
int desync = 0;

void setup() {
  Serial.begin(115200);   // USB PC Serial Monitor
  Serial.println("START TIME");
  Serial3.begin(115200);  // RX3/TX3 to Mega B
  delay(250);
}

void loop() {
  Serial3.write("A"); // request data from Mega B
  while (Serial3.available() == 0) {} // wait for data to start coming in from Mega B
  int FirstByte = Serial3.read(); // read the first byte received
  Serial.println(FirstByte);
  if (FirstByte == 65) // if first byte received is an "A", process the data.
  {
    Serial.println("First byte is 65"); // Processing the rest of the data here! 
  }
  else
  {
    desync++; // If the first byte received wasn't an "A", i increment the desync counter
    Serial.print("Desync: "); 
    Serial.println(desync);
  }
  while (Serial3.available())
  {
    Serial3.read(); // Spam read to clear out any other trash in the buffer.
  }
  delay(50); // Just a pause before we do it again, this doesn't need to loop too fast. 
}

You have to connect the GNDs of the two boards. The RX3 and TX3 have no meaning without GND.
If something is wrong, then you have to fix that first.
Are the boards connected to the same computer ?
Do you use a very cheap power supply that leaks the mains voltage or is very noisy ?

We don't wait for serial input, we don't stay in while-loops. With that code, you might have a synchronization or a timing problem without knowing it. You should start with something very simple.

I think you need to add extra hardware to be able to turn one board off, but I have no good idea at the moment :frowning:

Mega A gets it's power/ground from a USB to my PC
Mega B gets it's power/ground from a USB to my laptop

Mega A and B are connected via TX3/RX3 only, no other jumper pins

When they're both turned on, the communication works fine, even without the GND's connected. When B is turned off, Mega A basically just talks to itself somehow. Whatever I send on A, I am able to read on A instantly. It's like I've just made a loop back on the TX3/RX3 pins on Mega A.

I suppose I could change the:

Serial3.write("A"); // request data from Mega B
while (Serial3.available() == 0) {}
// code here

To:

Serial3.write("A"); // request data from Mega B
if (Serial3.available() >= 0) {
 // code here
}

But then if Mega B doesn't reply quick enough Mega A would skip a loop, and in that time the buffer might fill up and I miss the data that goes past 64 bytes of buffer? That would stop Mega A ever getting stuck in the while loop though if B doesn't reply. It's just that the rest of the loop is quite lengthy, and I think the buffer would get filled quicker than it loops round and then starts to read again

I Can't change the code on Mega B, but this would work. I was just curious as to why the loopback was happening.

  if (FirstByte == 65) // if first byte received is an "A", Check the second
  {
    int SecondByte = Serial3.read();
    if (SecondByte != -1)
    {
      Serial.println("Second byte isnt empty"); // Processing the rest of the data here!
    }
  }

Tested this using software serial on pins 10/11 and it works fine... When Mega B turns off Mega A doesn't just talk to itself constantly. No idea what's going on there.

Just need to change the following so it doesn't get stuck whilst Mega B is turned on/off.

while (SoftSerial.available() == 0) {} // wait for data to start coming in from Mega B
#include <SoftwareSerial.h>

// counters
int desync = 0;

SoftwareSerial SoftSerial(10,11);

void setup() {
  Serial.begin(115200);   // USB PC Serial Monitor
  Serial.println("START TIME");
  SoftSerial.begin(115200);  // RX3/TX3 to Mega B
  delay(250);
}

void loop() {
  SoftSerial.write("A"); // request data from Mega B
  while (SoftSerial.available() == 0) {} // wait for data to start coming in from Mega B
  int FirstByte = SoftSerial.read(); // read the first byte received
  Serial.println(FirstByte);
  if (FirstByte == 65) // if first byte received is an "A", Check the second
  {
    int SecondByte = SoftSerial.read();
    if (SecondByte != -1)
    {
      Serial.println("Second byte isnt empty"); // Processing the rest of the data here!
    }
  }
  else
  {
    desync++; // If the first byte received wasn't an "A", i increment the desync counter
    Serial.print("Desync: ");
    Serial.println(desync);
  }
  while (SoftSerial.available())
  {
    SoftSerial.read(); // Spam read to clear out any other trash in the buffer.
  }
  delay(50); // Just a pause before we do it again, this doesn't need to loop too fast.
}

Tested again with software serial and the GND pins jumped between the two megas, it literally keeps the second mega powered on when USB cable is removed just via the RX/TX and GND pins and eventually crashes. I'll leave the GND disconnected as it works fine without it

You may never ever use RX and TX without GND :stuck_out_tongue_closed_eyes: Never. Not in this project, not in any project, not with the RX/TX serial bus, not with the I2C bus, not with the SPI bus, never.
I know that it will keep the other Arduino powered, that is via the RX and TX lines. That is a problem to solve.

You could connect the RX and TX via optocouplers.
When a low level turns the led (inside the optocoupler) on, then the led is off when the Arduino board is no longer powered because there will be no 5V to turn the led on.
The same for the other signal. You need resistors for the leds and pullup resistor for the output of the optocoupler. For example 470Ω for the led (it depends on the optocoupler) and 2k2 or 4k7 or so for the output.

Why doesn't Software serial have the loopback effect to itself but the hardware serial does.

guy1195:
Why doesn't Software serial have the loopback effect to itself but the hardware serial does.

I don't know :confused:

Hmmm very strange haha! Thanks a lot anyway, I'll keep looking into it and try figure out a better solution! Don't really want to use the software serial as it seems a fair bit slower.

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