Open Source MULTIUART Project, Add more UART Serial Ports to your projects

If you're a fan of electronics then you like me will often find it annoying on the lack of hardware serial ports on modern devices. Many modules like the Wifi ESP8266 and the Bluetooth HC-06 are available for peanuts but they each require a UART based serial peripheral on your controller to work effectively. In fact a huge range of external electronics can be added to your system via a serial UART connection: GPS, GSM (mobile phone), RFID, RS232, LIN, Ethernet, Zigbee, Modbus, DMX, 4D systems graphical LCDs to name a few more.

Most modern microcontrollers and devices like the Raspberry Pi have at least one serial UART peripheral so you can do a lot with these devices. However now and then you need to combine several communications style modules together into a single design. A recent project I undertook was a mobile alarm system which used Bluetooth proximity to arm / disarm the system, GPS to track the location, Accelerometer to track movement and GSM based SMS messages to inform the owner where their item is.

The Arduino Mega 2560 offers four serial UART peripherals but what if that is not enough or you need something more affordable for mass production. To move to a different chip may mean rewriting your entire code so is there an easier way?

These modern microcontrollers commonly also feature a peripheral named SPI which is typically a lot faster then a UART based serial peripheral and can be used to talk to multiple devices by use of individual chip select signals from the controller. If the controller does not have an SPI peripheral then it can simply be driven using a bit banged software approach using standard I/O pins with no major downfalls. By using the SPI interface and my design you can communicate with up to four serial UART peripherals simultaneously.

Here is my open source project to create a SPI to 4 UART bridge code name MULTIUART or SPI2UART.
Instructables - SPI-to-4-x-UART-Bridge-MULTIUART

I have now created an Arduino library to drive the hardware.
Github - MULTIUART

Included in the library is a test program I created to test the MULTIUART boards using an Arduino Uno and transmitting data back to the PC using the serial library.

If you're interested then a small number of boards are currently available on sale on eBay.

Many thanks and enjoy!

So, that's a 16-bit PIC on a board, acting like a peripheral to an 8-bit AVR? Alrighty then.

If your you're a fan...

Fixt.

The Arduino Mega 2560 offers two four serial UART peripherals

Fixt.

I have now created an Arduino library

You should find a way to leverage the Stream class (which leverages the Print class). I would suggest a grouping class that contains an array of 4 instances derived from Stream. Those instances could be used by any code or library that expects the Stream (or Print)class. It would look just like the current HardwareSerial usage:

class MultiUART;

class MultiUARTPort : public Stream
{
    uint8_t    id;
    MultiUART *group;
    friend class MultiUART;

  public:
    // Serial port controls
    begin( uint32_t baud ... );
         ...

    // Override all pure virtual methods of Print and Stream...
    virtual size_t write( uint8_t c ) { group->TransmitByte( id, c ); return 1; }
    virtual int available() { return group->CheckRx( id ); }
         ...
};

class MultiUART
{
    MultiUARTPort port[4];
  public:

    MultiUART()
      {
        for (uint8_t i=0; i<NUM_PORTS; i++) {
          port[i].id = i;
          port.group = this;
        }
      }

    MultiUARTPort& operator []( uint8_t i ) { return port[i]; }
      ...
};

MultiUART mu;

void setup()
{
  Serial.begin( 9600 );
  mu[0].begin( 9600 );
}

void loop()
{
  if (mu[0].available())
    Serial.write( mu[0].read() );
}

You should also find a way to get rid of the 50us delays. The above loop will delay 250us for each character. This will limit the baud rate to 38400.

I would also recommend using SPI transactions to avoid conflicts with other SPI devices, and perhaps concurrent transfers (reading and writing with one transaction).

Cheers,
/dev

Some great info there, thanks.

I'll have a play with the library and see if I can improve things as per your suggestions.

You should also find a way to get rid of the 50us delays. The above loop will delay 250us for each character. This will limit the baud rate to 38400.

It will limit the throughput to roughly 4800 bytes per second (38400 / 8) but the baud will still be 115200 not 38400.

The delays can probably be brought down a bit without causing any major headache. They were just in there for a belt and braces approach.

RowlandTechnology:
By using the SPI interface and my design you can communicate with up to four serial UART peripherals simultaneously.

Here is my open source project to create a SPI to 4 UART bridge code name MULTIUART or SPI2UART.
Instructables - SPI-to-4-x-UART-Bridge-MULTIUART

I have now created an Arduino library to drive the hardware.
Github - MULTIUART

Included in the library is a test program I created to test the MULTIUART boards using an Arduino Uno and transmitting data back to the PC using the serial library.

If you're interested then a small number of boards are currently available on sale on eBay.

Many thanks and enjoy!

Hi,
I have some problem to get datas over UART1 and UART 4 except UART 2 and UART 3 works (with SPI2UART)..

Here is my source code:

#include <SPI.h>
#include <MULTIUART.h>
#include <SoftwareSerial.h>

MULTIUART multiuart(8); //CS imamo na 8 pinu
SoftwareSerial mySerial(2, 3); // RX, TX

char LENGTH;
char Str1[14];

void setup() {
  multiuart.initialise(SPI_CLOCK_DIV64);  // set up the SPI and MultiUART Library
  Serial.begin(115200);              
  mySerial.begin(115200);

  multiuart.SetBaud(0, 7);   
  multiuart.SetBaud(1, 7);    
  multiuart.SetBaud(2, 7);    
  multiuart.SetBaud(3, 7);    
}



void loop() {
  
  
  Serial.print("UART 0: ");
  
  LENGTH = multiuart.CheckRx(0);  //Check UART 0 for incoming data
  if (LENGTH > 0)
  {
    multiuart.ReceiveString(Str1, 0, LENGTH); //Collect incoming data from buffer
    Serial.print(Str1);     //Forward data to PC
  }

  Serial.print("UART 1: ");
  LENGTH = multiuart.CheckRx(1);  //Check UART 1 for incoming data
  if (LENGTH > 0)
  {
    multiuart.ReceiveString(Str1, 1, LENGTH); //Collect incoming data from buffer
    Serial.print(Str1);     //Forward data to PC
  }

  Serial.print("UART 2: ");
  LENGTH = multiuart.CheckRx(2);  //Check UART 2 for incoming data
  if (LENGTH > 0)
  {
    multiuart.ReceiveString(Str1, 2, LENGTH); //Collect incoming data from buffer
    Serial.println(Str1);     //Forward data to PC
  }
  
  Serial.print("UART 3: ");
  LENGTH = multiuart.CheckRx(3);  //Check UART 3 for incoming data
  if (LENGTH > 0)
  {
    multiuart.ReceiveString(Str1, 3, LENGTH); //Collect incoming data from buffer
    Serial.println(Str1);     //Forward data to PC
  }

  Serial.print("\n");
  mySerial.write("Peter10101");
  delay(50);      
}

on UART 1,3,4 I don't receive any datas

on UART 2 I recevie "string" Peter10101 which is ok...

Is something wrong with my code or is something other?

If I slow down the baud rate to 19200 then
I can receive

on UART 0: NOT OK!

UART 0: €„…„„UART 1: UART 2: UART 3:

on UART 1: OK!

UART 0: UART 1: Peter10101 UART 2: UART 3:

on UART 2: OK!

UART 0: UART 1: UART 2: Peter10101 UART 3:

on UART 3: OK!

UART 0: UART 1: UART 2: UART 3: Peter10101

I don't know why I can't get data on UART 0 ?!? or why the received datas are corrupted..