Hardware Serial Port Referencing

Hey All :slight_smile:

I am trying to figure out how to use references with the hardware serial ports.

// File: sketch.ino

#include <Arduino.h>
#include <TestSerial.h>

TestSerial testSerial(Serial);

void setup() {
Serial.begin(9600);
}

void loop() {
if (Serial.available() > 0) {
byte iByte = Serial.read();
testSerial.sayit();
}
}

// File: TestSerial.h
#ifndef TestSerial_h
#define TestSerial_h

class TestSerial {
private:
// Here is where I want to declare whatever it is I need to declare to get the reference supplied by the constructor
// but I have no idea what to do. I have tried:
HardwareSerial& privateSerial;
// Which generates a compiler error cannot convert 'HardwareSerial' to 'HardwareSerial*' in assignment

public:
TestSerial(HardwareSerial& localSerial);
void sayit();
};

#endif

// File: TestSerial.cpp

#include <Arduino.h>
#include <TestSerial.h>

TestSerial::TestSerial(HardwareSerial& localSerial) {
// Here is where I want to put the reference 'localSerial' into the 'privateSerial'
// I tried:
privateSerial = localSerial; - No go because of compiler error
}

void TestSerial::sayit() {
privateSerial.println("HELLO WORLD!");
}

Any ideas?

I think you can use a pointer to Print for output to a hardware or software serial port:

Print *myPort;

SoftwareSerial mySoftSerial(2,3);

myPort = Serial1;
myPort = mySoftSerial;

myPort->println("Hello, world.");

For input I think you may need a Stream pointer instead.

Change TestSerial.h to read:

#ifndef TestSerial_h
#define TestSerial_h

class TestSerial {
  private:
     HardwareSerial& privateSerial;  

  public:
    TestSerial(HardwareSerial& localSerial) : privateSerial (localSerial) { } 
    void sayit();
};

#endif

And remove the constructor from TestSerial.cpp.

Ok, that last suggestion works wonderful for a single reference, but...

What if I wanted to have the constructor deal with multiple hardware serial port references?

And could I get them into an array?

class MyClass {
private:
HardwareSerial& portA;
HardwareSerial& portB;
HardwareSerial& portC;
HardwareSerial& portD;

// What about
HardwareSerial& ports[4];

public:
MyClass(HardwareSerial& sRefA, HardwareSerial& sRefB, HardwareSerial& sRefB, HardwareSerial& sRefC, HardwareSerial sRefD)

};

That's as far as I have gotten, need further direction....

And could I get them into an array?

Define the array correctly, and assign the instances one at a time.

What about that declaration? Didi it compile? Did the assignments in the constructor work? Did the array access then work?

Example code from an earlier thread:

class myMenu 
  {
  private:
    Stream & port_; 
  public:
    myMenu (Stream & port) : port_ (port) { }
    void begin ();
  };

void myMenu::begin ()
  {
  port_.println ("Menu initialized."); 
  }

myMenu menu (Serial);

void setup ()
  {
  Serial.begin (115200);
  menu.begin ();
  }  // end of setup

void loop () { }

I thank you guys for being patient with me, however, I am still a little stumped.

I need my class to contain all 4 hardware serial ports as references so that I can work with them locally inside the class.

Your example for a single reference worked fine for a singe serial port reference.

How do I get the constructor to deal with all of the references I pass to it?

IE:

// Header file

class MyClass {
private:
HardwareSerial& portA, portB, portC, portD;

public:
MyClass(HardwareSerial& sRefA, HardwareSerial& sRefB, HardwareSerial& sRefC, HardwareSerial& sRefD) {
// How to assign the references passed to the constructor to the local class objects?
//
}

// Or deal with them in the source file constuctor...

// Source file
#include <MyClass.h>

MyClass::MyClass(HardwareSerial& sRefA, HardwareSerial& sRefB, HardwareSerial& sRefC, HardwareSerial& sRefD) {
portA = sRefA; // Does not work
portB = sRefB;
portC = sRefC;
portD = sRefD;

}

Time to start using code tags.

How to use this forum

You use the initialization list syntax which my example showed. This compiles:

class MyClass 
  {
  private:
    HardwareSerial&   portA, portB, portC, portD;
  
  public:
    // constructor
    MyClass (HardwareSerial& sRefA, HardwareSerial& sRefB, HardwareSerial& sRefC, HardwareSerial& sRefD);
  };

MyClass::MyClass (HardwareSerial& sRefA, HardwareSerial& sRefB, HardwareSerial& sRefC, HardwareSerial& sRefD) :
  // initialization list
  portA (sRefA), portB (sRefB), portC (sRefC), portD (sRefD)
  {
    // other code
  }

MyClass foo (Serial, Serial1, Serial2, Serial3);

void setup () { }
void loop () { }

Thank you ever so much! This works perfectly!

I am not quite sure what is happening, but it works and for now that's all that matters.

Again, thank you for your help!

and thank you for pointing out the code blocks pointer, I was wondering how you guys did that :slight_smile: