I notice quite a few sketches use this just after Serial.begin()
void setup(){
Serial.begin(115200); // USB serial interrupts already in place
while (!Serial){};
Serial.println("Hello");
}
I've been playing in Arduino-land for over 10 years and have a wide variety of Arduino boards and man, many skethes, but I've never used while (!Serial).
As far as I know this has not caused me any problems. I understand what this command aims to do, but is it really important / necessary?
It is needed only if you have an Arduino board that uses the serial port to communicate directly with the USB on your computer.
If it is in and you don't need it then the code will in effect skip over it. If it is not there and you do need it then there will be a delay in starting up and you are likely to miss any serial communication you get in the first few seconds.
The Arduino Micro has a USB-AVR that may not be USB initialized when setup() runs and take a little bit to begin serial.
Before the Micro was released, we didn't have that line.
On the R4 however it is not recommended at all, and often causes problems when I have used it. At best it will not cause problems and at worst it will actually prevent ser serial port from starting up. The state of the firmware on the R4 is a bit flaky to say the least. A simple one second delay after the serial begin call always works for me.
If the bool operator on the HardwareSerial class is overloaded and just returns true as for the common avr based (UNO, Nano, Mega) based arduino then I’m saying it’s likely the compiler will generate for your while (!Serial) {}
The equivalent (inlining the function) while (!true) {}
And the optimizer knows that !true is false and thus the while will never run so this operation having no side effect and being useless will just be thrown away and not make it in your binary code at all for this target platform. It’s really just like if you had not written it in the first place
So it’s a good common practice to have it anyway so that you get portable code for platforms needing it.
Yes the Serial instance does exist when you hit the setup() function.
for example for avr, the Serial ports are conditionally declared in the HardwareSerial.h class
and being instantiated at the end of the HardwareSerial0 class definition for Serial
(the others being in HardwareSerial1.cpp, HardwareSerial2.cpp and HardwareSerial3.cpp)
so it's technically OK to call a function on that instance.
In the case of a CDC implementation, for example on a SAMD platform, waiting for the Serial line to become available before initialising it seems to make sense (the baud rate is irrelevant) and is taken into account in the operator bool
in Object Oriented programming instances and object are often synonymous. You could say Serial is an object (pretty generic then), or qualify this a bit more and say it's an instance of the HardwareSerial class.
basically instantiating a class gives you an object (and by extension of the verb, also an instance).
Serial contains a bunch of “virtual methods” that cannot be detected to be unused.
It’s annoying, and an example of how C++ features can cause unexpected bloat.
On the boards with native USB, the bool operator overload which is called when you do while (!Serial) ; or while (!SerialUSB); indicates whether or not the USB CDC serial connection is open and on other boards it just returns true as already discussed.
have a look at what begin() does when you are using CDC, Serial_ is the subclass of HardwareSerial
and this is the begin() content
âžś We can't say this is where all the mysterious set up of the Serial line (SerialUSB) happens....
Perhaps, you meant
Serial contains a bunch of “virtual methods” that can{not} be detected to be unused{, and therefore cannot be excluded by the compiler}.
It’s annoying, and an example of how C++ features can cause unexpected bloat.
You may consider that to be just "wordsmithing", but I think it more clearly expresses the problem being described?