Serial Differences Among Arduino Boards

I’ve been writing about the USARTs and one might first think that all AVR based Arduino boards can be treated the same. However that is not the case. And since some of the example programs in the (future) book involve two boards communicating with each other, there are a large number of combinations I need to verify. So this section of the book is turning out to be very tedious.

The ATmega328P based boards like the most popular Uno or Nano have a single USART this is wired on the board to the USB-Serial interface which is used for programming and for the Serial Monitor in the IDE. This makes it inconvenient to difficult to use in an application that doesn’t involve using the USB-Serial interface. It makes this board a poor however popular choice. The Arduino Library calls this interface Serial

The ATmega32U4 based boards like the Leonardo or Micro have the USB interface as part of the microcontroller, so the single USART can be used by application programs independent of the USB interface. At the hardware level, the interface is called USART1 rather than just USART, a slight inconvenience, while the Arduino Library calls the USB interface Serial and the USART interface Serial1. The low level code for the USB interface is completely different from the USART code.

A way to get more low level compatibility with the Uno but with four USARTs, only one connected to the USB-Serial interface, is the Arduino Mega board with the ATmega2560. In the hardware, the USARTs are called 0 through 3, with 0, Serial, connecting to the USB-Serial interface, and USART1, USART2, and USART3 being freely available in applications (and called Serial1, Serial2, and Serial3.)

The more modern ATmega4809 in the Arduino Nano Every board has four USARTS, one connected to the USB-Serial interface. However the microcontroller is programmed in a different fashion that does not need the USART, so all four can be used in applications without blocking the ability to program the chip. The USARTs have more capability which means that the register interface isn’t completely compatible. And matters are complicated in that the mapping of USARTs to Arduino Serial ports isn’t straightforward:

Serial (USB-Serial Interface)USART3
Serial1 (pins D1 and D0 for TXD and RXD)USART1
(Not defined in library for Nano Every) (pins D2 and D7)USART0
(Not defined in library) (pins D6 and D3)USART2

So here we use USART3 for the USB-Serial interface, not USART0!

Anyway, I think I’ve got it all straightened out and have single example programs that work across the Uno, Mega, Leonardo, Nano Every, and other Arduino boards based on the same AVR microcontrollers. Like the other examples all the driver functions are non-blocking, provide callback function calls on completion, and don’t allocate buffer memory.