Arduino wrap or subclass print() to work with multiple SerialReading multiple bytes from *software* serialSerial Communication with two bluetooth modules on Arduino MegaWhy can't I print this text to LCD?Serial is freezing arduinoArduino to read from RS232 converter to TTL serial module (updated)47Effects MIDI Library and serial debuggingArduino + SIM808 HTTP GET POST headersUtilizing two different serial ports simultaneously on a dueC: No communication to a connected serial port?
Is swap gate equivalent to just exchanging the wire of the two qubits?
What is this plant I saw for sale at a Romanian farmer's market?
what is "dot" sign in the •NO?
Explicit direct #include vs. Non-contractual transitive #include
Is the infant mortality rate among African-American babies in Youngstown, Ohio greater than that of babies in Iran?
How did space travel spread through the galaxy?
Why is gun control associated with the socially liberal Democratic party?
Positive cumulative sum of difference
Background for black and white chart
Fill the maze with a wall-following Snake until it gets stuck
Co-worker is now managing my team. Does this mean that I'm being demoted?
TiKZ won't graph 1/sqrt(x)
Numerical second order differentiation
Digital signature that is only verifiable by one specific person
Why can't we feel the Earth's revolution?
What do I put on my resume to make the company i'm applying to think i'm mature enough to handle a job?
Catching a robber on one line
Converting 3x7 to a 1x7. Is it possible with only existing parts?
Basic power tool set for Home repair and simple projects
Is it a bad idea to have a pen name with only an initial for a surname?
What is the color associated with lukewarm?
Does knowing the surface area of all faces uniquely determine a tetrahedron?
Can I drive in EU states and Switzerland with German proof of a surrendered U.S. license?
Should I email my professor to clear up a (possibly very irrelevant) awkward misunderstanding?
Arduino wrap or subclass print() to work with multiple Serial
Reading multiple bytes from *software* serialSerial Communication with two bluetooth modules on Arduino MegaWhy can't I print this text to LCD?Serial is freezing arduinoArduino to read from RS232 converter to TTL serial module (updated)47Effects MIDI Library and serial debuggingArduino + SIM808 HTTP GET POST headersUtilizing two different serial ports simultaneously on a dueC: No communication to a connected serial port?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
I am writing an Arduino program that uses Bluetooth on Serial1 to print text to a Bluetooth terninal on an Android phone and also normal Serial to print text to the serial monitor on a laptop. I would like to wrap the Serial.print() and Serial.println() functions so that they work with either or both Serial and Serial1. For example the code below works fine depending on the values of the global variables. But this only works for single chars, but print() and println() can take a very wide variety of datatypes. If I also define overloading functions for int and String types it works fine, but that is a very verbose and maybe fragile solution, it also ignores the optional inputs to the underlying functions. What is the proper way to do this ?
void print(char x)
if (g_use_Serial)
Serial.print(x);
if (g_use_Serial1)
Serial1.print(x);
void println(char x)
if (g_use_Serial)
Serial.println(x);
if (g_use_Serial1)
Serial1.println(x);
I have implemented the solution suggested and it works nearly perfectly. There seems to be a problem with the new line characters on the bluetooth (Serial1) connection.
The code is:
class DualPrint : public Print
public:
DualPrint() : use_Serial(false), use_Serial1(false)
virtual size_t write(uint8_t c)
if (use_Serial) Serial.write(c);
if (use_Serial1) Serial1.write(c);
return 1;
bool use_Serial, use_Serial1;
out;
void setup()
Serial.begin(9600);
Serial1.begin(9600);
delay(1000);
void loop()
out.use_Serial = true;
out.print("Printed to USB only.n");
out.use_Serial1 = true;
out.print("Printed to both USB and BT.n");
out.use_Serial = false;
out.print("Printed to BT only.n");
out.use_Serial1 = false;
delay(3000);
The output on the USB Serial monitor is as expected:
Printed to USB only.
Printed to both USB and BT.
Printed to USB only.
Printed to both USB and BT.
The output on the Bluetooth terminal is not as expected, the new lines are not in the right position:
Printed to both USB and BT.Pri
nted to BT only.
Printed to both USB and BT.Pr
inted to BT only.
Printed to both USB and BT.Pr
inted to BT only.
Printed to both USB and BT.Pr
inted to BT only.
Any suggestions on how to fix this. Are there other function members that need to be re-implemented to make this work properly?
Many thanks for high quality answers so far.
arduino-uno serial c++ c
|
show 3 more comments
I am writing an Arduino program that uses Bluetooth on Serial1 to print text to a Bluetooth terninal on an Android phone and also normal Serial to print text to the serial monitor on a laptop. I would like to wrap the Serial.print() and Serial.println() functions so that they work with either or both Serial and Serial1. For example the code below works fine depending on the values of the global variables. But this only works for single chars, but print() and println() can take a very wide variety of datatypes. If I also define overloading functions for int and String types it works fine, but that is a very verbose and maybe fragile solution, it also ignores the optional inputs to the underlying functions. What is the proper way to do this ?
void print(char x)
if (g_use_Serial)
Serial.print(x);
if (g_use_Serial1)
Serial1.print(x);
void println(char x)
if (g_use_Serial)
Serial.println(x);
if (g_use_Serial1)
Serial1.println(x);
I have implemented the solution suggested and it works nearly perfectly. There seems to be a problem with the new line characters on the bluetooth (Serial1) connection.
The code is:
class DualPrint : public Print
public:
DualPrint() : use_Serial(false), use_Serial1(false)
virtual size_t write(uint8_t c)
if (use_Serial) Serial.write(c);
if (use_Serial1) Serial1.write(c);
return 1;
bool use_Serial, use_Serial1;
out;
void setup()
Serial.begin(9600);
Serial1.begin(9600);
delay(1000);
void loop()
out.use_Serial = true;
out.print("Printed to USB only.n");
out.use_Serial1 = true;
out.print("Printed to both USB and BT.n");
out.use_Serial = false;
out.print("Printed to BT only.n");
out.use_Serial1 = false;
delay(3000);
The output on the USB Serial monitor is as expected:
Printed to USB only.
Printed to both USB and BT.
Printed to USB only.
Printed to both USB and BT.
The output on the Bluetooth terminal is not as expected, the new lines are not in the right position:
Printed to both USB and BT.Pri
nted to BT only.
Printed to both USB and BT.Pr
inted to BT only.
Printed to both USB and BT.Pr
inted to BT only.
Printed to both USB and BT.Pr
inted to BT only.
Any suggestions on how to fix this. Are there other function members that need to be re-implemented to make this work properly?
Many thanks for high quality answers so far.
arduino-uno serial c++ c
No. The general technique should work OK. Perhaps the Bluetooth can't handle more than 30 bytes before throwing in a newline of its own. In any case, why not useprintlnrather thanprintand then supplying your own newline?
– Nick Gammon♦
Jun 9 at 11:19
I tried with bothprintln("...")andprint("...n"), same behavior with both. I hard coded the same outputs withSerialandSerial1and it works fine so nothing to do with Bluetooth. It is something to do with the new class.
– Hubert B
Jun 9 at 11:32
1
The Bluetooth link should see the exact same byte stream whether you print throughSerial1or this class. Only the timing will be slightly different, so it could be that whatever receives the data is sensitive to the timing of the incoming bytes. This could be mitigated by overridingvirtual size_t write(const uint8_t *buffer, size_t size).
– Edgar Bonet
Jun 9 at 11:37
1
Should that look like this:virtual size_t write(const uint8_t *buffer, size_t size) if (use_Serial) Serial.write(buffer, size); if (use_Serial1) Serial1.write(buffer, size); return 1;
– Hubert B
Jun 9 at 13:03
I doubt the timing will matter. Those bytes will be buffered and sent out by an interrupt service routine.
– Nick Gammon♦
Jun 9 at 22:50
|
show 3 more comments
I am writing an Arduino program that uses Bluetooth on Serial1 to print text to a Bluetooth terninal on an Android phone and also normal Serial to print text to the serial monitor on a laptop. I would like to wrap the Serial.print() and Serial.println() functions so that they work with either or both Serial and Serial1. For example the code below works fine depending on the values of the global variables. But this only works for single chars, but print() and println() can take a very wide variety of datatypes. If I also define overloading functions for int and String types it works fine, but that is a very verbose and maybe fragile solution, it also ignores the optional inputs to the underlying functions. What is the proper way to do this ?
void print(char x)
if (g_use_Serial)
Serial.print(x);
if (g_use_Serial1)
Serial1.print(x);
void println(char x)
if (g_use_Serial)
Serial.println(x);
if (g_use_Serial1)
Serial1.println(x);
I have implemented the solution suggested and it works nearly perfectly. There seems to be a problem with the new line characters on the bluetooth (Serial1) connection.
The code is:
class DualPrint : public Print
public:
DualPrint() : use_Serial(false), use_Serial1(false)
virtual size_t write(uint8_t c)
if (use_Serial) Serial.write(c);
if (use_Serial1) Serial1.write(c);
return 1;
bool use_Serial, use_Serial1;
out;
void setup()
Serial.begin(9600);
Serial1.begin(9600);
delay(1000);
void loop()
out.use_Serial = true;
out.print("Printed to USB only.n");
out.use_Serial1 = true;
out.print("Printed to both USB and BT.n");
out.use_Serial = false;
out.print("Printed to BT only.n");
out.use_Serial1 = false;
delay(3000);
The output on the USB Serial monitor is as expected:
Printed to USB only.
Printed to both USB and BT.
Printed to USB only.
Printed to both USB and BT.
The output on the Bluetooth terminal is not as expected, the new lines are not in the right position:
Printed to both USB and BT.Pri
nted to BT only.
Printed to both USB and BT.Pr
inted to BT only.
Printed to both USB and BT.Pr
inted to BT only.
Printed to both USB and BT.Pr
inted to BT only.
Any suggestions on how to fix this. Are there other function members that need to be re-implemented to make this work properly?
Many thanks for high quality answers so far.
arduino-uno serial c++ c
I am writing an Arduino program that uses Bluetooth on Serial1 to print text to a Bluetooth terninal on an Android phone and also normal Serial to print text to the serial monitor on a laptop. I would like to wrap the Serial.print() and Serial.println() functions so that they work with either or both Serial and Serial1. For example the code below works fine depending on the values of the global variables. But this only works for single chars, but print() and println() can take a very wide variety of datatypes. If I also define overloading functions for int and String types it works fine, but that is a very verbose and maybe fragile solution, it also ignores the optional inputs to the underlying functions. What is the proper way to do this ?
void print(char x)
if (g_use_Serial)
Serial.print(x);
if (g_use_Serial1)
Serial1.print(x);
void println(char x)
if (g_use_Serial)
Serial.println(x);
if (g_use_Serial1)
Serial1.println(x);
I have implemented the solution suggested and it works nearly perfectly. There seems to be a problem with the new line characters on the bluetooth (Serial1) connection.
The code is:
class DualPrint : public Print
public:
DualPrint() : use_Serial(false), use_Serial1(false)
virtual size_t write(uint8_t c)
if (use_Serial) Serial.write(c);
if (use_Serial1) Serial1.write(c);
return 1;
bool use_Serial, use_Serial1;
out;
void setup()
Serial.begin(9600);
Serial1.begin(9600);
delay(1000);
void loop()
out.use_Serial = true;
out.print("Printed to USB only.n");
out.use_Serial1 = true;
out.print("Printed to both USB and BT.n");
out.use_Serial = false;
out.print("Printed to BT only.n");
out.use_Serial1 = false;
delay(3000);
The output on the USB Serial monitor is as expected:
Printed to USB only.
Printed to both USB and BT.
Printed to USB only.
Printed to both USB and BT.
The output on the Bluetooth terminal is not as expected, the new lines are not in the right position:
Printed to both USB and BT.Pri
nted to BT only.
Printed to both USB and BT.Pr
inted to BT only.
Printed to both USB and BT.Pr
inted to BT only.
Printed to both USB and BT.Pr
inted to BT only.
Any suggestions on how to fix this. Are there other function members that need to be re-implemented to make this work properly?
Many thanks for high quality answers so far.
arduino-uno serial c++ c
arduino-uno serial c++ c
edited Jun 9 at 11:13
Hubert B
asked Jun 8 at 20:47
Hubert BHubert B
134
134
No. The general technique should work OK. Perhaps the Bluetooth can't handle more than 30 bytes before throwing in a newline of its own. In any case, why not useprintlnrather thanprintand then supplying your own newline?
– Nick Gammon♦
Jun 9 at 11:19
I tried with bothprintln("...")andprint("...n"), same behavior with both. I hard coded the same outputs withSerialandSerial1and it works fine so nothing to do with Bluetooth. It is something to do with the new class.
– Hubert B
Jun 9 at 11:32
1
The Bluetooth link should see the exact same byte stream whether you print throughSerial1or this class. Only the timing will be slightly different, so it could be that whatever receives the data is sensitive to the timing of the incoming bytes. This could be mitigated by overridingvirtual size_t write(const uint8_t *buffer, size_t size).
– Edgar Bonet
Jun 9 at 11:37
1
Should that look like this:virtual size_t write(const uint8_t *buffer, size_t size) if (use_Serial) Serial.write(buffer, size); if (use_Serial1) Serial1.write(buffer, size); return 1;
– Hubert B
Jun 9 at 13:03
I doubt the timing will matter. Those bytes will be buffered and sent out by an interrupt service routine.
– Nick Gammon♦
Jun 9 at 22:50
|
show 3 more comments
No. The general technique should work OK. Perhaps the Bluetooth can't handle more than 30 bytes before throwing in a newline of its own. In any case, why not useprintlnrather thanprintand then supplying your own newline?
– Nick Gammon♦
Jun 9 at 11:19
I tried with bothprintln("...")andprint("...n"), same behavior with both. I hard coded the same outputs withSerialandSerial1and it works fine so nothing to do with Bluetooth. It is something to do with the new class.
– Hubert B
Jun 9 at 11:32
1
The Bluetooth link should see the exact same byte stream whether you print throughSerial1or this class. Only the timing will be slightly different, so it could be that whatever receives the data is sensitive to the timing of the incoming bytes. This could be mitigated by overridingvirtual size_t write(const uint8_t *buffer, size_t size).
– Edgar Bonet
Jun 9 at 11:37
1
Should that look like this:virtual size_t write(const uint8_t *buffer, size_t size) if (use_Serial) Serial.write(buffer, size); if (use_Serial1) Serial1.write(buffer, size); return 1;
– Hubert B
Jun 9 at 13:03
I doubt the timing will matter. Those bytes will be buffered and sent out by an interrupt service routine.
– Nick Gammon♦
Jun 9 at 22:50
No. The general technique should work OK. Perhaps the Bluetooth can't handle more than 30 bytes before throwing in a newline of its own. In any case, why not use
println rather than print and then supplying your own newline?– Nick Gammon♦
Jun 9 at 11:19
No. The general technique should work OK. Perhaps the Bluetooth can't handle more than 30 bytes before throwing in a newline of its own. In any case, why not use
println rather than print and then supplying your own newline?– Nick Gammon♦
Jun 9 at 11:19
I tried with both
println("...") and print("...n"), same behavior with both. I hard coded the same outputs with Serial and Serial1 and it works fine so nothing to do with Bluetooth. It is something to do with the new class.– Hubert B
Jun 9 at 11:32
I tried with both
println("...") and print("...n"), same behavior with both. I hard coded the same outputs with Serial and Serial1 and it works fine so nothing to do with Bluetooth. It is something to do with the new class.– Hubert B
Jun 9 at 11:32
1
1
The Bluetooth link should see the exact same byte stream whether you print through
Serial1 or this class. Only the timing will be slightly different, so it could be that whatever receives the data is sensitive to the timing of the incoming bytes. This could be mitigated by overriding virtual size_t write(const uint8_t *buffer, size_t size).– Edgar Bonet
Jun 9 at 11:37
The Bluetooth link should see the exact same byte stream whether you print through
Serial1 or this class. Only the timing will be slightly different, so it could be that whatever receives the data is sensitive to the timing of the incoming bytes. This could be mitigated by overriding virtual size_t write(const uint8_t *buffer, size_t size).– Edgar Bonet
Jun 9 at 11:37
1
1
Should that look like this:
virtual size_t write(const uint8_t *buffer, size_t size) if (use_Serial) Serial.write(buffer, size); if (use_Serial1) Serial1.write(buffer, size); return 1; – Hubert B
Jun 9 at 13:03
Should that look like this:
virtual size_t write(const uint8_t *buffer, size_t size) if (use_Serial) Serial.write(buffer, size); if (use_Serial1) Serial1.write(buffer, size); return 1; – Hubert B
Jun 9 at 13:03
I doubt the timing will matter. Those bytes will be buffered and sent out by an interrupt service routine.
– Nick Gammon♦
Jun 9 at 22:50
I doubt the timing will matter. Those bytes will be buffered and sent out by an interrupt service routine.
– Nick Gammon♦
Jun 9 at 22:50
|
show 3 more comments
1 Answer
1
active
oldest
votes
You can create a class derived from Print that forwards its output to
either or both Serial and Serial1. The only method you need to
implement for this to work is write(uint8_t):
class DualPrint : public Print
public:
DualPrint() : use_Serial(false), use_Serial1(false)
virtual size_t write(uint8_t c)
if (use_Serial) Serial.write(c);
if (use_Serial1) Serial1.write(c);
return 1;
bool use_Serial, use_Serial1;
out;
You would use it like this:
out.use_Serial = true;
out.println("Printed to Serial only");
out.use_Serial1 = true;
out.println("Printed to both Serial and Serial1");
out.use_Serial = false;
out.println("Printed to Serial1 only");
Note that with this approach, unlike yours, printing number will format
them as text only once, and the underlying Serial and Serial1 will
only handle the resulting characters.
Edit: To answer the question in OP's comment, the construct
class ClassName
...definition...
classInstace;
is a shotcut for
class ClassName
...definition...
;
ClassName classInstace;
A very similar construct exists in plain C:
struct struct_name
...the struct fields...
struct_instance;
1
for advanced users I would overrideavailableForWrite()andflush()too
– Juraj
Jun 9 at 4:44
@Edgar Many thanks for this, very helpful. One request, I am more experienced at C than C++ so the class definition is unfamiliar. In the usage exampleoutis an instance ofDualPrint, is that right? How is it declared?DualPrint out;??
– Hubert B
Jun 9 at 9:50
@HubertB: Yes,outis an instance ofDualPrint. See expanded answer.
– Edgar Bonet
Jun 9 at 10:05
Edgar & @Juraj I have updated the question with a progress report on implementing the suggested solution. It works almost perfectly except for new lines in wrong sequence in BT terminal. Any suggestions? Is this related to flush() or other functions that also need to be re-implemented?
– Hubert B
Jun 9 at 10:51
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
return StackExchange.using("schematics", function ()
StackExchange.schematics.init();
);
, "cicuitlab");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "540"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2farduino.stackexchange.com%2fquestions%2f66136%2farduino-wrap-or-subclass-print-to-work-with-multiple-serial%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
You can create a class derived from Print that forwards its output to
either or both Serial and Serial1. The only method you need to
implement for this to work is write(uint8_t):
class DualPrint : public Print
public:
DualPrint() : use_Serial(false), use_Serial1(false)
virtual size_t write(uint8_t c)
if (use_Serial) Serial.write(c);
if (use_Serial1) Serial1.write(c);
return 1;
bool use_Serial, use_Serial1;
out;
You would use it like this:
out.use_Serial = true;
out.println("Printed to Serial only");
out.use_Serial1 = true;
out.println("Printed to both Serial and Serial1");
out.use_Serial = false;
out.println("Printed to Serial1 only");
Note that with this approach, unlike yours, printing number will format
them as text only once, and the underlying Serial and Serial1 will
only handle the resulting characters.
Edit: To answer the question in OP's comment, the construct
class ClassName
...definition...
classInstace;
is a shotcut for
class ClassName
...definition...
;
ClassName classInstace;
A very similar construct exists in plain C:
struct struct_name
...the struct fields...
struct_instance;
1
for advanced users I would overrideavailableForWrite()andflush()too
– Juraj
Jun 9 at 4:44
@Edgar Many thanks for this, very helpful. One request, I am more experienced at C than C++ so the class definition is unfamiliar. In the usage exampleoutis an instance ofDualPrint, is that right? How is it declared?DualPrint out;??
– Hubert B
Jun 9 at 9:50
@HubertB: Yes,outis an instance ofDualPrint. See expanded answer.
– Edgar Bonet
Jun 9 at 10:05
Edgar & @Juraj I have updated the question with a progress report on implementing the suggested solution. It works almost perfectly except for new lines in wrong sequence in BT terminal. Any suggestions? Is this related to flush() or other functions that also need to be re-implemented?
– Hubert B
Jun 9 at 10:51
add a comment |
You can create a class derived from Print that forwards its output to
either or both Serial and Serial1. The only method you need to
implement for this to work is write(uint8_t):
class DualPrint : public Print
public:
DualPrint() : use_Serial(false), use_Serial1(false)
virtual size_t write(uint8_t c)
if (use_Serial) Serial.write(c);
if (use_Serial1) Serial1.write(c);
return 1;
bool use_Serial, use_Serial1;
out;
You would use it like this:
out.use_Serial = true;
out.println("Printed to Serial only");
out.use_Serial1 = true;
out.println("Printed to both Serial and Serial1");
out.use_Serial = false;
out.println("Printed to Serial1 only");
Note that with this approach, unlike yours, printing number will format
them as text only once, and the underlying Serial and Serial1 will
only handle the resulting characters.
Edit: To answer the question in OP's comment, the construct
class ClassName
...definition...
classInstace;
is a shotcut for
class ClassName
...definition...
;
ClassName classInstace;
A very similar construct exists in plain C:
struct struct_name
...the struct fields...
struct_instance;
1
for advanced users I would overrideavailableForWrite()andflush()too
– Juraj
Jun 9 at 4:44
@Edgar Many thanks for this, very helpful. One request, I am more experienced at C than C++ so the class definition is unfamiliar. In the usage exampleoutis an instance ofDualPrint, is that right? How is it declared?DualPrint out;??
– Hubert B
Jun 9 at 9:50
@HubertB: Yes,outis an instance ofDualPrint. See expanded answer.
– Edgar Bonet
Jun 9 at 10:05
Edgar & @Juraj I have updated the question with a progress report on implementing the suggested solution. It works almost perfectly except for new lines in wrong sequence in BT terminal. Any suggestions? Is this related to flush() or other functions that also need to be re-implemented?
– Hubert B
Jun 9 at 10:51
add a comment |
You can create a class derived from Print that forwards its output to
either or both Serial and Serial1. The only method you need to
implement for this to work is write(uint8_t):
class DualPrint : public Print
public:
DualPrint() : use_Serial(false), use_Serial1(false)
virtual size_t write(uint8_t c)
if (use_Serial) Serial.write(c);
if (use_Serial1) Serial1.write(c);
return 1;
bool use_Serial, use_Serial1;
out;
You would use it like this:
out.use_Serial = true;
out.println("Printed to Serial only");
out.use_Serial1 = true;
out.println("Printed to both Serial and Serial1");
out.use_Serial = false;
out.println("Printed to Serial1 only");
Note that with this approach, unlike yours, printing number will format
them as text only once, and the underlying Serial and Serial1 will
only handle the resulting characters.
Edit: To answer the question in OP's comment, the construct
class ClassName
...definition...
classInstace;
is a shotcut for
class ClassName
...definition...
;
ClassName classInstace;
A very similar construct exists in plain C:
struct struct_name
...the struct fields...
struct_instance;
You can create a class derived from Print that forwards its output to
either or both Serial and Serial1. The only method you need to
implement for this to work is write(uint8_t):
class DualPrint : public Print
public:
DualPrint() : use_Serial(false), use_Serial1(false)
virtual size_t write(uint8_t c)
if (use_Serial) Serial.write(c);
if (use_Serial1) Serial1.write(c);
return 1;
bool use_Serial, use_Serial1;
out;
You would use it like this:
out.use_Serial = true;
out.println("Printed to Serial only");
out.use_Serial1 = true;
out.println("Printed to both Serial and Serial1");
out.use_Serial = false;
out.println("Printed to Serial1 only");
Note that with this approach, unlike yours, printing number will format
them as text only once, and the underlying Serial and Serial1 will
only handle the resulting characters.
Edit: To answer the question in OP's comment, the construct
class ClassName
...definition...
classInstace;
is a shotcut for
class ClassName
...definition...
;
ClassName classInstace;
A very similar construct exists in plain C:
struct struct_name
...the struct fields...
struct_instance;
edited Jun 9 at 10:04
answered Jun 8 at 22:00
Edgar BonetEdgar Bonet
25.9k22546
25.9k22546
1
for advanced users I would overrideavailableForWrite()andflush()too
– Juraj
Jun 9 at 4:44
@Edgar Many thanks for this, very helpful. One request, I am more experienced at C than C++ so the class definition is unfamiliar. In the usage exampleoutis an instance ofDualPrint, is that right? How is it declared?DualPrint out;??
– Hubert B
Jun 9 at 9:50
@HubertB: Yes,outis an instance ofDualPrint. See expanded answer.
– Edgar Bonet
Jun 9 at 10:05
Edgar & @Juraj I have updated the question with a progress report on implementing the suggested solution. It works almost perfectly except for new lines in wrong sequence in BT terminal. Any suggestions? Is this related to flush() or other functions that also need to be re-implemented?
– Hubert B
Jun 9 at 10:51
add a comment |
1
for advanced users I would overrideavailableForWrite()andflush()too
– Juraj
Jun 9 at 4:44
@Edgar Many thanks for this, very helpful. One request, I am more experienced at C than C++ so the class definition is unfamiliar. In the usage exampleoutis an instance ofDualPrint, is that right? How is it declared?DualPrint out;??
– Hubert B
Jun 9 at 9:50
@HubertB: Yes,outis an instance ofDualPrint. See expanded answer.
– Edgar Bonet
Jun 9 at 10:05
Edgar & @Juraj I have updated the question with a progress report on implementing the suggested solution. It works almost perfectly except for new lines in wrong sequence in BT terminal. Any suggestions? Is this related to flush() or other functions that also need to be re-implemented?
– Hubert B
Jun 9 at 10:51
1
1
for advanced users I would override
availableForWrite() and flush() too– Juraj
Jun 9 at 4:44
for advanced users I would override
availableForWrite() and flush() too– Juraj
Jun 9 at 4:44
@Edgar Many thanks for this, very helpful. One request, I am more experienced at C than C++ so the class definition is unfamiliar. In the usage example
out is an instance of DualPrint, is that right? How is it declared? DualPrint out;??– Hubert B
Jun 9 at 9:50
@Edgar Many thanks for this, very helpful. One request, I am more experienced at C than C++ so the class definition is unfamiliar. In the usage example
out is an instance of DualPrint, is that right? How is it declared? DualPrint out;??– Hubert B
Jun 9 at 9:50
@HubertB: Yes,
out is an instance of DualPrint. See expanded answer.– Edgar Bonet
Jun 9 at 10:05
@HubertB: Yes,
out is an instance of DualPrint. See expanded answer.– Edgar Bonet
Jun 9 at 10:05
Edgar & @Juraj I have updated the question with a progress report on implementing the suggested solution. It works almost perfectly except for new lines in wrong sequence in BT terminal. Any suggestions? Is this related to flush() or other functions that also need to be re-implemented?
– Hubert B
Jun 9 at 10:51
Edgar & @Juraj I have updated the question with a progress report on implementing the suggested solution. It works almost perfectly except for new lines in wrong sequence in BT terminal. Any suggestions? Is this related to flush() or other functions that also need to be re-implemented?
– Hubert B
Jun 9 at 10:51
add a comment |
Thanks for contributing an answer to Arduino Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2farduino.stackexchange.com%2fquestions%2f66136%2farduino-wrap-or-subclass-print-to-work-with-multiple-serial%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
No. The general technique should work OK. Perhaps the Bluetooth can't handle more than 30 bytes before throwing in a newline of its own. In any case, why not use
printlnrather thanprintand then supplying your own newline?– Nick Gammon♦
Jun 9 at 11:19
I tried with both
println("...")andprint("...n"), same behavior with both. I hard coded the same outputs withSerialandSerial1and it works fine so nothing to do with Bluetooth. It is something to do with the new class.– Hubert B
Jun 9 at 11:32
1
The Bluetooth link should see the exact same byte stream whether you print through
Serial1or this class. Only the timing will be slightly different, so it could be that whatever receives the data is sensitive to the timing of the incoming bytes. This could be mitigated by overridingvirtual size_t write(const uint8_t *buffer, size_t size).– Edgar Bonet
Jun 9 at 11:37
1
Should that look like this:
virtual size_t write(const uint8_t *buffer, size_t size) if (use_Serial) Serial.write(buffer, size); if (use_Serial1) Serial1.write(buffer, size); return 1;– Hubert B
Jun 9 at 13:03
I doubt the timing will matter. Those bytes will be buffered and sent out by an interrupt service routine.
– Nick Gammon♦
Jun 9 at 22:50