Using only TX of SoftwareSerial, leaving RX pin free

Hi everyone.

I'm using SparkFun's OpenLog, a microSD card data-logger to which you communicate through serial. The only connection needed is Arduino TX to OpenLog RX, because the OpenLog handles the rest.

I have run out of pins in the project I'm using, and have exactly one digital I/O pin left to use for the OpenLog. I'm using SoftwareSerial. However, when I declare an instance of SoftwareSerial, I need to give it 2 pins: RX and TX. I only need TX, and every other pin on my Arduino (Nano) is currently being used for output.

Will something go wrong if I declare SoftwareSerial with an RX pin that's actually being used elsewhere for output? Can I, instead, declare SoftwareSerial with a pin that doesn't exist - say, 100? Any other options?

Thanks for any advice!

1 Like

I wouldn't use pin 100 or anything like that, because it tries to use that pin, eg. here:

void SoftwareSerial::setRX(uint8_t rx)
{
  pinMode(rx, INPUT);
  if (!_inverse_logic)
    digitalWrite(rx, HIGH);  // pullup for normal logic!
  _receivePin = rx;
  _receiveBitMask = digitalPinToBitMask(rx);
  uint8_t port = digitalPinToPort(rx);
  _receivePortRegister = portInputRegister(port);
}

They don't seem to have allowed for no Rx at all, so you might be better off taking the class, and making a "send-only" version by removing the references to the reading part. I'll take a stab at it, shouldn't take long.

1 Like

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

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

Example of use:

#include <SendOnlySoftwareSerial.h>

SendOnlySoftwareSerial mySerial (3);  // Tx pin

void setup ()
  {
  mySerial.begin(115200);
  }
 
int i;

void loop ()
{
  mySerial.print ("test: ");
  mySerial.println (i++);
  delay (100);
}
2 Likes

Thanks so much, that's brilliant, I appreciate it!

1 Like

Fantastic! Thank you very much.

Glenndrives

1 Like

You can set RX to 0.

SoftwareSerial Serial2 = SoftwareSerial(0, 4);    //!< RX is 0. Pin 4 is TX

This works because there is no pin 0.

Mushfiq

1 Like

Yes there is a pin 0. Take a look at your board. It's labelled Rx (and 0).

1 Like

Thanks Nick!

Just what I was looking for. :slight_smile:

in my case I want to release TX pin
how I can change the library in order to implement this method?
more info:
http://forum.arduino.cc/index.php?topic=227760.0

1 Like

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

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

Example of use:

#include <ReceiveOnlySoftwareSerial.h>

ReceiveOnlySoftwareSerial mySerial(10); // RX

void setup()  
{
  Serial.begin(115200);
  while (!Serial) { }  // wait for Serial to become available

  // set the data rate for the ReceiveOnlySoftwareSerial port
  mySerial.begin(9600);
}

void loop() // run over and over
{
  // echo from software serial to hardware serial
  if (mySerial.available())
    Serial.write(mySerial.read());
}

This could be handy for situations (like reading from a GPS) where you don't need to write, and thus you can save a few hundred bytes of program code.

1 Like

had to add a line in your send only cpp file to make it work with micronuclius/digispark cores running at 16.5MHz.
see Software Serial doesn't recognize 16.5Mhz

thank you nick, again

Hi Nick !

I want to ask question,
I'm using Arduino UNO, and i want to reduce I/O pin..
Is it possible to combine your library and SoftwareSerial library?
because when i tried your library alone thats perfect !

right now i try to combine your library to SoftwareSerial in order to retrieve data serial from my ID-12 (RFID) and send it to other device using Serial too..

this is my code

#include <SoftwareSerial.h>
#include <ReceiveOnlySoftwareSerial.h>

// DEFINE
// ======== SERIAL =============
// == RFID
#define RXID  8
ReceiveOnlySoftwareSerial RFID (RXID);

// == RS 485
#define RX45           2
#define TX45           3
#define SerialControl  7
#define Transmit       HIGH
#define Receive        LOW
SoftwareSerial toSlave (RX45, TX45);

void setup(){
}

void loop(){
}

and these the error message

 This report would have more information with
  "Show verbose output during compilation"
  enabled in File > Preferences.
Arduino: 1.0.6 (Windows 7), Board: "Arduino Uno"
ReceiveOnlySoftwareSerial\ReceiveOnlySoftwareSerial.cpp.o: In function `__vector_3':
--------------\Arduino\libraries\ReceiveOnlySoftwareSerial/ReceiveOnlySoftwareSerial.cpp:300: multiple definition of `__vector_3'
SoftwareSerial\SoftwareSerial.cpp.o:--------.cpp:305: first defined here
ReceiveOnlySoftwareSerial\ReceiveOnlySoftwareSerial.cpp.o: In function `__vector_4':
---------------\Arduino\libraries\ReceiveOnlySoftwareSerial/ReceiveOnlySoftwareSerial.cpp:307: multiple definition of `__vector_4'
SoftwareSerial\SoftwareSerial.cpp.o:-------\Arduino\libraries\SoftwareSerial/SoftwareSerial.cpp:312: first defined here
ReceiveOnlySoftwareSerial\ReceiveOnlySoftwareSerial.cpp.o: In function `__vector_5':
---------------\Arduino\libraries\ReceiveOnlySoftwareSerial/ReceiveOnlySoftwareSerial.cpp:314: multiple definition of `__vector_5'
SoftwareSerial\SoftwareSerial.cpp.o:-------------\Arduino\libraries\SoftwareSerial/SoftwareSerial.cpp:319: first defined here

Thanks ~ :slight_smile:

1 Like

Once you have SoftwareSerial you can have multiple instances of it (I think), so you don't need to combine the libraries.

1 Like

Hi Nick ! Thanks for your reply :slight_smile:

Ya you were right, SoftwareSerial can allow us to have Serial Port programming more than 1..I've tried it with two Serial port. And it works.. But I haven't tried it for more than two yet.
Ah.. ok.. I understand.. I just tried to minimize my I/O pin so I try to combine it with your library.

Thanks Nick ~

1 Like

Quite possibly the pin you chose. Please post your code. Also state which Arduino you have.

How to use this forum

1 Like

Hi Nick
Is it possible to use Receive only software serial for multiple pins (To read data from multiple devices).
I am using seven RFID readers in my project. What is the best way to read from all these devices

Ah, I suppose you could make 7 instances, but I warn you that because it turns interrupts off while receiving it would only successfully read from one at a time.

1 Like

Just to add.. You can always call Software serial with the same pin value for both Tx and Rx and just use it for only one function.

Hi Nick,
Your library works perfectly in Arduino IDE. In fact when I imported my project in Atmel Studio 7 it compiled with no errors.
However, once I uploaded the code onto ATmega328p using Atmel ICE programmer, as soon as a message is printed out, the terminal breaks!!!
In my case I am using CoolTerm on Windows 8.1. CoolTerm breaks with error message "104: Framing Error". I don't experience the same problem using SoftwareSerial library though.
What's my mistake?
Here is my code:

/*Begining of Auto generated code by Atmel studio */
#include <Arduino.h>

/*End of auto generated code by Atmel studio */

#include <SendOnlySoftwareSerial.h>
//Beginning of Auto generated function prototypes by Atmel Studio
//End of Auto generated function prototypes by Atmel Studio


// Connect Arduino pin 10 to RX of usb-serial device
uint8_t myTX = 10;
SendOnlySoftwareSerial ss(myTX);


void setup() {
 Serial.begin(57600);
 ss.begin(57600);
 ss.println("Start");
}

void loop() {

}

Thanks

I can't see any "mistake". You could try using a lower baud rate. Software-generated serial is rather dependent on timing loops.

1 Like