How to pass a software serial to a function?

This is a simplified version of the present code:

#include <SoftwareSerial.h>

SoftwareSerial swSer1(12, 13, false, 256);
SoftwareSerial swSer2(14, 15, false, 256);

void processSwSer1() {
   // do something with swSer1
}

void processSwSer2() {
   // do something with swSer2
}

If I want to process swSer1 and swSer2 in only one function,
I have to pass the software serial to a function.

This is what I have so far:

void processSwSer(int Ser, Stream &swSer) {
   static byte ndx = 0;
   byte rb;
   receivedBytes[numBytes];

   while ( swSer.available() > 0 )
   {
      rb = swSer.read();
      receivedBytes[ndx] = rb;
      ndx++;
   }

   if ( Ser == 1 ) { 
      memcpy(receivedBytes1, receivedBytes, sizeof(receivedBytes));
   }
   else {
      memcpy(receivedBytes2, receivedBytes, sizeof(receivedBytes));
   }
}

Would it be more performant to use swSer1 and swSer2 inside the function?

The only time I've passed stream objects around like this is when writing library code. In terms of doing this in a sketch - I'd only do it if the sketch were particularly complex

The idea is to avoid redundant code.
In this case processSwSer1 and processSwSer2 does almost the same.

nuon:
The idea is to avoid redundant code.
In this case processSwSer1 and processSwSer2 does almost the same.

It's honestly up to you and what YOU want to do. If it works, it works, if you like it, do it

nuon:
I have to pass the software serial to a function.

....

Would it be more performant to use swSer1 and swSer2 inside the function?

.............

The idea is to avoid redundant code.
In this case processSwSer1 and processSwSer2 does almost the same.

You only pass the address of the software serial which is put on the stack and used from there.

If you would have many calls using the same SoftwareSerial port in a row you could save speed by using a global SoftwareSerial pointer that you set only when you change channels and code the function to use that.

using a global SoftwareSerial pointer that you set only when you change channels and code the function to use that.

Can you give an example how to do this?

Arduino has definitions for standard variables like int and char.
When you make an int, the name refers to where that int resides in RAM.

The SoftwareSerial library has definitions for a user-defined variable type, in this case a C++ class named SoftwareSerial.

SoftwareSerial swSer1(12, 13, false, 256);
SoftwareSerial swSer2(14, 15, false, 256);

This code makes 2 SoftwareSerial class objects (special variables) where the object is the part that resides in RAM the same way as the defined int resides in RAM.

The names swSer1 and swSer2 refer to where in RAM the objects are.

So if you make a function

void someFunc( SoftwareSerial *ss, char *str )
{
  ss->println( str );  // with pointers you use -> instead of .
}

you can pass whichever you want, swSer1 or swSer2

someFunc( swSer1, "pointers rule" );

This might work if you can't handle the ->. The call to someFunc() is the same.

void someFunc( SoftwareSerial *ss, char *str )
{
  (* ss).println( str );  // with pointers you use -> instead of .
}

And this =might= work if you can't handle the ->. The call to someFunc() is the same.

void someFunc( SoftwareSerial &ss, char *str )
{
  ss.println( str );  // with pointers you use -> instead of .
}

Sorry, a bit tired right now and it takes longer to look up or test than the forum post timeout.

nuon:
This is a simplified version of the present code:

#include <SoftwareSerial.h>

SoftwareSerial swSer1(12, 13, false, 256);
SoftwareSerial swSer2(14, 15, false, 256);

void processSwSer1() {
  // do something with swSer1
}

void processSwSer2() {
  // do something with swSer2
}




If I want to process swSer1 and swSer2 in only one function, 
I have to pass the software serial to a function.

This is what I have so far:



void processSwSer(int Ser, Stream &swSer) {
  static byte ndx = 0;
  byte rb;
  receivedBytes[numBytes];

while ( swSer.available() > 0 )
  {
     rb = swSer.read();
     receivedBytes[ndx] = rb;
     ndx++;
  }

if ( Ser == 1 ) {
     memcpy(receivedBytes1, receivedBytes, sizeof(receivedBytes));
  }
  else {
     memcpy(receivedBytes2, receivedBytes, sizeof(receivedBytes));
  }
}




Would it be more performant to use swSer1 and swSer2 inside the function?

I pass Serial, LCD, VFD or any other character device to my library:

look how it's done.

Thanks for the comprehensive examples.

Just in terms of performance, what would be the best / fastest method?

  1. void someFunc( Stream &ss ) // is Stream correct at all?

  2. void someFunc( SoftwareSerial &ss )

  3. void someFunc( SoftwareSerial *ss )

  4. Using global ss1 and ss2 in someFunc?

Another question is, would it be more efficient to use a temporary one dimensional local receivedBytes array and memcpy it to the global arrays or to use a global two dimensional array:

const byte numBytes = 32;
byte receivedBytes[2][numBytes];

nuon:
Another question is, would it be more efficient to use a temporary one dimensional local receivedBytes array and memcpy it to the global arrays or to use a global two dimensional array:

Given that you're using SoftwareSerial, efficiency is already out the window. Any futzing you do around the edges won't fix that. Just peeing in the ocean.

FYI, you might be interested in using this library for fast and reliable serial data transfer

Given that you're using SoftwareSerial, efficiency is already out the window. Any futzing you do around the edges won't fix that. Just peeing in the ocean

You mean every diminutive gain in efficiency by this code changes is exceeded many times by the inefficiency of SoftwareSerial?

Are there more efficient SoftwareSerial libraries or is this a general problem?

Nevertheless it still remains cleaner code. If the project grows this could also be useful.

nuon:
Are there more efficient SoftwareSerial libraries or is this a general problem?

Use a board with multiple (real) hardware Serial Ports. I really like the PJRC Teensy 3.x Family. Multiple serial port, fast 32-bit ARM processors, great support. If you want to stick with the 8-bit AVR family, try a Mega.