Wire-or Arduino TX pins

Has anyone tried to wire-OR the TX pins on multiple Arduinos? I've got a system that has 12 temperature sensing processors that send 40 measurements to a central unit. Total transmission time over 5 minutes is less than 0.5 seconds at 9600 baud, so collisions can be detected and resent.

From the Atmel 328 data sheet, the PD1 (TX pin for the USART) is a tri-state port, so I suspect it's an "active hi" source and can't be directly wire-ORed. A a central unit, the Mega has four serial ports, so I'd still have to combine the serial streams from the remote senders. Any suggestions on how to combine the serial streams is appreciated. I'm thinking a multiple input AND gate.

(wire-OR is directly tying multiple open collector outputs together. Seems like it ought to be called wire-AND)

The pins are not tri-state as you wrote about tri-state.

A pin can be output with strong (40mA) 0V or 5V.
A pin can be input, which is a very high impedance input. An internal pullup resistor can be added.

But when the UART is turned on, it takes over the pins and sets the TX to output and RX to input.

Are the 12 units also Arduino boards (or Arduino compatible) ?
So you can program the units and the central unit with whatever you want ?
You could chain-link the serial communication, but if one unit fails, also the rest looses the communication.

For a wired-or/and you can use logic gates, but also 12 diodes with a pullup resistor.
The collision detection could be a problem with 12 units. What if they resend with the same timing ?
It is better if the central unit polls the units one by one. The central unit TX is connected to all the RX and the central sends "0t" to request the temperature of unit 0. When you add a timeout, you can detect a missing unit.

Diodes! Why didn't I think of that? Thanks. I'll breadboard that and see how it works. That would require a pull-up on the common junction and would make the common junction essentially an open collector pin (passive hi and active low).

All the sensors are Arduino Nanos and are distributed over a 70' radius. The central Mega transmits on one TX line with a line driver to drive a common bus to all remote units. That side works OK in the prototype.

Do you use a single wire and half-duplex, or still both RX and TX ?
If you use a single wire, and you use polling by the central unit, you have to do something extra.
In that case, the other units must also disregard the answer by the polled unit.
Perhaps you can use an escape character, like the STX character for the central unit.
If the answer by the units never contain the STX character, and the central unit starts with STX, the units only have to wait for the STX and after that see if they are addressed.

You are combining the Rx input to the Mega?

About the diodes and resitor:
Start with 1k, not 10k. Because of the wires a lower value is better.
Use 1N4148 diodes, not 1N4007. Those small 1N4148 have less capacitance and are more robust than you think.
The 1N4007 are good for 50/60Hz rectifying, and nothing else.

Is that 70 inch/feet/meters/spitting-distance/steps ?

I started a thread: Open source CANbus alternative/pubsub over uart/message passing project - #3 by system - Networking, Protocols, and Devices - Arduino Forum about a very closely related thing.

Yes, you definitely can do this. I did this at a distance of 50 feet, using cheap headphone cable from monoprice, using the a 20k internal pull up, using 3.3v, but one of the devices was actually 5v...

I used shottky diodes though, and I seem to remember the whole thing failing with any other kind of diode. I also used a protocol that had checksums and could detect when another node tried to talk over it and stop and retry and all that stuff.

Peter: 1N4148 signal diodes are great. If I need to go to schottky I will. BTW, this is Amerika, the Ludite country that refuses to go metric, so 70' (see the tick?) is 70 feet (22-ish meters, and I can't spit that far). The system is connected full duplex, so I only need to control collisions, not directional issues. I agree that a low value of pull-up is important for wire length, local EMI noise rejection, etc. The TX pins can sink 20 ma easily, so the pull-up could be as low as 250 ohms. I'll start with 2.2K (my favorite value from TTL days).

Crossroads: Yes, all the remote TX lines will be combined at the RX pin(s) at the Mega. Your diagram is correct, except the diodes would be reversed with a pull-up.

Eternity: Thanks for the empirical input. All my units are 5V. I'm using 22/4 cable for my serial loops, which can be used as backup for power distribution. All the units have a 20x4 LCD that consumes about 60 ma, so each remote package uses about 120 ma.

Peter, sorry I missed this:

For a wired-or/and you can use logic gates, but also 12 diodes with a pullup resistor.
The collision detection could be a problem with 12 units. What if they resend with the same timing ?
It is better if the central unit polls the units one by one. The central unit TX is connected to all the RX and the central sends "0t" to request the temperature of unit 0. When you add a timeout, you can detect a missing unit.

Repeated collisions can be avoided if you use a randomized time delay for the response, but I like your polled idea with the timeout. One big advantage would be that all the data points could be input in the span of just a second or two.

You may run into an issue with the voltage drop across the wires. If the voltage drop in the ground lead is enough to cause ground at the remote node to be higher than the logic high threshold of the receiver, than the remote node will not be able to pull the voltage on the bus lower than it's own ground, and thus might not actually be able to drive the bus low, so be sure that there isn't too much voltage drop over ground if you carry power.

You can get into all kinds of crazy hacks involving a separate negative supply and a few transistors to pull to that instead of to the MCU Vss or an isolated dc dc converter at each note so you could have a separate power ground and bus ground, but when we looked at it for our project none of them were going to be anywhere near as cheap or as reliable as just using a 1$ CAN transceiver on each node and connecting it to the TX and RX pins.

In your case the main problem is that you have 12 devices each using at least 60-70ma, so I'm not sure how well the backup power feature would really work unless you used thicker wire.

What I did for collision reduction is to actually use the message arrival times from other nodes to seed the random numbers for the back off, because clock drifts between devices are fairly random.

IMHO you don't want to use a protocol that relies on timeouts to detect a failed packet when doing collision detection, because you don't want to have to wait the entire timeout period to retry. We used a unique STX character and a unique end character, plus a backslash that can escape either one. In case a node poops out just after sending a backslash, you can send two STXs, the first being a dummy, on any messages that really matter to you.

Having the master TX connect directly to the slaves seems like a bad idea, because you need the RX pin for collision detection. Why not have the master part of the open collector bus?

In your case the main problem is that you have 12 devices each using at least 60-70ma, so I'm not sure how well the backup power feature would really work unless you used thicker wire.

Each unit has a separate 22/4 cable, so total current in the ground lead is 120 ma. 22 gauge wire resistance is 16 ohm/1000 feet. So at 70 feet at 120 ma, that would be a voltage drop (or offset) of 0.14 volts. I think anything less than 0.60 volts is safe.

I need to find out about CAN transceivers. Thanks.

If each device has its own cable, the total cable length will be ~22meters*12devices. With the pull up resistor, the cable capacitance makes an RC low pass filter. Generally you want the time constant of your filter to be significantly less than half the time it takes to send one bit at whatever baud rate you are using. With the assumption that 22/4 cable isn't too much worse than cat5 in terms of capacitance it still might work, but it might be a tight squeeze.

You might actually want a 120 to 180 ohm resistor in series with the diodes in each device, just to avoid the large current spike that happens when the IO pin goes low and tries to discharge the entire bus capacitance all at once. Which will of course limit how low you can pull down the voltage unless you use a larger value of a pullup, which might limit your speed.

You might have to experiment a bit and/or lower your speed to 4800 or 2400 baud, which would really suck.

The CAN transceiver is starting to look like a better option. If it can carry i2c, it should be able to carry UART just fine, and signal reflections aren't usually an issue at low speeds. I'm planning on using the mcp2561, which is the 1$ one I mentioned.

If you want to do a polled protocol and not a collision detection wired or bus, you could just use RS485, but I think the transceivers cost slightly more and might not be quite as fault protected as the cheap CAN transceivers.

The CAN transceiver is starting to look like a better option. If it can carry i2c, it should be able to carry UART just fine, and signal reflections aren't usually an issue at low speeds. I'm planning on using the mcp2561, which is the 1$ one I mentioned.

Although I have some spare wire pairs, I was initially planning for a single TX bus and a single RX bus. The CAN transceiver is differential, so either I dedicate another wire pair, or use a negotiated master/slave CAN bus. Not a high hill to get over, but it does add some additional software complexity.

Slower serial speed is not a problem for this application. I only need 10s of seconds of "simultaneity." (The concrete radiant floor weighs 90,000 lb. Its temperature isn't going to swing quickly unless the Russians nuke Cheyenne Mountain, which is nearby.)

The big attraction is the EMI reduction (slope control on the transceiver waveform) and noise resistance.