I've been trying to gather some debug functions inside a class. These are simple wrappers around Serial.println() that send debug messages through the UART to the PC.
But this doesn't work. I know that the class is instantiated before the setup() function is invoked, and I suspect that the Arduino libraries don't allow serial comms before the function. If I move the Serial.begin() line to the setup() function, everything works as I expect, but I'm not able to use my Debug class in other classes (i.e., I won't be able to send anything though the UART)!
To wrap it up, this means that we can't use the class constructors if we want to send through the UART. We need an explicit init() method that does all the initialisation and that it's then called from setup().
To wrap it up, this means that we can't use the class constructors if we want to send through the UART.
Correct. As to why that is the case, the constructors are called before the init() function is called. The init() function is what gets the hardware ready. It is why pinMode(), digitalRead(), digitalWrite(), and a host of other hardware-related functions can't be used in constructors, either.
On a PC, all the hardware is ready before your program is even started, so you can output stuff from the constructor. Not so on the Arduino.
The very last lines in init() turn hardware serial off:
// the bootloader connects pins 0 and 1 to the USART; disconnect them
// here so they can be used as normal digital i/o; they will be
// reconnected in Serial.begin()
#if defined(UCSRB)
UCSRB = 0;
#elif defined(UCSR0B)
UCSR0B = 0;
#endif
}
In this case you may well find that your Debug class was instantiated before the HardwareSerial instance called Serial, and thus Serial is not ready to use yet. It's not particularly that init() wasn't called.
The recommended solution of having a begin() method is the simplest way out of this.
Even on a non-Arduino platform the initialization order problem is alive and well.