Context of HardwareSerial lost when passed as a parameter

Mike Maurice

Active member
The code example at URL: https://www.pjrc.com/teensy/td_uart.html
See below.

Has a problem in that if you a add HWSERIAL.clear(); it will compile, as the HWSERIAL still has the context of hardware serial versus plain serial. A warning: plain serial has no: "clear();" Note that HWSERIAL is defined as Serial1 which is a HardwareSerial feature. It would seem wise to flag serial ports that are hardware rather than not, like in the example code.

However, if you pass "HWSERIAL" as a parameter, and accidentally declare the passed parameter as "Serial" the code will compile and appears to work until you add a function in the called code that uses a HardwareSerial function. That code will not compile and if you have never included HardwareSerial.h it could take a while before the mistake becomes apparent.

It seems to me that if you are going to use HardwareSerial functionallity, then the .h file should be included even if the resulting code will compile without it. Otherwise you may get bite later and have forgotten what the solution is.


Add: #include <HardwareSerial.h> this code example.

Code:
// set this to the hardware serial port you wish to use
#define HWSERIAL Serial1

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

void loop() {
  int incomingByte;

  if (Serial.available() > 0) {
    incomingByte = Serial.read();
    Serial.print("USB received: ");
    Serial.println(incomingByte, DEC);
    HWSERIAL.print("USB received:");
    HWSERIAL.println(incomingByte, DEC);
  }
  if (HWSERIAL.available() > 0) {
    incomingByte = HWSERIAL.read();
    Serial.print("UART received: ");
    Serial.println(incomingByte, DEC);
    HWSERIAL.print("UART received:");
    HWSERIAL.println(incomingByte, DEC);
  }
}
 
Has a problem in that if you a add HWSERIAL.clear(); it will compile, as the HWSERIAL still has the context of hardware serial versus plain serial. A warning: plain serial has no: "clear();" Note that HWSERIAL is defined as Serial1 which is a HardwareSerial feature. It would seem wise to flag serial ports that are hardware rather than not, like in the example code.

HWSERIAL is a macro defined to have the value Serial1. clear() is a member function of the HardwareSerial class, so it's valid to use HWSERIAL.clear(). I don't understand the point about function arguments. You could pass HWSERIAL to a function if the argument had the correct type.
 
Debugging an issue by someone unfamiliar with the code. Reading Egyption Hyroglyphics

HWSERIAL is a macro defined to have the value Serial1. clear() is a member function of the HardwareSerial class, so it's valid to use HWSERIAL.clear(). I don't understand the point about function arguments. You could pass HWSERIAL to a function if the argument had the correct type.

Your statement is exactly correct. And is what I stated, that if you mistakenly declare the type as Serial in the called function, it will compile as long as the function does not use any of the hardware options, like clear(). Years later if you try to add the clear it won't compile and it might take awhile before you notice where the error is.

The issue is not about how you can "make" it work, it's about being able to trouble shoot the error long afterwards, possibly by someone else who does not understand the difference between plain serial and hardwareserial.

Maintainability is the issue.
BYTW, there may be some subtle side effects, or differences between the two types, but Paul would be the one to know that. Or maybe not, even if he wrote the code. Bugs sneak in where Angels fear to tread.
 
If that happened it would simply be a bug. The two classes are closely related.Are you suggesting the functions should all be given different names? The compiler can’t divine your intent based on the names of macros. It’s just an example to show ther are similar.
 
No, I am not suggesting that the functions be given different names. Although that would be one line of attack. Frankly, my suggestion that the .h file be included is all that I think ought to be done. If nothing else, it would be a clue, to anyone working on the code years later. That there is an explicit difference, rather than an just an implied one.
 
The Arduino IDE always automatically includes Arduino.h while compiling .ino files.

Many of the header files, like HardwareSerial.h, aren't meant to be included by ordinary programs. Including Arduino.h is the intended way.
 
Paul,
I read your comment as implying that including the Arduino.h file eliminates the need to include the HardwareSerial.h file.
But, I had to include the Hardware.... h file to fix the problem where the library file did not know about HardwareSerial.
I just tested removing the .h file from the main program and then including it in the library.h file that I built.
I really don't like the way the Arduino ide builds things, I am used to a normal c,c++ compiler system and there are too many quirks with the Arduino ide, to suit me. Oh, well...
If I had not chosen programming for an occupation, I might have more sanity, remaining.
 
Back
Top