Communicating two Arduino Nano using SoftwareSerial

I'm trying to communicate two arduino nano with Serial communication using the library SoftwareSerial but it's not working. Anyone could brieftly explain why and how can I solve it? I copy the both code here:

#include "SoftwareSerial.h"

char mystr[] = "Hello";

SoftwareSerial serial(2, 3);
  
void setup() {
  
  
  Serial.begin(9600);
  Serial.println("Master");
  serial.begin(9600);
}

void loop() {
  serial.write(mystr,5);
  serial.flush();
  Serial.println("Writing");
  delay(1000);
}
#include "SoftwareSerial.h"

char buff[10];
SoftwareSerial serial(3, 2);
  
void setup() {
  // Begin the Serial at 9600 Baud
  
  Serial.begin(9600);
  Serial.println("Slave");
  serial.begin(9600);
}

void loop() {
    serial.listen();
    while(serial.available() <= 0) {
      Serial.println("Waiting");
      yield();
      delay(1000);
    }
    Serial.println("Leido:");
    serial.readBytes(buff,5);
  
  delay(1000);
}

The hardware connection is pretty simple:

  • I connected both Arduino to USB ports for powering and to upload the firmware
  • I connected both GND pins of arduinos.
  • I connected pin 2 from one to pin 2 for the other one
  • I connected pin 3 from one to pin 3 for the other one

I read there are many software libraries: ¿Cuál es la diferencia entre todas las bibliotecas de serie de software? ¿Cuál es compatible con Arduino Nano?
But SoftwareSerial is one that I'm used to use. Do you recommend me to use other one?
I also read that you can not use two instances of software serial for reading. But I think here I'm not using two because I have an instance of SoftwareSerial and the usage of the hardware serial where I print message for debbuging on the PC (i.e. Serial.println("Esclavos")). Am I correct?

Also this is a tiny test but I would like to use it in an already existing application where:

  • The master only can use pins A5, A7 for the communication.
  • The master is already using SoftwareSerial instance (on other pins) to communicate with a sensor.
  • The master only writes and the slave only reads
    (Is for controling things actionable by the slave)

The sender is sending once per second. You should look for input more often.

void loop()
{
  if (serial.available() >= 5)
  {
    serial.readBytes(buff, 5);
    
    Serial.println("Leido:");
    Serial.write(buff, 5);
    Serial.println();
  }
  else
  {
    Serial.println("Esperando");
  }

  delay(500);
}

Welcome to the forum.

May I ask why are you doing this to yourself? SoftwareSerial is an old invention to save a penny for another microcontroller. When you sell millions of units it may be worthwhile doing this kind of tricks. For hobby use I would only recommend this for nostalgic reasons. Otherwise you can use an Arduino that has enough hardware UARTs or use another peripheral (SPI, I2C, ...).

UARTs are asynchronous and use a clock-less signal. That means the master can start a transmission at any time and there is no signal to tell the slave when the data is valid. Master and slave agree on the baudrate (well the programmer does) that tells the slave when the data is valid. There are multiple sources of error (even when using a hardware UART)

  • clock frequency tolerance on both master and slave
  • some baudrates cannot be created from a given clock frequency e.g., 16MHz / 115200
  • other interrupts (SoftwareSerial only)
  • high baudrates tend to have higher error rates

Hi, @mcros22
Welcome to the forum.
To help post your code please click this link;

Tom... :smiley: :+1: :coffee: :australia:

Hi TomGeorge! Sorry my post included literal string on spanish. I will modify it to be en english.

Thank you all for your quick responses!

I didn't included the purpose of what I'm doing or the rest of the code because I was trying to only show a minimal reproducible example of my problem.
I had an Arduino connected to a sensor, a display showing the meassurements, a buzzer for alarms, an RGB led and a analogic keyboarding. Everything is mounted on a PCB and now I want to create an extension of my device with a 4 digits 7-segments. So I was thinking about having a wire and transmit the information with UART.
I like UART because I can use any pin for it (I think) and I don't have to use the dedicated pins for I2C (for example). Because I already solded the rest of the components.

Thanks @Klaus_K I will consider other peripheral maybe. But the most important advice of this comment is: if you use UART, you should implement a checksum system!

Thanks @johnwasser for taking off one of my loops. I think the coded I originally posted worked (at least now I noticed that!). But I forgot a Serial print to show the string. The code also works even with big delays (with delay(5000) also works).

Does Master-Slave vocabulary exist in UART communication?

Master/slave is a general terminology/model for communication. UARTs have two independent communication channels that share the same baudrate. Each channel has a master/transmitter that initiates the transaction and a slave/receiver that has no control whatsoever.

At the device level UART do not have a master and a slave because both sides have a channel where they are master and the other channel, they are the slave.

1 Like

@GolamMostafa , Klaus_K answered the question but I wanted to clarify adding that I identified the devices with those names because of the role they have in the communication and the interaction I'm building over UART (using UART). In my application (upper layer of communication) the master will only write the orders ("show this measures on the 7-segments") and the slave will do it.

Notes:

  • I would also add (as Klaus_K suggested not to rely on UART!) a checksum field.

  • I was seeing other examples where both devices perform a handshake. For example with sensors, tipically a UART communication would be: "ok, give me those meassures", "here you habe the meassures + checksum".

  • I think SoftwareSerial relies on change interrupt to listen from RX, so A6 A7 pins from Arduino Nano are not allowed to be used.

As I said, the code I initially pasted was a "proof of concept" for debugging what was happening but in my real application I only had available pins A5, A7 from the "master" and pins A6, A7 from the "slave".

The UART example I wrote worked fine for using 2,3 pins but not when using those above.
I searched for other answers in the forum which clarify me that and I found this post:

Where the issue was not properly answered but redirect to this other:

Where also was not properly answer but reading the docs of SoftwareSerial you can see you need change interrupt for RX:
https://www.arduino.cc/en/Reference/SoftwareSerial

And seeing docs form PinChangeInterrupt we noticed are not available for A6/A7
https://playground.arduino.cc/Main/PinChangeInterrupt/

Seeing this post I found a confirmation:

And after trying A6 / A7 are not suitable for TX also. It's not a surprise, after all you can not make a digitalWrite on them (digitalWrite() - Arduino Reference)

Sorry for being very verbose, I think all this info could be useful for others. Also sorry for being not electronic precisely. I from CS field so I didn't know anything about what analog or digital pin precisely means, just play around with code and experiment.

I don't want debate about forum policies being a new user but my general opinion is that any forum post on the internet are informal documentation and an important source of collaborative knowledge, not only for the one who answer but for many who search in the future.
I think the first 2 cited post were not precisely answered and it would be good to be allowed to respond them even when they are old. Also I think it would be very good to incentive / enforce nicely manners in the community: a link without a comment (as we can see in the first post) it's not the best of the answers, and "why not to try it?" (as we can see in the second one) it's not an answer at all.

We have these common vocabulary:
1. SPI Port Based Serial Data Communication is synchronous and Master-Slave oriented.
2. I2C Bus Based Serial Data Communication is synchronous and Master-Slave oriented.
3. UART Port Based Serial Data Communication is asynchronous and Sender-Receiver oriented.

Why are they called Master-Slave?
1. In I2C protocol, the data exchange takes place based on ACK (acknowledgement) signal. The Sender (Master) interrogates the presence of the Receiver (Slave).

2. In SPI protocol, the clock initiating device (the Master) becomes sure that the current data exchange has taken place before sending the next byte.

3. In UART Protocol, data exchnage takes place at wish and like a radio boradcast. There is no requirement as to checking if the desired destination has received the data at all.

1 Like

If you are going to use Serial, have a look at Serial Input Basics, the way you are sending/receiving could potentially get out of synchronization.

Not really a problem in the example code, but mystr is actually 6 bytes, the last byte being the terminating null character.

1 Like