Using only TX of SoftwareSerial, leaving RX pin free

You are right Nick.

I tried lowering the baud rate of SendOnlySoftwareSerial, and noticed at 28800 it works for about 3 times. After lowering it even further to 19200 then it seems to work reliably.

Do you think there is a relationship between Serial baud rate and SendOnlySoftwareSerial baud rate limit?

It is interesting why I don't have the same issue with SoftwareSerial though!

After comparing SoftwareSerial with SendOnlySoftwareSerial it seems clear that SoftwareSerial has been improved in the releases since I converted it into a "send only" version. They probably tweaked the timings so that it works more reliably. A couple of quick tests appear to show that the SendOnlySoftwareSerial version takes slightly too long for each bit, which would aggregate over longer strings.

What I think I'll have to do is rework the current SoftwareSerial (by removing the receiving part) and release that as a new version.

SendOnlySoftwareSerial timings:

SoftwareSerial timings:

Notice that the logic analyzer agrees about the framing errors. The bits are being output slightly slowly which you can see from the white dots (the sample points).

1 Like

oh, I see. Thanks Nick.

I've reworked the library from IDE 1.6.9 SoftwareSerial. It's basically just cutting out the "read" stuff. You can download it from:

http://www.gammon.com.au/Arduino/SendOnlySoftwareSerial.zip

1 Like

Awesome. It works now. Thanks again Nick.

hello, can you provide ReadOnly version of updated SoftwareSerial please ? thanks

Hi nickgammon,

I wonder why nearly all keywords (except print) and new: end, flush (what does it do?) are present in the ReceiveOnlySoftwareSerial() library. Also in the SendOnlySoftwareSerial() library I see the keyword read, but not send (?!) Thanks for helping me out, I know it is a long time ago since you posted ...

This seems to be just the library I need as I port my Basic code from the Parallax BS2pe to Arduino.

However when I load the library IDE reports no error but will not compile, Web Creator reports the following error:-

Libraries that could not be imported:
[] [jACc6oSx] 400 invalid_request: attribute "name" of response is missing and required, attribute: name, parent: response

I am a newbie on the Arduino and any guidance would be appreciated.

TIA Andy B

nickgammon:
I adapted SoftwareSerial to only have a receive function. Download library here:

http://gammon.com.au/Arduino/ReceiveOnlySoftwareSerial.zip

Thanks for contributing this.

I have a project where I need to toggle the TX output HIGH or LOW manually, and found I can't do that with SoftwareSerial. Using ReceiveOnlySoftwareSerial works for me.

Seeing that this message was from four years ago, have any updates been done to the Arduino library that might require updating in this spinoff version?

Thanks.

I doubt it. If it works, it works. Possibly some compiler warnings have been tightened up.

The good thing about embedded systems like the Arduino is, since you don't rely on DLLs, operating systems, viruses not being there, etc., you can still successfully compile with really old versions of the IDE. Or, code which worked 5 years ago will still work.

1 Like

nickgammon:
I doubt it. If it works, it works. Possibly some compiler warnings have been tightened up.

The good thing about embedded systems like the Arduino is, since you don't rely on DLLs, operating systems, viruses not being there, etc., you can still successfully compile with really old versions of the IDE. Or, code which worked 5 years ago will still work.

Thanks! I have to go through some of my old stuff and update it for the latest IDE from time to time, so I understand that part.

hey, I tried using the ReceiveOnlySoftwareSerial library for my project where I need to read from 9 ID-12 RFID readers, but I've run into a problem where it only reads from the last port i call during setup.
any hints to what i can do to fix this?

#include <ReceiveOnlySoftwareSerial.h>

ReceiveOnlySoftwareSerial RA1(50);
ReceiveOnlySoftwareSerial RA2(51);
/*  ReceiveOnlySoftwareSerial RA3(52);
  ReceiveOnlySoftwareSerial RB1(53);
  ReceiveOnlySoftwareSerial RB2(62); //A8
  ReceiveOnlySoftwareSerial RB3(63); //A9
  ReceiveOnlySoftwareSerial RC1(64); //A10
  ReceiveOnlySoftwareSerial RC2(65); //A11
  ReceiveOnlySoftwareSerial RC3(66); //A12
*/
char val = 0;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  while (!Serial) {};
  RA1.begin(9600);
  RA2.begin(9600);
  delay(50);
}

void loop() {
  // put your main code here, to run repeatedly:
  if (RA1.available() > 0) {readRA1();}

  if (RA2.available() > 0) {readRA2();}
  /*      if (RA3.available()>0) {
        readRA3();}
      if (RB1.available()>0) {
        readRB1();}
      if (RB2.available()>0) {
        readRB2();}
      if (RB3.available()>0) {
        readRB3();}
      if (RC1.available()>0) {
        readRC1();}
      if (RC2.available()>0) {
        readRC2();}
      if (RC3.available()>0) {
        readRC3();}
  */
}

void readRA1() {
  String ID = "Serial 1 reads : ";
  while (RA1.available() > 0) {
    val = RA1.read();
    ID += val;
    delay(10);
  }
  ID.remove(17, 1);
  ID.remove(30);
  if (ID.length() > 17) {
    Serial.println(ID);
  }
}
void readRA2() {
  String ID = "Serial 2 reads : ";
  while (RA2.available() > 0) {
    val = RA2.read();
    ID += val;
    delay(10);
  }
  ID.remove(17, 1);
  ID.remove(30);
  if (ID.length() > 17) {
    Serial.println(ID);
  }
}

Removing "RA2.begin(9600)"
makes it so the RA1 can read the value of the tags, but when the line is included the RA1 doesnt output any data.

also, I know its bad form to duplicate code, but I couldn't get it to work by just passing the serial as an argument to a general method.

SoftwareSerial (including the read-only version) is based on pin-change interrupts. It will never be a great success in reading multiple ports at the same time, because once a receive starts it keeps interrupts off so it can do a read with timed intervals. There is a method "ReceiveOnlySoftwareSerial::listen()" which makes the current instance be the one that is listening for input. You won't, of course, know which one to listen to at a particular moment…

You have a Mega, I presume, which can handle 4 hardware serial ports, plus you could add a SoftwareSerial one.

If you want 9 ports you are probably better off making up a board with 9 x Atmega328P on it (they are only about $3 each for the raw chip after all). You only need a couple of decoupling capacitors (per chip) and a pull-up resistor preferably for the /Reset pin. You could connect all the I2C lines together and thus they could be interrogated by a master chip (the 10th chip, say) to see if any has received any serial data in the last few milliseconds. You could program each one to have a different I2C address (store that in EEPROM). Then the master addresses each one in turn and asks if it has data.

1 Like

nickgammon:
SoftwareSerial (including the read-only version) is based on pin-change interrupts. It will never be a great success in reading multiple ports at the same time, because once a receive starts it keeps interrupts off so it can do a read with timed intervals. There is a method "ReceiveOnlySoftwareSerial::listen()" which makes the current instance be the one that is listening for input. You won't, of course, know which one to listen to at a particular moment…

You have a Mega, I presume, which can handle 4 hardware serial ports, plus you could add a SoftwareSerial one.

If you want 9 ports you are probably better off making up a board with 9 x Atmega328P on it (they are only about $3 each for the raw chip after all). You only need a couple of decoupling capacitors (per chip) and a pull-up resistor preferably for the /Reset pin. You could connect all the I2C lines together and thus they could be interrogated by a master chip (the 10th chip, say) to see if any has received any serial data in the last few milliseconds. You could program each one to have a different I2C address (store that in EEPROM). Then the master addresses each one in turn and asks if it has data.

I know the thread is old...
The idea with the eeprom is good, but i think it's bester to set the address with 5 DIs or one Analoginput with different resistors (voltage divider).

Wow this is an old thread but I was wondering if I am able to use Receive only serial alongside Send only Serial as I am using a SIM module and a GPS module in a project and I only need to receive from GPS and send to the SIM module. Thanks.

SoftwareSerial will neither know nor care what is connected to its Tx and Rx pins. Your program can use them independently.

If you have more questions I suggest you start your own Thread rather than prolong this old one.

...R