Steve
Steve

Reputation: 6424

Arduino Serial object data type, to create a variable holding a reference to a port

I'm working on a project with an ArduinoMega2560. There are multiple serial ports available, and I'd like to have a variable to hold a reference to one of them, something like this:

SerialPort port;
if (something == somethingElse)
    port = Serial;
else
    port = Serial1;

byte b = 5;
port.write(b);

However, the Arduino documentation is either limited or I haven't found the information I'm looking for. I think what I need it "What is the type for Serial, Serial1, etc?".

Upvotes: 9

Views: 9074

Answers (2)

tinman
tinman

Reputation: 6608

The underlying C++ type for the Serial objects is HardwareSerial. You can find that in the files in <arduino path>\hardware\arduino\cores\arduino. You can then use a pointers using code like this:

HardwareSerial *port;
if (something == somethingElse)
    port = &Serial;
else
    port = &Serial1;

byte b = 5;
port->write(b);

Upvotes: 14

Lundin
Lundin

Reputation: 213970

I don't know anything about Arduino, but the way this is commonly done on most microcontrollers is that you point straight at the register area of the periheral, in this case the serial port. Lets assume your MCU maps those registers like this:

// serial port 1
0x1234 SERIAL_CONTROL_REG
0x1235 SERIAL_DATA_REG
0x1236 SERIAL_STATUS_REG

// serial port 2
0x2000 SERIAL_CONTROL_REG
0x2001 SERIAL_DATA_REG
0x2002 SERIAL_STATUS_REG

You can then keep track of a the port with a pointer, like this:

#define SERIAL_PORT1 ((volatile uint8_t*)0x1234)
#define SERIAL_PORT2 ((volatile uint8_t*)0x2000)

typedef volatile uint8_t* serial_port_t;
...

serial_port_t port;

if (something == somethingElse)
    port = SERIAL_PORT1;
else
    port = SERIAL_PORT2;

This can then be expanded further so that you can use the registers just as variables, for example with macros:

#define SERIAL_CONTROL_REG(offset) (*(offset + 0))
#define SERIAL_DATA_REG(offset)    (*(offset + 1))
#define SERIAL_STATUS_REG(offset)  (*(offset + 2))

if(SERIAL_STATUS_REG(port) & some_mask)
{
  SERIAL_DATA_REG(port) = 0xAA;
}

This is how you typically write generic hardware drivers for MCU peripherals with more than one identical port on-board.

Upvotes: 0

Related Questions