Single wire multi UART communication

Go To Last Post
31 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi!

I'm designing a device that uses three m8:s that communicate over a single wire using UARTs. By only enabling the UART outputs (TXEN) when actually transmitting anything all three uCs can share single line.
But turning TXEN on and off between transmissions create noise, so I'm trying to figure out how long time to wait when enabling/disabling before sending data.
Any clues?

Has anyone done this before?

My oscilloscope is not good enough to tell me, and I have searched the forum and googled for it.

Wileur

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Silly question but wouldn't I2C have been the more obvious solution for connecting them? Or is this driving over some distance? In which case you might consider RS485

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That's a valid question. The reason for using the UART is that I want to use only three lines, for power, ground and data. I2C and RS485 would both require four.
My design actually works, but I'm trying to find the optimum settings.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

wileur wrote:
That's a valid question. The reason for using the UART is that I want to use only three lines, for power, ground and data. I2C and RS485 would both require four.
My design actually works, but I'm trying to find the optimum settings.

Why would these need 4? Is this going to be a peer-to-peer system rather than a master/slaves system? At least in principle you can achieve the same results with 2 when using RS485.

If there is no master then you might need to have a third signal to allow one device to signal that is going to use the bus.

I think that the MODBus standard may address some of your needs.

-Tony

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It needs 4 because the remote devices get their power from the main one. Power,Ground,SCL,SDA or Power,Ground,Bus+,Bus- unless there is some way to send data over the power line as with 1-wire systems.

If I understand MODBus correctly it uses two wires, just like RS485.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

When al uc's are listening, none are sending and probably all TxD pins are disabled.
This means that the voltage on your communication line is undefined.
That can be easily prevented by using a pull up or pull down resistor on the communication wire.
The goal is to always have the voltage for the "idle" state on the communication wire so there is no noise on the line when the TxD line is turned on or off.

Gr, P.

Doing magic with a USD 7 Logic Analyser: https://www.avrfreaks.net/comment/2421756#comment-2421756

Bunch of old projects with AVR's: http://www.hoevendesign.com

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks, but putting a pullup/down on the line doesn't work with the UARTs. When nothing is going all pins need to be tristated, leaving room for any uC to send, which is why I switch the transmitter on/off.

My original question was simply how long time it takes for the pin to go from tristated to enabled and vice versa.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So if any node enables tx, the line snaps to -12, signalling 'bus in use' to all nodes. This should be instantaneous. Maybe biasing the line near 0v with big value resistors 47k? would bring it back near 0 after release... couple usec?

Imagecraft compiler user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I must admit that I'm confused.

You want -
(a) a 1 wire system (actually 2 including common)
(b) to supply power to slave devices through the communications/power line.
(c) tri-state the line during off times

Items (b) and (c) are in conflict. You cannot supply power through a tri-stated line. The typical way of accomplishing a 1 wire system that supplies power an communications is to have a pullup on the single line. To send data, the master (and slaves) pull the line low to transmit. When the bus is idle, the pull-up resistor (located on the master) supplies power to the slaves. It also prevents the bus from floating. The idle time must be sufficient so that the slaves have enough power to operate. You can help the situation by encoding you data such that long strings of "0x00" are avoided.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks a lot for trying to help!
To clarify again, this is my setup:

 ____________                _____________
|          Tx|-|          |-|Tx           |
| Main uC  Rx|-*----------*-|Rx Remote uC |
|____________|              |_____________|
    |  |                        |  |
+5v-*--|------------------------|  |
       |                           |
Gnd--------------------------------|

Description of the problem:
1) My system is normal CMOS levels, uC to uC communication.
2) I have three wires available to the remote uC
3) Two wires are used for power and ground
4) The third wire is available for bi-directional data (half duplex)
5) Tx and Rx are wired together
6) Only ONE Tx can be enabled at any given time
7) Every time a uC transmits data it:
7.1) enables Tx (TXEN)
7.2) transmits the data
7.3) disables Tx
8) Enabling and disabling Tx creates noise on the line, which corrupts any data sent when changing the state of Tx.

My solution to (8): introduce a short delay between enabling and transmitting.

------------
My question: how long delay is needed (i.e. how long does it take to enable or disable Tx)?
------------

Or is there a better electrical solution?

Wileur

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

As sugested above you MUST have a pull up resistor (10K?? or even one of the chip's internal pullups) on the communication bus. This will prevent the buss from floating and giving possible false start bits to the USARTs which would normally be in the RX mode.

Before changing direction after transmitting you MUST wait for TXC or you will lose some bits and get rubbish.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I personally think your implementation is wrong somehow... Just use two wires for UART, one wire for common ground, and power the remote device standalone, with a battery or something...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Just use two wires for UART,
But that's NOT what he wants to do. :-)
There are many implementation where TX and RX are tied together as above. Car radios comms to remote CD changers come to mind.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I understand this, I just don't think the trouble of changing a connector or adding a wire is worth the trouble of keeping an implementation like this working reliably... ;)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There is a protocol called SDI-12 which uses single wire, bidirectional UART-based comms. While the protocol includes a rigid message structure designed for environmental sensing, the song and dance that the various members have to do is pretty well spelled out. It might be worth a look in this case. Here, Google is your friend.

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Seems like you need an input from the computer to sense bus level. -12 is sort of awkward... if you used 0 and 5V you could tell if the line was hi or lo with a regular input. Sort of 'carrier sense, collision avoidance'. It suddenly dawned on me you were using 0-5v levels all along, so this is like rs485, where you send the char then poll the Transmit Complete bit while the char is shifting out... obviously you cant shut off the transmitter until the char has finished. Thats what the TXC bit is for.

Imagecraft compiler user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

wileur wrote:
Thanks, but putting a pullup/down on the line doesn't work with the UARTs. When nothing is going all pins need to be tristated, leaving room for any uC to send, which is why I switch the transmitter on/off.

My original question was simply how long time it takes for the pin to go from tristated to enabled and vice versa.

You seem to misunderstand what a pullup is/does. It will indeed work, and is exactly what you need.

First let's understand how the uart signalling works. When the line is idle, and the transmitter is on, the TX line is high. When it is ready to send a byte, it puls it low for one bit time (start bit), transmits the data bits, and any parity bits, and then pulls it back high for at least one bit time (stop bit, then idle)

Now when you disable the transmitter, there is nothing driving the line high, so it may float low, causing the receiving end to think that a byte is being sent. This state can happen whenever all 3 of your AVR's are in receive mode. Adding a pull-up resistor will ensure the line remains high when all 3 AVR's are in receive mode, thus preventing the false reception of noise.

 ____________                _____________
|          Tx|-|           |-|Tx           |
| Main uC  Rx|-*-----*-----*-|Rx Remote uC |
|____________|       |       |_____________|
    |  |            4k7            |  |
    |  |             |             |  |
+5v-*--|-------------*-------------|  |
       |                              |
Gnd----*------------------------------|

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Seconded

Imagecraft compiler user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

You seem to misunderstand what a pullup is/does. It will indeed work, and is exactly what you need.

Thanks, I do indeed know what a pullup does, I just didn't think of how the UARTS sync.

I have now gotten the whole thing to work as I wished. I spent a long time trying, getting random errors, until I realized my character size was set to six bits instead of eight.

A big thanks to everybody who suggested different protocols, I looked them up and even though none of them fit my purpose it got me thinking.

The funny thing is, though, that nobody has even attempted to answer my original question, which was how long time I have to wait before transmitting after enabling the transmitter:)

Wileur

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

wileur wrote:

The funny thing is, though, that nobody has even attempted to answer my original question, which was how long time I have to wait before transmitting after enabling the transmitter:)

Wileur

If the line is stable, you don't have to wait, you can begin transmitting immediately.

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

If the line is stable, you don't have to wait, you can begin transmitting immediately.

Now when I have the pullup, the noise is gone! Thanks a lot!

Wileur

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

As a matter of interest were you or are you now using TXC before changing direction or just a time delay?

...I hope that this firmware is being used as described and it is not just another smart card hacking project... :shock:

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I didn’t read all of the replies but I am thinking that the OP is using one ‘master’ and the ‘slaves’ are receive only. If that is the case , he could drive the transmit output via a open collector (not RS-232 signals) and the slaves could use something like a opto coupler to the slave receive inputs. I worked for one company that did that, the output pullup was tied to +12 VDC.
Perhaps I should just read the whole thread before making replies .
:|

I'll believe corporations
are people when Texas executes one.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Why don't see LIN bus spec.? Probably may help... :D

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Why don't see LIN bus spec.?
..because it's not good for hacking smart cards or talking to disk changers that use single wire uart protocol....
...coffee break...
a single wire uart comms would very good as a multimaster protocol too (unlike a 2 wire uart comms) for several chips communicating over short range where RS485 would not be necessary.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hacking smart cards? You mean like the one in my phone? I'll try that next...

FYI, I'm working on a kind of data glove with sensors on both hands.

I was not using the TXC interrupt, thanks for pointing it out. Everything works fine now, and I will work on optimizing it as soon as I finished the rest of the hardware.

Andreas

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

glitch wrote:
wileur wrote:
Thanks, but putting a pullup/down on the line doesn't work with the UARTs. When nothing is going all pins need to be tristated, leaving room for any uC to send, which is why I switch the transmitter on/off.

My original question was simply how long time it takes for the pin to go from tristated to enabled and vice versa.

You seem to misunderstand what a pullup is/does. It will indeed work, and is exactly what you need.

First let's understand how the uart signalling works. When the line is idle, and the transmitter is on, the TX line is high. When it is ready to send a byte, it puls it low for one bit time (start bit), transmits the data bits, and any parity bits, and then pulls it back high for at least one bit time (stop bit, then idle)

Now when you disable the transmitter, there is nothing driving the line high, so it may float low, causing the receiving end to think that a byte is being sent. This state can happen whenever all 3 of your AVR's are in receive mode. Adding a pull-up resistor will ensure the line remains high when all 3 AVR's are in receive mode, thus preventing the false reception of noise.

 ____________                _____________
|          Tx|-|           |-|Tx           |
| Main uC  Rx|-*-----*-----*-|Rx Remote uC |
|____________|       |       |_____________|
    |  |            4k7            |  |
    |  |             |             |  |
+5v-*--|-------------*-------------|  |
       |                              |
Gnd----*------------------------------|

Hi,
I try this circuit and it works perfectly. But why the data which Main uC just send wouldn't receive by itself through the RX line??

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

dabinn wrote:
I try this circuit and it works perfectly. But why the data which Main uC just send wouldn't receive by itself through the RX line??

Each uC does indeed receive the data sent by itself. Although I have not tried it, I have thought a bit about using that as the basis of a collision detection mechanism.

Christopher Hicks
==

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

cmhicks wrote:
dabinn wrote:
I try this circuit and it works perfectly. But why the data which Main uC just send wouldn't receive by itself through the RX line??

Each uC does indeed receive the data sent by itself. Although I have not tried it, I have thought a bit about using that as the basis of a collision detection mechanism.

Christopher Hicks
==

When I started writing my code, I planed to disable the RXEN before transmission and re-enable when the Transmit Complete Interrupt occur, to prevent recieving the coming back data. But I found the data didn't come back as expect, even I havn't done anything for the RXEN, the main uC recieved only the data which remote uC replied. So I disconnect the line between uCs any try again, and found the data come back from Rx at this time.
Though I am happy with "no need" to process the coming back data, but really don't know why would this happen. :cry:

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Unless you disable the receiver, each node will also be receiving it's own transmission... guaranteed! If your code is not seeing this "echo" then you must be filtering it out somehow along the way.

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

glitch wrote:
Unless you disable the receiver, each node will also be receiving it's own transmission... guaranteed! If your code is not seeing this "echo" then you must be filtering it out somehow along the way.

I traced my code and found maybe I confused the outgoing data with the incoming one. I thought the remote uC will reply same string back when main uC send requst string, it should be the data main uC echo back.And actually there was no data getting lost.

Thx alot! :)