Is there a more elegant way to refer to the additional serial ports on the Mega without hard-coding them into the serial commands? I’m writing a class to support a serial LCD display and can’t find an elegant way to pass the serial port in to the constructor and then access it within the class (the way you would with a normal pin).
If I have to I can write a private method that executes a CASE statement and then call it from other methods when I need to send data, but that’s still kind of ugly. Any alternatives?
Thanks
Found one idea (but not sure it's the best):
Declare a private pointer to a HardwareSerial object in the class definition:
private:
HardwareSerial *_port;
Then set it to point to the appropriate Serial object in the constructor, and then use it for all future references to the serial port:
{
MGCFA632::MGCFA632(int serialPort0123, int baud)
//Initialize pointer to serial object we'll be using
switch(serialPort0123) {
case 0 : _port=&Serial; break;
case 1 : _port=&Serial1; break;
case 2 : _port=&Serial2; break;
case 3 : _port=&Serial3; break;
}
//Init port
_port->begin(baud);
}
Any better ideas welcome...
You can try this, it is far more complex, not tested yet, but would remove the selections from run-time ( smaller code )
//My TMP SerialSelector
template< int i_Number > class SerialSelector;
template<> struct SerialSelector< 0 >{ static inline HardwareSerial &Get( void ){ return Serial; } };
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
template<> struct SerialSelector< 1 >{ static inline HardwareSerial &Get( void ){ return Serial1; } };
template<> struct SerialSelector< 2 >{ static inline HardwareSerial &Get( void ){ return Serial2; } };
template<> struct SerialSelector< 3 >{ static inline HardwareSerial &Get( void ){ return Serial3; } };
#endif
//A rework of your class
template< int i_Number >
class MGCFA632{
public:
MGCFA632( int i_Rate = 9600 ) : _port( SerialSelector< i_Number >::Get() )
{ this->_port.begin( i_Rate ); }
protected:
private:
HardwareSerial &_port;
};
//And finally a declaration.
MGCFA632< 0 > m_Obj; //Uses Serial
MGCFA632< 1 > m_Obj; //Uses Serial1
MGCFA632< 2 > m_Obj; //Uses Serial2
MGCFA632< 3 > m_Obj; //Uses Serial3
If you can grasp the SerialSelector class you are on a win ( it is a compile time switch construct )