Skip to content

Serial Stream Refactor and Split-Channel Example#220

Open
brocci wants to merge 5 commits into
SvenRosvall:mainfrom
brocci:stream-serial-refactor
Open

Serial Stream Refactor and Split-Channel Example#220
brocci wants to merge 5 commits into
SvenRosvall:mainfrom
brocci:stream-serial-refactor

Conversation

@brocci

@brocci brocci commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

This PR refactors serial bindings to use Arduino Stream instead of hard-wiring to global Serial, while preserving default behavior.

It also adds a new example showing split serial channels:

  • SerialGC on hardware Serial (GridConnect transport)
  • SerialUserInterface on SoftwareSerial or Serial1 on Mega2560 (user console)

Changes

  • Refactor SerialGC constructor/member type to Stream&
  • Keep transport stream protocol-clean in SerialGC::begin() (Removed startup banner print from begin)
  • Refactor SerialUserInterface to injected Stream& with default Serial
  • Add new split-channel example: examples/VLCB_SerialGC_SerialUI_SoftwareSerial/VLCB_SerialGC_SerialUI_SoftwareSerial.ino
  • Document new example in docs/Examples.md

Why

  • Allow SerialGC and SerialUserInterface to work with either HardwareSerial or SoftwareSerial (or other Stream-compatible ports).
  • Enable practical split-channel use where protocol traffic and UI commands are isolated.
  • Avoid accidental non-GridConnect text on the transport stream.

Compatibility

  • Existing sketches remain compatible via default constructors using Serial.
  • Behavior is unchanged unless an alternate stream is explicitly passed.

Closes #216

@brocci brocci marked this pull request as ready for review June 17, 2026 21:49
@SvenRosvall

Copy link
Copy Markdown
Owner

Quick early comment (before reviewing thoroughly) is that the name of the sketch is long. Also I'd like to include "empty" in the name to show what functionality it provides.

Suggest "VLCB_SerialGC_empty_withSerialUI.ino"
OK, that is not much shorter. :( The "SerialGC" must be there. Or can we shorten this marker? (applies to all serial example sketches) "VLCB" must be there to avoid confusion with the examples in the "CBUS" library if you work with both libraries.

Does this make sense?

@brocci

brocci commented Jun 18, 2026

Copy link
Copy Markdown
Contributor Author

Yes, it makes sense. The longest example filename is VLCB_long_message_example, 25 characters.
Would VLCB_SerialGC_SerialUI_empty be better?

@SvenRosvall

Copy link
Copy Markdown
Owner

Would VLCB_SerialGC_SerialUI_empty be better?

Yes. it does. Just thinking that the "empty" bit should be earlier in the file name. But that would affect existing VLCB_SerialGC sketches. Need to think about a naming convention and if needed change all sketches.

@@ -0,0 +1,144 @@
// Copyright (C) Sven Rosvall (sven@rosvall.ie)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please claim copyright for yourself.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahah. I didn't think about this ;-)

serialUserPort << F("> compiled on ") << __DATE__ << F(" at ") << __TIME__ << F(", compiler ver = ") << __cplusplus << endl;

// copyright
serialUserPort << F("> © Sven Rosvall (MERG 3777) 2026") << endl;

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claim copyright for yourself. ;)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, 90% of the code is yours. But OK ;-)

//
/// print code version config details and copyright notice
//
void printConfig()

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you put this function at the bottom of this file. Then it is easier to compare the different "*_empty" sketches.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought I had put it back in my last commit. Need to check.

Comment thread test/ArduinoMock.cpp
{
}

Serial_T & operator<<(Serial_T & s, int i)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I implemented these operators this way so that any debug info would be printed in the text outputs for the unit tests. This is handy when troubleshooting.

Can you keep these operators but change to use your Stream class?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will have a look.

Comment thread Arduino/Arduino.h

struct Serial_T
{
void begin(int baudrate);

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This begin() function is used by the example sketches.

No, these headers are not used by the Arduino IDE or your new workflows when compiling the example sketches. However I also use the headers in the Arduino directory for my IDE (CLion) so that the example sketch codes come up nicely in the IDE without any red markers. So please keep the begin() function in the Stream.h .

Comment thread Arduino/Stream.h Outdated
virtual void flush() {}
};

// Operator overloads for Stream to work with Streaming library

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These operators don't need definitions in the Arduino directory. This directory is only used to make my IDE work well with Arduino code.
For executing test code the definitions should reside in ArduinoMock.cpp in the test directory. See also comments there.

Comment thread src/SerialGC.h
{
public:
SerialGC(typeof(Serial)& _serial = Serial) : serial(_serial) {}
SerialGC(Stream& _serial = Serial) : serial(_serial) {}

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes! That looks much nicer. Should have done that from the beginning. :)

Comment thread src/SerialUserInterface.h
{
public:
/// @cond LIBRARY
SerialUserInterface(Stream& _serial = Serial) : serial(_serial) {}

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The constructor should be declared above the @cond line.
The @cond tells Doxygen to ignore a block (until @endcond) of declarations. This is useful to reduce the amount of documentation a sketch developer needs to see. (The library developer needs to see everything.)
This constructor is something a sketch developer will use and thus it should be include in the sketch developer documentation.

@SvenRosvall

Copy link
Copy Markdown
Owner

Thanks for this pull request. It looks good. Will be a good feature. I know John Fletcher will be happy about this.

The comments I have added are mostly about my style and how I work with this project. Sorry that this is not documented properly. So the comments are there to share this until I get that bit done.

@brocci

brocci commented Jun 19, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for this pull request. It looks good. Will be a good feature. I know John Fletcher will be happy about this.

Thank you. I will fix the remaining "glitches" and commit on this PR. Happy to make John happy :-)

The comments I have added are mostly about my style and how I work with this project. Sorry that this is not documented properly. So the comments are there to share this until I get that bit done.

No problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Using both SerialGC and SerialUserInterface

2 participants