Can Arduino handle multiple serial SPI, I2C, SoftwareSerial at one sketch?

Hi everyone :slight_smile: !

Sorry if I ask a silly question or maybe its already posted long time ago..
I'm using is Arduino UNO rev3 and then I want to ask "Is it possible to Arduino handle serial communication SPI, I2C, and SoftwareSerial at one sketch ?"

I've already testing arduino using SoftwareSerial to listening 3 port using " .listen() " , but I dont know how to change "listening" process from SoftwareSerial to SPI then I2C and so on..
My program doesn't require to run all Serial communication at once in the same time..It's just like a sequence. First, I want to get data from SoftwareSerial, then read RTC from I2C, and so on..

Thanks !

Serial: The Arduino UNO only has one hardware serial port on Pins 0 and 1. It is connected to the USB-to-Serial chip so you can't use it to talk to anything else if you are using the USB cable to talk to a PC. The Leonardo has two: Serial goes to USB and Serial1 goes to Pins 0 and 1. The MEGA 2560 has four: Serial goes to USB on Pins 0 and 1. Serial1, Serial2, and Serial3 use other pins and are available for your use.

SoftwareSerial: You can create multiple instances but only one will be listening for input at a time. Characters arriving from other instance are ignored. You can send to all of them.

I2C: Each slave device has an address. They all share the bus. You can talk to them in any order. Since the slaves only send when prompted there is no conflict.

SPI: Each slave has a separate SlaveSelect pin. Only one can be selected (SlaveSelect = LOW) at a time. You can use any digital pin as a SlaveSelect output and you can use external chips to expand the number of digital outputs. That makes the number of usable SPI devices almost unlimited.

Hi johnwasser :slight_smile: !

Thanks for replying my question…
So I guess “listening” process are only for SoftwareSerial library?
And i can use other serial communication like SPI and I2C with no problem right?

Thanks johnwasser :slight_smile:

SPI and I2C and hardware Serial can work all together.
The SoftwareSerial has a big impact for timing and interrupts. You can avoid that with the Arduino Leonardo which has a spare hardware Serial port, or the Arduino Mega 2560 which has 3 spare hardware Serial ports.

The AltSoftSerial has less impact for timing and interrupts, but uses a timer and specific pins : http://www.pjrc.com/teensy/td_libs_AltSoftSerial.html

When there is not many others things to do when you use SoftwareSerial, it is no problem. Perhaps you can use the undocumented SoftwareSerial.end() to stop listening when ready with the SoftwareSerial communication.
https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/libraries/SoftwareSerial/SoftwareSerial.cpp.
I don't know how to restart after "end()", I assume "begin()" is needed.

Peter_n:
The SoftwareSerial has a big impact for timing and interrupts. You can avoid that with the Arduino Leonardo which has a spare hardware Serial port, or the Arduino Mega 2560 which has 3 spare hardware Serial ports.

The AltSoftSerial has less impact for timing and interrupts, but uses a timer and specific pins : http://www.pjrc.com/teensy/td_libs_AltSoftSerial.html

Because of the limitations of SoftwareSerial and the hardware requirements of AltSoftSerial, I wrote a timer0 based software serial library. Instead of delay loops with interrupts disabled, it reads timer0, which it assumes is in the default mode of 1 tick per 4us, to determine the incoming bits. Compared to SoftwareSerial which hogs more than 95% of the processor bandwidth, the library I wrote spends only slightly more time in its RX ISR than AltSoftSerial. It is limited to 9600, 19200 and 38400 baud, it isn’t full duplex and it isn’t as robust as AltSoftSerial. But it doesn’t use many system resources (just a pin change interrupt) and it has a smaller footprint, something that was very important for my application.

gSoftSerial.cpp (9.84 KB)

gSoftSerial.h (1.24 KB)

Peter_n:
When there is not many others things to do when you use SoftwareSerial, it is no problem. Perhaps you can use the undocumented SoftwareSerial.end() to stop listening when ready with the SoftwareSerial communication.
https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/libraries/SoftwareSerial/SoftwareSerial.cpp.
I don't know how to restart after "end()", I assume "begin()" is needed.

jboyton:
Because of the limitations of SoftwareSerial and the hardware requirements of AltSoftSerial, I wrote a timer0 based software serial library. Instead of delay loops with interrupts disabled, it reads timer0, which it assumes is in the default mode of 1 tick per 4us, to determine the incoming bits. Compared to SoftwareSerial which hogs more than 95% of the processor bandwidth, the library I wrote spends only slightly more time in its RX ISR than AltSoftSerial. It is limited to 9600, 19200 and 38400 baud, it isn't full duplex and it isn't as robust as AltSoftSerial. But it doesn't use many system resources (just a pin change interrupt) and it has a smaller footprint, something that was very important for my application.

Thanks to Peter_n and jboyton !
You are very helpful to me.. thanks for your explanation and support !
And I'll try your library jboyton \m/
God bless you all :slight_smile: ~

Thanks !