Uno SoftwareSerial with Mega is not 100% accurate

My Arduino Uno has 2 Serials at 115200.

The first one is the classic Serial and is used to send commands from Arduino IDE
The second one is SoftwareSerial RX=2 and TX=3 and is used to get data from the mega.

The mega only has this SoftwareSerial RX=69 and TX=8.
Everithing works 98% of the time, but I get random ⸮ (reversed question mark) or false data when I send MEGA_UNO_Serial.println("9999");.

I Read all Serials as follow

char data_MEGA_UNO[message_len_MEGA_UNO];  : 
If Serial.available()
byte m = MEGA_UNO_Serial.readBytesUntil('\n', data_MEGA_UNO, message_len_MEGA_UNO);

and after I split by space with

char *pch;
    pch = strtok(data_MEGA_UNO, " ,");

    while (pch != NULL)
    {
        Serial.println("Uno said: " + String(pch));
        pch = strtok(NULL, " ,");
        continue;
    }

How can I get rid of the random data and reversed question mark which appears about 2/100 times on the IDE Serial Uno

Replace the Arduino Uno with a Arduino Leonardo and use a hardware serial port on both boards.

I think you will find that SoftwareSerial is very unreliable / not working at all at 115200 baud. Anything above 19200 baud and I think you may begin to encounter issues.

Your topic was MOVED to its current forum category as it is more suitable than the original as it has nothing to do with the installation or troubleshooting of the IDE

SoftwareSerial is vey unreliable at 115200 baud. Try reducing the baud rate

@raf1
You may go with the following arrangement (Fig-1) at Bd = 9600.
uartUnoMega
Figure-1:

sorry english is not my first language and i'm a bit dumb

The MAGA has several hardware serial port, why not use the available hardware serial ports on the Mega?

Then you have come to the right forum. We are all a bit dumb sometimes.

How are you going to solve it ?
The SoftwareSerial on the Uno and a hardware Serial port on the Mega might work. But the SoftwareSerial can have a conflict with other libraries. Avoiding SoftwareSerial is the best option.

I have 20 potentiometers that needs instant update (a 115200 speed is quite good)
So my goal is that when I say ' get potentiometer 1' to the Uno, the Mega can give me the value.

From what I've seen the softwareSerial doesn't look like the best option, I think I need to look at SPI, Wire.h and I2C, because I need at least 115200 baud, and have a lot of button, potentiometers

Thank you, the data is much more accurate, but it's not fast enough compared to the number of components to watch

What is your message protocol? Maybe it has a lot of excess data overhead that you can cut out. Also what is the physical distance between the two boards?

I think, someone who considers themselves "dumb" might struggle with I2C or SPI processor intercommunication. Also those channels don't like to run long distances.

How many bytes does your request for data send to the Uno and how many bytes does the Uno send back ?

How frequently is a request sent ?

EDIT : I may have this back to front but the questions are still relevant. How many bytes of data are you sending and receiving ?

There is an overpowering smell of an X-Y problem here...

The Mega's role in this project is to provide more analog ports for the Uno, to read potentiometers? There are far better, faster, easier, cheaper ways to do that.

Here is the Uno code, and the mega is almost the same, without the USB_serial parts
The distance is less than 10cm but with cheap Amazon 'Dupont Breadboard' cables,
And when the speed is less than 115200 baud, the perfect precision is lost

#include <SoftwareSerial.h>

/*################### 6 USB_serial Analyser les entrées ##################*/
const int message_len_usb = 201;

char data_usb[message_len_usb];
/*################### 6 USB_serial Analyser les entrées ##################*/


/*################### 6 MEGA_UNO__serial Analyser les entrées ##################*/
#define rxPin 2
#define txPin 3
SoftwareSerial MEGA_UNO_Serial = SoftwareSerial(rxPin, txPin);

const int message_len_MEGA_UNO = 100;

char data_MEGA_UNO[message_len_MEGA_UNO]; 
/*################### 6 MEGA_UNO__serial Analyser les entrées ##################*/

unsigned long pTime = 0;

void setup() {
    pinMode(rxPin, INPUT);
    pinMode(txPin, OUTPUT);

    MEGA_UNO_Serial.begin(19200);

    Serial.begin(115200);
    Serial.println("Uno");

    delay(2000);
 }

void loop() 
{
    read_USB_serial();
    read_MEGA_UNO_serial();
}

void read_USB_serial()
{
    byte n = Serial.available();
    if (n != 0)
    {
        for (int i = 0; i < message_len_usb; i++)
        {
            data_usb[i] = '\0';
        }
        byte m = Serial.readBytesUntil('\n', data_usb, message_len_usb);
        process_USB_serial();
        data_usb[m] = '\0';
    }
}

void process_USB_serial()
{
    // Arduino IDE terminal => Mega Board 
    MEGA_UNO_Serial.println(String(data_usb));
    pTime = micros();
}

void read_MEGA_UNO_serial()
{
    byte n = MEGA_UNO_Serial.available();
    if (n != 0)
    {
        for (int i = 0; i < message_len_MEGA_UNO; i++)
        {
            data_MEGA_UNO[i] = '\0';
        }
        byte m = MEGA_UNO_Serial.readBytesUntil('\n', data_MEGA_UNO, message_len_MEGA_UNO);
        process_MEGA_UNO_serial();
        data_MEGA_UNO[m] = '\0';
    }
}

void process_MEGA_UNO_serial()
{
    unsigned long A = micros()-pTime;
    Serial.println("Megga a dit : " + String(data_MEGA_UNO) + String(A));
}

It is just a small part, but on the final project I use 'lisse set 1 99' for example, so the message length is < 20 chars

Right. Horribly inefficient protocol. Send raw data and see a speed improvement of at least 5x. Probably more.

The issue is that I need at least 4 informations :

  1. Type (lisse or crante or buttons or leds)
  2. Methode (set or limit ...)
  3. Value A (from -90 000 to 90 000 at least)
  4. Value B (from -90 000 to 90 000 at least)

For now I use a space between each element, than split by space

char *pch;
    pch = strtok(data_MEGA_UNO, " ,");

    while (pch != NULL)
    {
        Serial.println("Uno said: " + String(pch));
        pch = strtok(NULL, " ,");
        continue;
    }
  1. 2 bits
  2. 1 bit
  3. 18 bits
  4. 18 bits

total payload 39 bits == 5 bytes

Thx a lot for the help,
Can you give me an example of how to send that ? (maybe MEGA_UNO_Serial.println())
And read that ? (maybe MEGA_UNO_Serial.readBytesUntil())
I need it to be non-blocking

Actually the blocking/non-blocking aspect has nothing at all to do with the message format...

Also I suspect the range -90000 to 90000 does not apply to all your cases, right? So you can further compress messages that have a smaller data range.

Stick what you need into a struct, then send serially to receiver Arduino.

Simple code to send a struct between Arduinos using Serial - Community / Exhibition / Gallery - Arduino Forum

Don't make this any harder than necessary.