Using both Hardware Serial and Software Serial on Arduino Mega

Is it possible to use both hardware serial and software serial on Arduino Mega at the same time? if so how to do ?

It is quite possible to do that but why would why want/need to when the Mega has 4 hardware Serial ports ?

Yes , but you do realise the Mega already has several hardware serial ports . You should use these in preference.
Just add software serial library and look at the examples

Note to self - must type faster ...

Along with 4 hardware UART Ports of MEGA, it is possible to use many more software UART (SUART) Ports under the following conditions:

1. Only the following DPins of MEGA could be used as SRX (RX pin for the SUART Port) Pins:
SRX Pin: DPins: 10, 11, 12, 13; 50, 51, 52,, 53; 62(A8), 63, 64, 65, 66, 67, 68, 69(A15).

2. Only the following pins can be used as STX pins for SUART Ports.
STX Pin: Dpins: 2-13, 20-69 (not tested all the pins)

3. Here is an Example:
megauno.png

Sketch for MEGA:

#include<SoftwareSerial.h>
SoftwareSerial SUART(10, 11);  //SRX = 10, STX = 11

void setup() 
{
  Serial.begin(9600);
  SUART.begin(9600);

}

void loop() 
{
  byte n = Serial.available();
  if(n !=0)
  {
    char x = Serial.read();
    Serial.print(x);
    Serial.println();
    SUART.print(x);
  }
  
  n = SUART.available();
  if(n !=0)
  {
    char y = SUART.read();
    Serial.print(y);
  }
}

Sketch for UNO:

#include<SoftwareSerial.h>
SoftwareSerial SUART(2, 3); 

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

void loop()
{
  byte n = Serial.available();//checking if charcater has come from InputBox of Serial Monitor 
  if(n !=0)
  {
    char x = Serial.read();  //yes, there is a charcater; read it
    Serial.print(x);        //send back the charctaer to OutputBox of Serial Monitor
    SUART.print(x);         //send the charcater to NANO as ASCII code
  }

  n = SUART.available();//checking if charcater has come from InputBox of Serial Monitor 
  if(n !=0)
  {
    char x = SUART.read();  //yes, there is a charcater; read it
    Serial.print(x);        //send back the charctaer to OutputBox of Serial Monitor
    SUART.print(x);         //send the charcater to NANO as ASCII code
  }
}

megauno.png

it is possible to use many more software UART (SUART) Ports

In practice it is very difficult to use more than one soft UART in the same program but the question remains why would you need to use even one with a Mega ?

UKHeliBob:
In practice it is very difficult to use more than one soft UART in the same program but the question remains why would you need to use even one with a Mega ?

If the OP wants to operate the following 6 devices using UART Ports using MEGA, then he needs additional SUART Ports.

  1. Serial Monitor with UART0
  2. BME28 with UART1
  3. UNO with UART2
  4. NANO with UART3
  5. HC-05 (BT1) with SUART0
  6. HC-12 with SUART1

Which soft UART solution would you suggest for 5 and 6 ?

What about using I2C? I used to use HW Serial between arduinos until I took the leap and started playing with I2C using the Wire library. Real simply to use, frees up serial ports, works well using interrupts.

Doesn't your BME28 use I2C or SPI? Mine does

UKHeliBob:
Which soft UART solution would you suggest for 5 and 6 ?

SoftwareSerial SUART5(10, 11);
SoftwareSerial SUART6(12, 13);
SUART5.listen();
SUART6.listen();

Good luck with that.

Have you tried it in practice ?
Can you listen() on SUART5 and SUART6 at the same time ?

UKHeliBob:
Good luck with that.

Have you tried it in practice ?
Can you listen() on SUART5 and SUART6 at the same time ?

I have not tried, and now I am going to try.

I understand that it is one after another; no two SUART instances could be made active at the same time.

GolamMostafa:
I have not tried, and now I am going to try.

I understand that it is one after another; no two SUART instances could be made active at the same time.

This is the hardware setup; where, 2 SUART Ports are present; each SUART Port remains open for communication only for 20 sec. Tested -- I am happy; because, it works in the way I have made it to work.
softmulti.png

These are sketches:
MEGA:

#include<SoftwareSerial.h>
SoftwareSerial SUART1(10, 11);  //SRX = 10, STX = 11
SoftwareSerial SUART2(12, 13);

void setup()
{
  Serial.begin(9600);
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);
  SUART1.begin(9600);
  SUART2.begin(9600);
}

void loop()
{
  byte n = Serial.available();
  if (n != 0)
  {
    char x = Serial.read();
    //Serial.print(x);
    //Serial.println();
    SUART1.print(x);
    SUART2.print(x);
  }
  listenSUART1();
  listenSUART2();
}

void listenSUART1()
{
  Serial.println();
  Serial.println("Now switching over to UNO for 20 sec.");
  SUART1.listen();
  unsigned long prMillis = millis();
  while (millis() - prMillis < 20000ul)
  {
    byte n = SUART1.available();
    if (n != 0)
    {
      char y = SUART1.read();
      Serial.print(y);
    }
  }
}

void listenSUART2()
{
  Serial.println();
  Serial.println("Now switching over to BT for 20 sec.");
  SUART2.listen();
  unsigned long prMillis = millis();
  while (millis() - prMillis < 20000ul)
  {
    byte n = SUART2.available();
    if (n != 0)
    {
      char y = SUART2.read();
      if (y == '1')
      {
        digitalWrite(13, HIGH);
      }
      else if (y == '2')
      {
        digitalWrite(13, LOW);
      }
    }
  }
}

UNO:

#include<SoftwareSerial.h>
SoftwareSerial SUART(2, 3);

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

void loop()
{
  byte n = Serial.available();//checking if charcater has come from InputBox of Serial Monitor
  if (n != 0)
  {
    char x = Serial.read();  //yes, there is a charcater; read it
    Serial.print(x);        //send back the charctaer to OutputBox of Serial Monitor
    SUART.print(x);         //send the charcater to NANO as ASCII code
  }

  n = SUART.available();//checking if charcater has come from InputBox of Serial Monitor
  if (n != 0)
  {
    char x = SUART.read();  //yes, there is a charcater; read it
    Serial.print(x);        //send back the charctaer to OutputBox of Serial Monitor
    SUART.print(x);         //send the charcater to NANO as ASCII code
  }
}

softmulti.png

What happens if serial data is sent to SUART1 whilst it is not listening ?
Is it buffered and if so, where ?

SUART1 and SUART2 are always ready to accept data from MEGA. The following codes in the loop() function of MEGA (Post#12) work well; data written by MEGA goes very well to UNO and Android Phone.

void loop()
{
  byte n = Serial.available();
  if (n != 0)
  {
    char x = Serial.read();
    SUART1.print(x);
    SUART2.print(x);
  }
  listenSUART1();
  listenSUART2();
}

When MEGA and UNO wants to exchange data via SUART1, MEGA opens listening window for 20 sec (an arbitrary time) during which any data coming from Android Phone via SUART2 will be discarded/lost.

Similarly When MEGA and Android Phone wants to exchange data via SUART2, MEGA opens listening window for 20 sec (an arbitrary time) during which any data coming from UNO via SUART1 will be discarded/lost.

When MEGA and UNO wants to exchange data via SUART1, MEGA opens listening window for 20 sec (an arbitrary time) during which any data coming from Android Phone via SUART2 will be discarded/lost.

Similarly When MEGA and Android Phone wants to exchange data via SUART2, MEGA opens listening window for 20 sec (an arbitrary time) during which any data coming from UNO via SUART1 will be discarded/lost.

That's exactly the problem; you can not simultaneously listen to two software uarts using SoftwareSerial.

Your approach will work when the Mega can initiate the communication and tell the connected devices to send data. It will not work when the devices at random send data and the Mega has to receive them.

NeoSWSerial is an alternative that can handle multiple software uarts.

during which any data coming from Android Phone via SUART2 will be discarded/lost
...
during which any data coming from UNO via SUART1 will be discarded/lost.

That makes the use of 2 SoftwareSerial ports unsuitable for asynchronous serial data, which needs to be understood by anyone contemplating such a setup