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 there any set of 2-6 notes that doesn't have a chord name?
Was touching your nose a greeting in second millenium Mesopotamia?
Why isn’t the tax system continuous rather than bracketed?
Should my manager be aware of private LinkedIn approaches I receive? How to politely have this happen?
Does image quality of the lens affect "focus and recompose" technique?
Intuitively, why does putting capacitors in series decrease the equivalent capacitance?
Every infinite linearly ordered set has two disjoint infinite subsets
Could Sauron have read Tom Bombadil's mind if Tom had held the Palantir?
Fedora boot screen shows both Fedora logo and Lenovo logo. Why and How?
Fitting a mixture of two normal distributions for a data set?
Layout of complex table
How many codes are possible?
Why does the numerical solution of an ODE move away from an unstable equilibrium?
Are Finite Automata Turing Complete?
Bash echo $-1 prints hb1. Why?
Inverse-quotes-quine
Does anycast addressing add additional latency in any way?
Find smallest index that is identical to the value in an array
What is the line crossing the Pacific Ocean that is shown on maps?
What are the penalties for overstaying in USA?
Is there a short way to compare many values mutually at same time without using multiple 'and's?
Why would people reject a god's purely beneficial blessing?
Why does the A-4 Skyhawk sit nose-up when on ground?
How risky is real estate?
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 useprintln
rather thanprint
and 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 withSerial
andSerial1
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
The Bluetooth link should see the exact same byte stream whether you print throughSerial1
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 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
135 bronze badges
135 bronze badges
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 useprintln
rather thanprint
and 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 withSerial
andSerial1
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
The Bluetooth link should see the exact same byte stream whether you print throughSerial1
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 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 useprintln
rather thanprint
and 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 withSerial
andSerial1
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
The Bluetooth link should see the exact same byte stream whether you print throughSerial1
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 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 exampleout
is an instance ofDualPrint
, is that right? How is it declared?DualPrint out;
??
– Hubert B
Jun 9 at 9:50
@HubertB: Yes,out
is 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 exampleout
is an instance ofDualPrint
, is that right? How is it declared?DualPrint out;
??
– Hubert B
Jun 9 at 9:50
@HubertB: Yes,out
is 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 exampleout
is an instance ofDualPrint
, is that right? How is it declared?DualPrint out;
??
– Hubert B
Jun 9 at 9:50
@HubertB: Yes,out
is 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
26.1k2 gold badges25 silver badges46 bronze badges
26.1k2 gold badges25 silver badges46 bronze badges
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 exampleout
is an instance ofDualPrint
, is that right? How is it declared?DualPrint out;
??
– Hubert B
Jun 9 at 9:50
@HubertB: Yes,out
is 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 exampleout
is an instance ofDualPrint
, is that right? How is it declared?DualPrint out;
??
– Hubert B
Jun 9 at 9:50
@HubertB: Yes,out
is 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
println
rather thanprint
and 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 withSerial
andSerial1
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
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 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