Simultaneous: USB, UART Serial, and SPI

Hey Everyone,

I want to make a device that can run USB communication (for MIDI over USB), UART Serial (for standard MIDI), and SPI (for an LCD screen) all at the same time.

  1. Can this be done on a single Arduino board?

  2. If not, would I need multiple AVRs?

  3. Any other tips would be appreciated.

Thanks all! :slight_smile:

Yes of course it can be done with a single Arduino!

Mark

Yes, a Mega, Leo, Due or Teensy 3.6 can do this. Most other 8-bit AVRs (UNO, Micro Mini, Nano) could not, because of the MIDI speeds. Tradeoffs:

  • the 8-bit Leo is a medium size, all libraries supported

  • the 8-bit Mega is larger and has more peripherals (4 UARTS [1 on USB], extra timers & PWM, etc.), all libraries supported

  • the 32-bit Due (same size as a Mega) is faster than the 8-bit Leo and Mega, but it's a discontinued product and not all libraries work

  • the 32-bit Teensy 3.6 is the smallest and fastest at 180MHz, and has plenty of RAM (256K), 1Mb FLASH, 5 UARTs and more. Not all libraries will work or have been ported, so you might needs some extra skills. There is a forum.

The first two are 5V systems and the last two are 3.3V systems.

-dev:
Yes, a Mega, Leo, Due or Teensy 3.6 can do this. Most other 8-bit AVRs (UNO, Micro, Nano) could not, because of the MIDI speeds. [/url].

Something is wrong here.

The Micro is effectively identical to the Leo, just a different shaped board; they're both 32u4 boards. So either both can do it or both can't. My understanding is that they both can. If you're talking about those color LCD screens though, you won't be happy driving one with a Leo - the black and white LCDs are great on the Leo/Micro.

And the Mega doesn't have native USB, so you have to jump through hoops to make it work as a USB MIDI device instead of a USB Serial adapter (and it can't be done at all with clones that don't use a 16u2, since you can't reprogram CH340G/CP2102/FT232/etc to act as a MIDI adapter, only a 16u2).

Teensy 3.2 is smaller than the 3.6 and is still capable of USB MIDI, UART and SPI.
All relevant libraries are fully functional.

Pete

I have the same problem.

So, if my broad is Uno, I can't run USART and SPI simultaneously?

GBCC:
I have the same problem.

So, if my broad is Uno, I can't run USART and SPI simultaneously?

SPI and USART sure - but not USB Midi too (since the only way to get that would be to reprogram the 16u2 GitHub - ddiakopoulos/hiduino: Native USB-MIDI on the Arduino , but you need the USART port to talk to the reprogrammed 16u2).

The DUE board is not discontinued, you can buy it from Arduino.cc or 3rd party manufacturers.

There are 5 U(s)ART and a native USB 2.0.

DrAzzy:
Micro…

Something is wrong here.

Oops, I have confused the Mini and the Micro on more than one occasion. :confused: Fixt above. I think I need some sort of mnemonic, perhaps visual…

ard_newbie:
The DUE board is not discontinued, you can buy it from Arduino.cc or 3rd party manufacturers.

LOL, at one time, the Arduino.cc product page said it was retired. I had to purchase a clone.

el_supremo:
All relevant libraries are fully functional.

If I had a nickel… :smiley: The hardware is quite different, so if a library is using the hardware it will not be “functional”. Many of the libraries that do use AVR hardware are also available on the Due (SPI, SoftwareSerial, etc.) because they were re-written for the Due hardware. SdFat has a configuration item to choose whether the library accesses the hardware directly (not portable) or uses the SPI library (more portable, but still required work).

Most libraries that do not use the hardware will probably work on the Due. There are C/C++ language issues that can prevent a library from working.

The hardware is quite different, so if a library is using the hardware it will not be "functional".

I don't understand that at all. The libraries for the Teensy use the Teensy hardware.

Specifically, which libraries are you saying don't work on the 3.1?
On a T3.1, USB-Midi, the Serial1 UART and SPI all work. I've used them.
[+edit] For that matter, I have used a lot of different peripherals (RTC, DS18B20, audio board, uSD cards etc.) on T3.1, T3.2, T3.5 and T3.6 without any problems with libraries.

Pete

el_supremo:
I don't understand that at all.

Try this:

The hardware [between AVR and SAM] is quite different, so if a library is using the [AVR] hardware it will not be "functional" [on the SAM hardware].

I was pointing out that the library could have the same name and methods, but the implementation has to change on the different platforms. It's basically a re-write, but the SAM interface was defined by the existing AVR library. A re-write can act differently in subtle ways.

Sometimes, the code has to be changed (ported), not because the AVR and SAM have different peripherals ("hardware"), but because the C/C++ environment is slightly different. That library would not run on the Due, but not because is was using "the hardware".

For example, a library that doesn't use any peripherals may have code that depends on sizeof(int) or pointer alignment requirements. It would not be functional, even though it compiles.

Specifically, which libraries are you saying don't work on the 3.1?

Heh heh, the ones that you really want. :wink: Seriously, though... I claim nothing specific about all libraries, just that you have to approach the term "compatible" with a healthy does of skepticism, and either try it yourself, or see what the Teensy community has reported.

I have used a lot of different peripherals (RTC, DS18B20, audio board, uSD cards etc.)

Hmm, I use the term "peripherals" to refer to the autonomous blocks within the MCU chip: UART, SPI, I2C, PWM, etc. You have been able to those "external modules" because the "peripheral" libraries were re-written for the SAM hardware: somebody re-wrote the HardwareSerial class, the SPI library, etc. The RTC library is portable enough that it could function with the SAM I2C library and the AVR I2C library.

Thanks everyone for the super helpful comments and discussion. I'm definitely in a better position now to choose a board and move forward with my project :slight_smile:

USB communication (for MIDI over USB), UART Serial (for standard MIDI), and SPI (for an LCD screen) all at the same time.

Any of the Arduino with hardware USB support (Atmega32u4, like Micro, Leonardo, and Teensy) or better (Zero, Due, Teensy 3, etc) should be able to do this. The peripherals that run USB, UART, and SPI are all separate hardware blocks that do a lot of the work, and operate independently from one another. That leaves the main CPU free to do little more than move bytes around.

(Now, there's been a bunch of discussion recently on the developers mailing list about just how poor the Arduino SPI API is when it comes to handling bulk data. If you have one of those displays that needs a full frame output to it via SPI every display interval, that may require a separate CPU to handle it.)

(Now, there's been a bunch of discussion recently on the developers mailing list about just how poor the Arduino SPI API is when it comes to handling bulk data. If you have one of those displays that needs a full frame output to it via SPI every display interval, that may require a separate CPU to handle it.)

I want to do a display of about 480 x 120 pixels on a colour TFT-LCD screen. However, I'm not doing videos or images. Only graphics and the graphics aren't moving a lot.

Do you think that's doable on a Teensy 3.2 or 3.6?

It's do able with an UNO.

Mark

I usually have problems when I want to receive serial from more than one device at the same time, because for most cases, only one pin can store messages while the arduino is busy: the RX. However, I have never had trouble sending data to several devices with the single arduino, because you can manage easily on which device it is currently busy.

Some communication protocols also, make a device that wants to send something to other device, to wait until the recieving device tells that it is ready to receive that signal. For example I2C.

The arduino mega has 4 RX pins, I would expect that one to be able to receive more than one serial input simultaneoulsy. There are also some hardware buffers that you can prepend to a softwareserial RX pin so it buffers incoming signals while the arduino is busy.

Joaquin:
only one pin can store messages while the arduino is busy

Um, pins don't store messages, and lots of things can happen while the Arduino is "busy".

If you are referring to the SoftwareSerial library, then yes, it can only listen to one RX pin at a time. It disables interrupts for the entire time a character is being received, which prevents anything else from happening. You might say the Arduino is "busy" receiving.

Joaquin:
I have never had trouble sending data to several devices with the single arduino, because you can manage easily on which device it is currently busy.

SoftwareSerial also disables interrupts for the entire time a character is being transmitted. Again, this prevents anything else from happening, including receiving a character. It cannot transmit and receive at the same time.

One of the reasons I recommend AltSoftSerial over SoftwareSerial is that it can transmit and receive at the same time. Also, it is able to capture the RX bits even though something else has disabled interrupts. This makes it very reliable for receiving, and transmitting is almost as reliable. It can only be used on two specific pins.

I also maintain NeoSWSerial, the next best choice for a software serial port. Like AltSoftSerial, it is much more efficient than SoftwareSerial because it does not disable interrupts for long periods of time. NeoSWSerial can be used on any two pins, but only at baud rates 9600, 19200 and 38400. Although it can only listen to one RX pin at a time, it can be used with AltSoftSerial to simultaneously receive from two RX pins.

Joaquin:
There are also some hardware buffers that you can prepend to a softwareserial RX pin so it buffers incoming signals while the arduino is busy.

Perhaps you are referring to an SPI/I2C UART module. The module receives characters and saves them until they are read over SPI/I2C (not a SoftwareSerial RX pin). Example: this.

Or perhaps you meant a serial port multiplexer that lets you connect multiple serial devices to one "port" (multiple pins) on the Arduino. Examples: this (no buffer) or this (buffer).

Cheers,
/dev