Reference or pointer to a hardware serial object

Assuming that the target hardware is something like an Arduino Mega with support for multiple hardware serial ports.

I'm trying to write a fairly simple terminal emulator to go between the principal (USB) serial port and an arbitrary secondary port, so that I can experiment with various devices that expect "Hayes-like" command sequences. What I was hoping to do was have a menu at the start of the run so that I could select the port plus possibly Baud rate etc.

The thread at Hardware Serial Port Referencing - Programming Questions - Arduino Forum from around 2013 has examples of using both a reference and a pointer to indicate one of the possible hardware serial ports. I can get the "pointer-style" code to work, but can't help but feel that it's rather "K&R"; I can't get the reference-style code to work, getting something like

terminal:50:17: error: 'mySerial' declared as reference but not initialized
 HardwareSerial& mySerial;
                 ^~~~~~~~
/usr/local/src/arduino-examples/terminal/terminal.ino: In function 'void loop()':
terminal:15:14: error: use of deleted function 'HardwareSerial& HardwareSerial::operator=(const HardwareSerial&)'
 #define PORT Serial1
              ^~~~
/usr/local/src/arduino-examples/terminal/terminal.ino:56:16: note: in expansion of macro 'PORT'
     mySerial = PORT;
                ^~~~

Is this "use of deleted function" error to be expected? What's best practice for this sort of thing these days?

My apologies if I've overlooked anything obvious, I'm no great devotee of C/C++ so there's a possibility that I quite simply haven't hit on the right bit of "Google-fu".

MarkMLl

Can you post the code you are trying to compile?

Reference needs to be initialized when the variable is defined.

HardwareSerial& mySerial = PORT;

ToddL1962:
Can you post the code you are trying to compile?

I gave the wrong reference in my question, it should have been Easy way to select Serial, Serial1, Serial2, etc.... - Programming Questions - Arduino Forum

Note that this is not tested yet. This compiles:

#define PORT Serial1
#define PORTNAME "Serial1"
#define BAUD 115200
#define ONLINE false


#include "board_info.h" // Relies on a pair of symlinks from .. to .


void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200); // Note: some boards do not support 9600 Baud etc.
  while (!Serial) ; // wait for serial port to connect. Needed for Native USB only
#ifdef board_info_h
  BOARD_INFO(__FILE__ " " __DATE__ " " __TIME__);
#endif
  Serial.print("Port: ");
  Serial.print(PORTNAME);
  Serial.print(", online: ");
  if (ONLINE) {
    Serial.print("yes, baud: ");
    Serial.print(BAUD);
  } else
    Serial.print("no");
  Serial.println();  
}


HardwareSerial *mySerial;


void loop() {
  // put your main code here, to run repeatedly:
  if (ONLINE) {
    mySerial = &PORT;
    mySerial->begin(BAUD);
    while (! mySerial) ;
  }
  char c;
  while(true) {
    while (mySerial->available()) {
      c = mySerial->read();
      Serial.write(c);
    }
    if (Serial.available()) {
      c = Serial.read();
      mySerial->write(c);
    }

  }
  mySerial->end();
}

This does not compile with the errors given:

#define PORT Serial1
#define PORTNAME "Serial1"
#define BAUD 115200
#define ONLINE false


#include "board_info.h" // Relies on a pair of symlinks from .. to .


void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200); // Note: some boards do not support 9600 Baud etc.
  while (!Serial) ; // wait for serial port to connect. Needed for Native USB only
#ifdef board_info_h
  BOARD_INFO(__FILE__ " " __DATE__ " " __TIME__);
#endif
  Serial.print("Port: ");
  Serial.print(PORTNAME);
  Serial.print(", online: ");
  if (ONLINE) {
    Serial.print("yes, baud: ");
    Serial.print(BAUD);
  } else
    Serial.print("no");
  Serial.println();  
}


HardwareSerial &mySerial = PORT;


void loop() {
  // put your main code here, to run repeatedly:
  if (ONLINE) {
    mySerial = PORT;
    mySerial.begin(BAUD);
    while (! mySerial) ;
  }
  char c;
  while(true) {
    while (mySerial.available()) {
      c = mySerial.read();
      Serial.write(c);
    }
    if (Serial.available()) {
      c = Serial.read();
      mySerial.write(c);
    }

  }
  mySerial.end();
}
/usr/local/src/arduino-examples/terminal/terminal.ino: In function 'void loop()':
terminal:15:14: error: use of deleted function 'HardwareSerial& HardwareSerial::operator=(const HardwareSerial&)'
 #define PORT Serial1
              ^
/usr/local/src/arduino-examples/terminal/terminal.ino:49:16: note: in expansion of macro 'PORT'
     mySerial = PORT;
                ^~~~

MarkMLl

why not
#define mySerial Serial1
?

Juraj:
why not
#define mySerial Serial1
?

because it won't work dynamically

aarg:
because it won't work dynamically

That being the whole point :slight_smile:

What I was hoping to do was start off with a menu including 1-2-3 to select the secondary port to be used and probably letters for Baud (sorry, bps) rate etc. All hack stuff that I've done plenty of times on other platforms.

MarkMLl

aarg:
because it won't work dynamically

but then

HardwareSerial& mySerial = PORT;

is not a solution

but

HardwareSerial* mySerial;

mySerial = &Serial1;

mySerial->begin(9600);

Juraj:
but then

HardwareSerial& mySerial = PORT;

is not a solution

but

HardwareSerial* mySerial;

mySerial = &Serial1;

mySerial->begin(9600);

Indeed, using a pointer works. But the link I cited in my second message Easy way to select Serial, Serial1, Serial2, etc.... - Programming Questions - Arduino Forum explicitly says that references work, so I'm interested to know whether that was wrong (when written) or if there's been some subsequent change in the compiler, the compilation options, or the Arduino class library which has broken it.

MarkMLl

Nothing has "changed" or been "broken". As already mentioned, a reference must be bound to the variable it references upon creation.

Which was at least attempted by my example this morning:

HardwareSerial &mySerial = PORT;

...which is the same syntax as used by @RayLivingston in 2015.

MarkMLl

That's fine.

This is not:

if (ONLINE) {
mySerial = PORT;
mySerial.begin(BAUD);
while (! mySerial) ;
}

gfvalvo:
That's fine.

This:Is not.

Hold on, I think I've got what you're trying to say: once set, a reference can't be redefined. Correct?

In which case a reference is NBG for what I'm trying to do since the scoping couldn't be made to work, and I need to use a pointer.

MarkMLl