Single line SW serial half duplex

Hello guys.

i am reading data from an ECU via single line UART and every 50 frames i jeed to send some bytes on the same line.

Using a 1k resistor between SW serial pins (d8,d9) works but i was wondering if this can be implemented by software using d8 only, such as:

define sw serial d8 as rx
read strings
define sw serial d8 as tx
transmit some bytes
define sw serial d8 as rx
read strings

any good way to do this?
an example would be appreciated.
thanks.

The answer is: Yes

Setting the RX and TX pins is done in the constructor.
You have to call the constructor to change it.

You also have to keep the line high when it is idle. It should not float while changing its function.
As you can see here, the SoftwareSerial::end() turns the pins into inputs:
Here: https://github.com/PaulStoffregen/SoftwareSerial/blob/master/SoftwareSerial.cpp#L185
and here: https://github.com/PaulStoffregen/SoftwareSerial/blob/master/SoftwareSerial.cpp#L649

I think you need a pullup resistor to keep the line high, or else the receiver might see a start-bit when the line is low by noise.

You can use new and delete with a pointer to a SoftwareSerial object in global memory.
Or you can let the C++ language do that for you by using the constructor in a function. But then it gets deleted as soon as you leave the function.

SoftwareSerial *pMySW;

void setup()
{
   // default: RX
  pMySW = new SoftwareSerial( 8, -1);  // does -1 disable the TX ? I'm not sure.
  pMySW->begin( 9600);
}

void loop()
{
  // switch to TX
  pMySW->end();   // nicely close the serial port
  delete pMySW;    // remove the object
  pMySW = new SoftwareSerial( -1, 8);  // does -1 disable the RX ? I'm not sure.
  pMySW->begin( 9600);
  ...
}

The destructor calls the .end() function. A delete on a object should automatically call the .end() function. I think that is correctly implemented, so you don't have to call .end() in the sketch.

Perhaps the pin -1 is only for the SoftwareSerial on the ESP8266. You could assign a dummy pin that you don't use.

Have you tried AltSoftSerial() : https://www.pjrc.com/teensy/td_libs_AltSoftSerial.html

The pins are set in the constructor, so that the .begin() function is compatible with the normal Serial library. I think that is the only reason. Perhaps there is a easier solution out there.

Which Arduino board do you use ?

im using pro mini.
328p 5V 16MHz.

im not sure either if -1 pin disables anything. a dummy may work.
regarding the pull up resistor perhaps set pin mode to INPUTPULLUP whenever not used?

because if this solution needs a hw resistor, i might as well use the old way (resistor between tx/rx)

Deleting a Serial object calls the end() function and that releases the pin. Also the SoftwareSerial and the AltSoftSerial do that, it is a nice way to close everything.
If you do a pinMode( ... , INPUT_PULLUP) after that, then the signal might be low for a short time by the noise and a low is seen as a start-bit by the receiver, even if it is just a low glitch.

If you need two resistors and a dummy (hardware) pin, then you might indeed use the old way.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.