Single Wire Interface Between Two Arduinos

I am working on a project that is going to has two parts, a fixed part and a rotating part. Rather than going into a deep description here you can check out our website that details the project if you need or want to know more.

http://www.calvin.edu/academic/engineering/2013-14-team9/index.html

I want to minimize the number of wires that must cross the rotating to fixed break. I plan to use a carefully managed coiled or flexible cable to make this connection. I can't use a typical slip ring because there needs to be a 10.5 inch diameter hole for light to shine through around the center of rotation.

If I can get this cable down to 3 conductors it will make things easier and give me some more options (like coiled headphone cables. There will be an ATMEGA328 on each side of the break that can handle all of the local actions including motor driving and encoder reading, but I need to connect them in some way. If I can get the cable down to 6V, GND, and one signal line that would be ideal.

Does anyone know of an existing library that could connect two Arduinos with only a shared ground and one signal line? I could write my own protocol loosely based on the CAN bus if I had to, but I would love to avoid this if possible. The data rate could be very low(100 bits per second would be sufficient) but it must be bidirectional (Though it will clearly be half-duplex).

jroorda: Does anyone know of an existing library that could connect two Arduinos with only a shared ground and one signal line? I could write my own protocol loosely based on the CAN bus if I had to, but I would love to avoid this if possible. The data rate could be very low(100 bits per second would be sufficient) but it must be bidirectional (Though it will clearly be half-duplex).

You can use the One-Wire protocol introduced by Dallas Semiconductor (http://en.wikipedia.org/wiki/1-Wire). The drawback is that you must have a master that controls the bus but it is designed to be bidirectional. For the master side of the channel there are some libraries for Arduino (http://playground.arduino.cc/Learning/OneWire) as well as for the slaves (https://github.com/smurfix/owslave), although I never used the slave libraries.

Why not use software serial? Add a buffer to each chip to disable its Rx input when it is transmitting, and its Tx output when it is receiving. Then just have 1 data wire going back & forth.
Both sides default to listening when not transmitting.

One wire library may do comparable with software control of pinMode (or equivalent using DDRs).

Great thanks,

I had though of One-Wire, but I didn't know of a slave library. I'll give it a look and see if it will work for what I need and how much work the libraries would take to integrate.

I had not though of buffering the built in serial hardware. To make this method completely robust I would have to make a system that guarantees that both chips won't try to drive the line at the same time. This shouldn't be too difficult as I should be able to have the master initiate all communication and poll the slave regularly. I'll have to see if I have any buffer chips floating around. I don't suppose the Software Serial library would let me do this inside of the chip by swapping pin modes?

Now I just need to finish some of my other projects so I have two free boards to prototype.

I don't know how the software serial could be manipulated, I've never dug into it.

I got it working! For posterity here is the solution I found:

I started trying to use one-wire, but the libraries are mainly built for third party IC’s and have a lot of overhead I did not want to use if I didn’t have to, so I switched to using a multiplexed software serial.

Instead of altering the library, I create my software serial instance in a function such that when the function exists it will go out of scope and close the port. Then I can use a separate function to create the opposite serial port. This system works because the slave will only use the bus in response to data from the master. Thus I can do all the communication with one digital pin and a ground line.

My code is attached. Pin 30 is just a dummy pin. I have an Uno and Duemilanove so I don’t have a pin 30. Apparently -1 will work as a dummy pin as well, but I haven’t tested this.

SoftwareSerialExampleR.ino (1.5 KB)

SoftwareSerialExampleS.ino (1.34 KB)

Nice work.

You seem to have it figured out, but If you ever want to use hardware serial for more speed, what you can do is to do it like i2c does, and have a single wire with a pull up resistor that either side can drive low.

Arduino TX pins are not open collector, but if you add a diode facing the pin, they can pull down the voltage but not drive it high, making them act just like open collector outputs. Something tells me the diode should probably be a shottky or other low forward voltage drop diode though.

Then just connect the RX pins directly to the line, and set one of the RX pins to input_pullup, or just use a real 4.7k-20k pull up resistor.

I usually add a 220-470 ohm resistor in series with each diode just for fault protection if I'm doing more than a few feet, just in case I short out a connector or such. I've run 50 feet at 9600 baud no problem like this, although I wasn't running power so there wasn't a voltage drop on the ground pin to worry about.

I think there's not so much overhead in OneWire, (soft serial has its own costs) if there is only one slave, you don't even need to use addressing. About 14kbps can be achieve with very good reliability. Maybe you could write your own protocol inspired by the time-slot mechanism used in 1-wire, i's quite simple.

EternityForest: You seem to have it figured out, but If you ever want to use hardware serial for more speed, what you can do is to do it like i2c does, and have a single wire with a pull up resistor that either side can drive low.

Arduino TX pins are not open collector, but if you add a diode facing the pin, they can pull down the voltage but not drive it high, making them act just like open collector outputs. Something tells me the diode should probably be a shottky or other low forward voltage drop diode though.

Then just connect the RX pins directly to the line, and set one of the RX pins to input_pullup, or just use a real 4.7k-20k pull up resistor.

I usually add a 220-470 ohm resistor in series with each diode just for fault protection if I'm doing more than a few feet, just in case I short out a connector or such. I've run 50 feet at 9600 baud no problem like this, although I wasn't running power so there wasn't a voltage drop on the ground pin to worry about.

Can you share a little Schematic for that?? THanks!!