I'm trying to figure out if I can send and receive serial data on ports 23 and 25 of the Arduino Mega 2560, and I'm very confused by seemingly contradictory information on the Arduino website. From the SoftwareSerial page:

Not all pins on the Mega and Mega 2560 support change interrupts, so only the following can be used for RX: 10, 11, 12, 13, 50, 51, 52, 53, 62, 63, 64, 65, 66, 67, 68, 69

On the Arduino Mega page:

A SoftwareSerial library allows for serial communication on any of the Mega2560's digital pins.

The pins it specifies as compatible with interrupts are:

2 (interrupt 0), 3 (interrupt 1), 18 (interrupt 5), 19 (interrupt 4), 20 (interrupt 3), and 21 (interrupt 2).

and have no overlap with the pins that the first quote. These seem completely contradictory. Am I missing something? Can I use serial on ports 23 and 25?

  • 1
    \$\begingroup\$ If you have the board, it might be simplest to try it. Or check the library source code and work out what it would do in various cases - it's possible it has a polling option in addition to an interrupt one, though that would be rather expensive. Also, if I recall, the Arduino MEGA's processor has additional hardware serial ports, so you might not need software serial. \$\endgroup\$ Feb 27, 2013 at 15:16

2 Answers 2


The reason behind the discrepancy in documentation is that the documentation refers to two different versions of the software and it is out of date.

In Arduino version 0023 and below, SoftSerial was a very basic library written by David Mellis. It just uses millis(), digitalRead/Write and blocks when sending or receiving. This means it can work on any pin. However, it works badly and slowly. I would strongly recommend avoiding this.

In Arduino version 1 and above, SoftSerial was replaced with NewSoftSerial. This uses interrupts and timers, and is far more efficient. This limits the pins that it can work on though to ones that have pin change interrupts.

With respect to the contradictory pins; there are two types of interrupt pin on the ATmega2560 - external interrupts (INT7 - INT0) and pin change interrupts (PCINT23 - PCINT0). External interrupts are more complex and can be configured to trigger on rising and/or falling edges. Pin change interrupts trigger as long as any change occurs.

The long list of:

10, 11, 12, 13, 50, 51, 52, 53, 62, 63, 64, 65, 66, 67, 68, 69

are pin change interrupts which are what are required for NewSoftSerial (called SoftSerial in Arduino 1.0 and above).

The short list of:

2 (interrupt 0), 3 (interrupt 1), 18 (interrupt 5), 19 (interrupt 4), 20 (interrupt 3), and 21 (interrupt 2).

are external interrupts.

You can see these on the pin mapping diagram for the ATmega2560 (which is correct, AFAIK). Function of the interrupt pins is described on page 105 onwards of the datasheet.

There are 4 hardware USARTs on the ATmega2560. These are far easier to use and far more efficient than any software serial library. They are on pins 0/1, 14/15, 16/17, 18/19.

There is also AltSoftSerial which is better than NewSoftSerial in terms of performance, but is even more limited in pin choice.

At this stage, I have to ask "why those pins?". Could the design not change?

  • \$\begingroup\$ Great answer! We didn't realize a peripheral needed serial and not just normal digital, and so our PCB has it connected to those pins... We may have to use jumpers then because we can't change the PCB. \$\endgroup\$
    – 0xFE
    Feb 28, 2013 at 0:37
  • \$\begingroup\$ You have three options really. Firstly, use old SoftSerial. It can work, but will inflict software pain on you. Secondly, write your own version of SoftSerial. You'd be more aware of limitations this way. Thirdly, modify the circuit and use the best of hardware USART or NewSoftSerial. I'd chose this one! \$\endgroup\$ Feb 28, 2013 at 0:39
  • \$\begingroup\$ What would be the benefit of writing my own version of SoftSerial? \$\endgroup\$
    – 0xFE
    Feb 28, 2013 at 0:50
  • \$\begingroup\$ As you'd be trying to emulate the old SoftSerial (works with any pin), you'd become very aware of the limitations of that method, and the rest of your code could allow for it. \$\endgroup\$ Feb 28, 2013 at 0:53

You stumbled upon the difference between hardware serial / UART and serial emulated in software.

hardware serial

The following pins support hardware serial / UART. It implies little processor overhead as the hardware takes care of the tough work.

Serial: 0 (RX) and 1 (TX); Serial 1: 19 (RX) and 18 (TX); Serial 2: 17 (RX) and 16 (TX); Serial 3: 15 (RX) and 14 (TX). Used to receive (RX) and transmit (TX) TTL serial data. Pins 0 and 1 are also connected to the corresponding pins of the ATmega16U2 USB-to-TTL Serial chip.

Use the commands as found on this page: http://arduino.cc/en/Reference/Serial

software serial

The SoftwareSerial library you refer to does not use the integrated UART hardware, instead it uses software to emulate the serial port. It uses various timing mechanisms (like interrupts) and bit banging (directly driving pins low/high) to act as if it were a real UART.

Not all pins on the Mega and Mega 2560 support change interrupts, so only the following can be used for RX: 10, 11, 12, 13, 50, 51, 52, 53, 62, 63, 64, 65, 66, 67, 68, 69

Use the commands as found on this page: http://www.arduino.cc/en/Reference/SoftwareSerial

in conclusion

Without knowing your exact requirements, I'd say first use the hardware UART's (because of lower CPU overhead) and if you run out of those, use SoftwareSerial.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.