I want to write a function that defines a serial port based on a flag but I'm not sure it's possible.
For example:
void writeToSerial(bool useSerial1)
{
SerialPortClass serialPortObject; // Is there some way of defining a generic Serial port object and reusing it below?
if (useSerial1)
{
serialPortObject = Serial1;
}
else
{
serialPortObject = Serial2;
}
serialPortObject.write("test123");
}
-
1Does this answer your question? Passing HardwareSerial and SoftwareSerial as a Class PropertyJuraj– Juraj ♦2020年07月23日 13:05:39 +00:00Commented Jul 23, 2020 at 13:05
2 Answers 2
According to sources at c:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino\HardwareSerial*
(on Windows platform), you can use pointer to Stream
class (because Serial
s are inherited from Stream
).
So, your function could look like this:
void writeToSerial(bool useSerial1)
{
Stream* serialPortObject;
if (useSerial1)
{
serialPortObject = &Serial1;
}
else
{
serialPortObject = &Serial2;
}
serialPortObject->write("test123");
}
-
2Note that the serial port has to be already initialized for this to work, as
Stream
lacks thebegin()
method. If you need to call eitherbegin()
orend()
, you should use a pointer toHardwareSerial
.Edgar Bonet– Edgar Bonet2020年07月23日 13:14:10 +00:00Commented Jul 23, 2020 at 13:14
This is not a proper answer, but rather a suggestion to reconsider your
approach. The code posted in the question is obviously just a simplified
example, and printing "test123" is likely not your final goal. I assume
what you really want to do is print out some information about some
variables. You can then collect these variables into a data structure (a
C++ object) and make writeToSerial()
a method of this object. The
object can the be printed like so:
myDataStructure::writeToSerial(true); // printed to Serial1
myDataStructure::writeToSerial(false); // printed to Serial2
In this case, what I suggest is to instead explicitly print()
(or
println()
) the object to the relevant serial port, like this:
Serial1.print(myDataStructure);
Serial2.print(myDataStructure);
This makes the code self-explanatory, and easier to maintain.
Obviously, you cannot just print arbitrary objects this way, as
Serial1
and Serial2
would have no idea about how to serialize them.
But the thing is, you can teach them! Make your class derive from
Printable
, implement the virtual printTo()
method, and you will be
able to print it to any serial port, LCD, or whatever understands
print()
:
class MyDataStructure : public Printable {
public:
size_t printTo(Print& p) const {
return p.print("test123");
}
};
MyDataStructure someData;
void setup() {
Serial1.begin(9600);
Serial2.begin(9600);
Serial1.println(someData);
Serial2.println(someData);
}
void loop(){}
See the answer to Is it possible to print a custom object by passing it to Serial.print()? for an example with actual data in the object.