Go Down

Topic: Software Serial with Half Duplex - For a Shared Serial Bus (Read 11040 times) previous topic - next topic


Jul 16, 2012, 11:02 pm Last Edit: Jul 17, 2012, 12:38 am by steddyrobots Reason: 1
Hey Everyone,
I needed to make use of Half Duplex Serial for a project, so I adapted the Software Serial Library to allow for it. You can find it on github:


The value of Half Duplex is that you can daisy-chain a bunch of devices to the same serial line, and communicate with them all. It doesn't however do any error checking or flow control like i2c, so you have to handle that yourself. The robotis AX-12 motors make use of Half-Duplex Serial for example, and it is often used with RS485.

With the standard SoftwareSerial library the TX line is always set as an Output, as you'd expect. With the SoftwareSerialWithHalfDuplex library (sorry for the long name!), by default the TX line works exactly the same as the original, but by adding a couple of optional arguments at instantiation, the TX line can instead be set as an Input, pulled-high. Only when a write/print command is called, does the TX line flip to an Output until the byte is sent, and then resets to an Input. As such, you can make the TX and RX line the same, because transmission will be disallowed while receiving and vice-versa.

Only a few modifications of the SoftwareSerial library were necessary. I'm sure it could be written more efficiently, but I wanted it to be as close to the original as possible to reduce maintenance (and hopefully to be considered for merging... :D ).

This is my first attempt at it, so any feedback or help is appreciated. Also it's my first time using github so let me know if something's amiss. It's been tested a little bit and seems to work pretty well up to 57600. I've used it to communicate with several Arduinos at once, and also with an AX-12 motor. The Half-Duplex option probably won't work As Is if you need to invert the data, which means that more work is required if you want RS485 communication.



Sep 04, 2013, 10:34 pm Last Edit: Sep 04, 2013, 11:05 pm by phatpaul Reason: 1
Hi Nick,
Nice work.  I need exactly this functionality.
Atmel is using what they call "single-wire interface" on several new products now:

Atmel's "Single-wire Software UART" (bitbang)

ATAVRSB201 (ATmega16HVA)

Atmel ATSHA204

Atmel AVR947: Single-Wire Bootloader

Another option is just tie TX and RX together with a 4.7k resistor (and use existing Hardware or Software serial library)
Code: [Select]

-----     4.7k
TX  |----VVVV---|
RX  |-----------+-----> 1-wire UART bus

(the other devices on the bus must have open-drain outputs, and no additional pull-up)

It works for me from a PC with a USB-to-serial (FTDI 232R) ic.  I was going to try it on the Arduino, but came across this post.

A  potential issue may be that the UART will recieve the same data that is transmitted.  It can be discarded, but I would prefer to force the reciever off while transmitting (half duplex).  I'm trying to figure out if the existing SoftwareSerial library is half-duplex.


This library is a very good idea. It would allow for many new protocols, besides the overly used  I2C.
I tried it with pro mini's and it works, but for some reason I couldn't get it working on an arduino mega 2560. I tried pins 9, 20 and 21.
I tried it with your example part B. It writes correctly, but doesn't read the response. So far I haven't tried to load the PartB example in a pro-mini or uno.
I found later that not any pin support interrupts for the softwareSerial receive in Mega.
Only candidates for softwareSerial RX function:  10, 11, 12, 13,  50, 51, 52, 53,  62, 63, 64, 65, 66, 67, 68, 69 should work (not tested)
And so it goes - it was something small, but not that easy to find.  Digging around in the source code of the library, I came accross the following:

// Specifically for the Arduino Mega 2560 (or 1280 on the original Arduino Mega)
// A majority of the pins are NOT PCINTs, SO BE WARNED (i.e. you cannot use them as receive pins)
// Only pins available for RECEIVE (TRANSMIT can be on any pin):
// (I've deliberately left out pin mapping to the Hardware USARTs - seems senseless to me)
// Pins: 10, 11, 12, 13,  50, 51, 52, 53,  62, 63, 64, 65, 66, 67, 68, 69

So pins 2 & 3 won't work (for receive).  Maybe this post can help someone else that has the same problem.




Does anyone know if SoftwareSerialWithHalfDuplex or similar has been developed any further?

Go Up