Leonardo - SoftwareSerial

Hi everyone,
I want to use SoftwareSerial for communication between multiple Arduino Leonardo.

I was considering pins 2,3,7 for RX because they have interrupts but on SoftwareSerial page I found that RX can only be used on 8, 9, 10, 11 which should not have interrupt but are used as "change interrupts" for the SoftwareSerial.
Can anyone tell me what am I missing?

PS: Testing on Leonardo but will use Micro for the project.

Pin change interrupts are also interrupts :wink: They just work slightly different.

Hope this helps, else you might want to elaborate a little more.

Note 1)
You are aware that software serial can not receive on more than one pin at a time?
Note 2)
There are alternative libraries; AltSoftSerial and NeoSWSerial. You can search this site for posts by -dev for the differences.

Are you aware that a Leonardo has a spare HardwareSerial port on pins 0 and 1 - performs very much better than SoftwareSerial.

...R

I will use "Hardware Serial" (0/1) for Bluetooth (HC-05 or HC-06) and I still need to connect 2 Arduinos. To one of them, I need both directions and for the second one I need only TX (no listening).

I am curious because attachInterrupt() supports CHANGE interrupt but not on those pins used by SoftwareSerial.

  1. Why do you need two Arduinos?
  2. If you do find yourself in a situation where you'd need two separate microcontrollers (very unlikely), why not use SPI or I²C instead of wasting resources on bit-banging a UART?

Abit, the reason that sterretje, Robin2 and PieterP warn you about SoftwareSerial is because it should be used as the very last option, if nothing else is possible.

The SoftwareSerial works, but it requires a lot from the Arduino board. Other code or other libraries might not work any more. The SoftwareSerial is not 100% reliable when the Arduino has other things to do.

I agree with PieterP, the best option is to upgrade to an other board.
For example the Arduino Due (it is a 3.3V board) or the good old Arduino Mega 2560 (a 5V board).

Perhaps wireless is possible ?

If you have enough pins, perhaps you could create a communication without clock, without interrupts and without baudrate. I forgot where it saw it, but I think it was with 4 wires (rx, tx, and two acknowledge lines).

The I2C bus can be used when the distance is very short. The code for the Slave is however not easy. You need help for that, because it is often done wrong.

I still want to use 3 Arduinos total because…
I need at least 1 which will be taking care of 9 RC Servos and some stuff which is not dependent on timing (Arduino time) like PWM.
Second Arduino will be taking care of 2 Stepper Motors and their limit buttons.
The last Arduino will be Master on I2C communication (as recommended here), Bluetooth (HC-05 or HC-06) and some other sensors.
And yes, they will be near each other (< 10cm).

But my main question is still there - why SoftwareSerial has different interrupts then attachInterrupt() ? And they do not overlap on any pin.

The magic word is "PCINT", that is short for "Pin Change Interrupt".

The old ATmega8 had only a few interrupt pins.
When they made the ATmega328, they decided that every pin should have an interrupt, but to fit that in the registers, they made a single interrupt and a register that tells which pin it is. That is called the PCINT.
Since then, there are two types of interrupts, the real interrupts and the PCINT.

The standard Arduino attachInterrupt() function supports only the real interrupts.
It is not easy to support both the real and the PCINT interrupts. The library enableInterrupt supports both, and that is big piece of code to support every Arduino board.

The SoftwareSerial should support both both types of interrupts, but it seems that it only supports the PCINT interrupts. That is weird.

With the ATmega32U4, which is used in the Leonardo, they didn't bother to put a PCINT on every pin.

The documentation for the SoftwareSerial is confusing, by calling it "change interrupt". The normal real interrupt pins can be used with CHANGE as well. I think it is plain wrong by calling it "change interrupt". No one use the term "change interrupt", but it is always "pin change interrupt". The datasheet of the ATmega32U4 (used in the Leonardo) is very clear by calling it always "pin change interrupt".

These are the pins of the Leonard: http://www.pighixxx.com/test/portfolio-items/leonardo/.
And the Micro: http://www.pighixxx.com/test/portfolio-items/micro/.
Do you see the real interrupts as INTx and the PCINTx interrupts ?

Using three separate microcontrollers is not the right approach.
If you need to drive more servos, get a microcontroller that has more PWM channels, or use an external servo driver.
If you need to drive a lot of steppers or read a lot of switches, use a microcontroller with more IO or use shift registers/IO expanders.

Koepel:
The magic word is “PCINT”, that is short for “Pin Change Interrupt”.

The old ATmega8 had only a few interrupt pins.
When they made the ATmega328, they decided that every pin should have an interrupt, but to fit that in the registers, they made a single interrupt and a register that tells which pin it is. That is called the PCINT.
Since then, there are two types of interrupts, the real interrupts and the PCINT.

The standard Arduino attachInterrupt() function supports only the real interrupts.
It is not easy to support both the real and the PCINT interrupts. The library enableInterrupt supports both, and that is big piece of code to support every Arduino board.

The SoftwareSerial should support both both types of interrupts, but it seems that it only supports the PCINT interrupts. That is weird.

With the ATmega32U4, which is used in the Leonardo, they didn’t bother to put a PCINT on every pin.

The documentation for the SoftwareSerial is confusing, by calling it “change interrupt”. The normal real interrupt pins can be used with CHANGE as well. I think it is plain wrong by calling it “change interrupt”. No one use the term “change interrupt”, but it is always “pin change interrupt”. The datasheet of the ATmega32U4 (used in the Leonardo) is very clear by calling it always “pin change interrupt”.

These are the pins of the Leonard: http://www.pighixxx.com/test/portfolio-items/leonardo/.
And the Micro: http://www.pighixxx.com/test/portfolio-items/micro/.
Do you see the real interrupts as INTx and the PCINTx interrupts ?

Thank you very much for the explanation and everyone for reminding me of I2C (to use it instead of SoftwareSerial).

No! That was only explanation about the PCINT.

Please use a single Arduino board and push some things out of the board into modules.
There are lot of very useful modules.
This is the board that PieterP gave a link to: Adafruit 16-Channel 12-bit PWM/Servo Driver - I2C interface [PCA9685] : ID 815 : $14.95 : Adafruit Industries, Unique & fun DIY electronics and kits.
Have a good look at it. It creates the signals in hardware. The Arduino makes the servo signals with an interrupt, which is more in software and can jitter.
The I2C I/O expanders are often used: MCP23017 - i2c 16 input/output port expander : ID 732 : $2.95 : Adafruit Industries, Unique & fun DIY electronics and kits
For stepper motors the EasyDriver modules can be used: EasyDriver - Stepper Motor Driver - ROB-12779 - SparkFun Electronics.

To make good code for an Arduino as I2C Slave is not easy. Most examples that you find are wrong.
You probably can't do that without our help.

I have been developing a system in which a master (Mega) communicates using Serial to the HardwareSerial port of a number of Atmega 328s that will each drive some servos and leds. I have arranged for the Serial line to daisy-chain from the Mega to Atmega328-A and then Atmega328-B etc. All the 328s will be listening for data from the Master but they will only reply if they receive a message with their ID number in it. The serial code in the 328s is essentially the same as the 3rd example in Serial Input Basics

I have also setup a DIY software serial Tx system on the 328s so I can temporarily connect to my laptop to read debug messages.

The daisy-chaining does require some external diodes and a pullup resistor on the serial link.

This whole system just uses in HardwareSerial port on the Mega so the others are available for other stuff.

If it would be important to have the HardwareSerial port free on the Atmega 328s then I would consider using SPI for communication with the Master.

If I had an application where an MCU needs more than serial connections (other than for debugging) I would use an MCU with extra HardwareSerial ports - such as a Mega or Leonardo or Micro (depending on how many are needed).

...R