Go Down

Topic: Duplicate Serial Output on Arduino Mega (Read 2126 times) previous topic - next topic


Hello everybody,

This is my first thread in this forum, so if I 'm doing anything wrong, please let me know.

My project board combines an Arduino Mega 2560, an XBee and an openLog. Both of the devices communicate with serial protocol. The openLog is hooked on Serial and the XBee on Serial1.
The openLog will serve as a "black box" and the XBee as a telemetry relay.

For the time being, both those modules must receive the same serial data. In the future, the telemetry will probably transmit a subset of those data.

My problem comes with the data duplication. I have at about 50 Serial.print() commands on each loop at 115200 baud.

A software approach would be to simply duplicate the Serial.print() commands and changing them into Serial1.print(), resulting into double the amount of commands. Ugly, but allows for future changes.

A hardware approach would be to select the XBee RX source with a SPDT switch; either Serial TX or Serial1 TX pins. More elegant and software-effective, but more invasive. (It would also mean I have to build another board)

Both ways are feasible, but I 'm looking for some advice to help me decide, or present me another option that I neglected.

Thanks in advance,


Don't you need to just use the same TX pin for both (No switch).?

Take a look at the XBee shield or the wireless/SD shield in the products section of this site.



I can't use the same pin, because, as I wrote, in the future those two devices won't share the same data. Different data will be sent to each one, according to the project needs.
It's only for now, during the debugging stage, that I need TX data duplication.

My question could be rephrased as wanting an efficient Serial TX data duplication method.


OK then all I can think of is two sets of Serial.prints. You could look a print of your own that duplicates the data but you only need to change it all later when the two sets of prints are not the same.



In the future you will need to print the output on those two streams separately since they will have different output, so it makes sense to use that approach from the outset.

I'm not clear how the two sets of output will be related, but if one is just a subset of the other and you know at the point of generating the message which stream(s) it will be written to, you could provide a function which accepts a printable string and an argument indicating which stream(s) to print it to. That way the code generating these various messages doesn't need to duplicate the messages.

For example, you could associate a 'level' with each output stream and then pass in a level associated with each message which determines which stream(s) that message gets written to. This approach is often used to control the output of log messages at varying levels of detail.


I guess this is a stupid answer but why not just write a "DoubleSerial" function in your code.  You call that each time you want to write to both and it writes the same data to both serial ports.


I guess this is a stupid answer but why not just write a "DoubleSerial" function in your code.  You call that each time you want to write to both and it writes the same data to both serial ports.

I think this is smart:


You may need to define a few versions of this function to print strings and numbers, unless you want to use template.
Serial LCD keypad panel,phi_prompt user interface library,SDI-12 USB Adapter


Thank all of you for your suggestions. When I end up with a specific solution I 'll post some details for reference.


I would do something like the following:

Code: [Select]
typdef enum OUTPUTS { SERIAL, SERIAL1, SERIAL2, SERIAL3 } outputs_e;

class Writer: public Stream
 void println(char*, outputs_e);

void Writer::println(char * data, outputs_e outputTo)
   if(outputTo & SERIAL) Serial.println(data);
   if(outputTo & SERIAL1) Serial1.println(data);
   if(outputTo & SERIAL2) Serial2.println(data);
   if(outputTo & SERIAL3) Serial3.println(data);

Now, in your code you simply do the following:

Code: [Select]
Writer writer;

writer.println("Some output", SERIAL | SERIAL1); // goes to both
writer.println("Some other output", SERIAL); // goes to Serial only
writer.println("Yet another output", SERIAL1); // goes to Serial1 only

Now you have a repeatable pattern that you can let be programmatically controlled:

Code: [Select]
if(somecondition) outputs = SERIAL;
else if(someothercondition) outputs = SERIAL | SERIAL1;
writer.println("Display me!", outputs);



For now I 'm using two auxiliary variables, writeXBee and writeLog.

Two if conditions, containing identical print code, but for different ports, read those variables and decide whether they should write or not.

It creates larger code but simpler, a better alternative for me for this debugging stage.

Go Up