Two wire serial bus for range 20-30m?

Hi,

I have several arduinos with sensors around an area, and I have a 4 wire cable going around for power and communication. I need to communicate everything with a central computer with no additional ICs and no additional cable.

Speed is not an issue and I am using only 3-4 pins from each one.

At first, i2c seems like the perfect solution, but I know it's intended for communication inside equipments, within very short range. I've been aware that I can increase i2c range by lowering frequency, but haven't tried because seems like the Wire library has no easy setting for this.

So, any way I can actually use i2c for this, or any other standard that' s compatible and would fit?

why not just go for rs232 type solution. Hook up all ardus on rs232 serial and run it on that. Ok because you only have vcc, gnd, rx, tx available, you cannot have handshaking by hardware. So do it on software. Just make sure that only one ardu at time speaks and others listen.

Well I would do this with xbee radio modems but like you said that you don't want to have more hw. 20-30 m should be easy for rs232 type solution.

I used to run 9600bps over 50 meters without problems

--jp

google keywords "iic long distance" yield this as the first link
http://ics.nxp.com/products/i2chubs/

Eberhard

If you want a multi-device serial BUS and not point to point serial RS232... you want to look at RS485.

..., and I have a 4 wire cable going around for power and communication. I need to communicate everything with a central computer with no additional ICs and no additional cable.

You may have constrained the solution so much that the only answer available is the USART.

I have not tried this yet, but I am planning to loop the Tx of board 1, into the Rx of board 2, then the Tx of board 2 into the Rx of board 3, and so on.

Thoughts for flow control are:

  • go so slowly that there is no need for flow control (?), and
  • use a digital output to handshake with the upstream board.

If you would get some chips, go with pwillard and use RS485 drivers. They are pretty low-cost.

HTH
GB-)

https://www.distrelec.com/ishopWebFront/catalog/product.do/para/keywords/is/P82B715PN,P82B715PN,NXP,I²C_Bus_Circuits_DIL-8,I²C_Bus_Peripheral_Circuit/and/language/is/en/and/shop/is/NL/and/series/is/1/and/id/is/01/and/node/is/DC-48735/and/artView/is/true/and/productNr/is/649003.html

bought 4 of these, now 20 m is no problem anymore.

https://www.distrelec.com/ishopWebFront/catalog/product.do/para/keywords/is/P82B...

bought 4 of these, now 20 m is no problem anymore.

Nice. Please tell us how things turn out.
I've never used those before (I'd have used RS485 drivers) so those will be very interesting to me.

GB

I use common or garden serial and software serial for communication between 4 arduinos (4 wires for power and comms) and distances of around 50 metres. Cheap and it works.

I use common or garden serial and software serial for communication between 4 arduinos and distances of around 50 metres. Cheap and it works.

Doh! :-[
Especially when there is a common ground (in the cable) and apparently plenty of pins.

Sorry fredlaatnaarbed.

GB-(

9600 baud no problem. It isn't an electrically pristine environment either, the cables run over a suspended ceiling with fluorescent light fittings just below. The receive only 'duinos only use 3 wires. Might get a bit flakey if you tried to use 115200........

i'm using 2 I²C bus extenders (https://www.distrelec.com/ishopWebFront/catalog/product.do/para/keywords/is/P82B715PN,P82B715PN,NXP,I²C_Bus_Circuits_DIL-8,I²C_Bus_Peripheral_Circuit/and/language/is/en/and/shop/is/NL/and/series/is/1/and/id/is/01/and/node/is/DC-48735/and/artView/is/true/and/productNr/is/649003.html).
It works for appr 24 hours and then the communication is lost. Need to reset all arduino's and everything is back online.

How is this possible and how can I solve this problem?

May I ask a couple of questions?

Have you got a way to see whether or not both Arduinos are still running when communication is lost?

If you connect the Arduinos together without the I2C bus extenders, does the system run for much more than 24 hours?

In the problem you are trying to solve, is it possible to designate one of the Arduinos as the "boss", and have all the others subordinate to that Arduino? This would open up ways to make the system more robust.

thx tkbyd,

What do you mean with "the Boss"?
one is the master sending information to 2 slaves.
I was thinking about resetting all arduino's every 6 hours automatically.
suggestions?

need also information from the slaves,
but I'll have a look @ RS232.
thx

RS232 is a point to point connection, so the master will need one USART to talk to each slave. AFAIK you said 2 slaves, so 2 USARTs; you could use the 'soft' (bit banging) USART.

RS485 is a 'bus' (like I2C), and so could work with a single common cable. I don't think I've seen any Arduino libraries to handle a protocol though (i.e. to sort out who is talking to who).

Ah! Good. "Boss" = "master".

Since you are in this situation:

You can "hang" the three Arduinos on a single pair of wires: A ground and a signal pulled high through a resistor. You can make the voltage and the "pulled high" whatever you need to make it to cope with the distances, etc, involved, and at each Arduino you will have simple interfaces between your "network" and the Arduinos.

(There must be a name for what I'm going to describe... someone please give it, so Wikipedia/Google searches can be done by interested parties? It is, by the way, more than is "necessary"... but if you want ultra robust....)

On reset, the master Arduino starts to do its thing... notes follow, and the slaves go into a "wait to be spoken to" mode. (Probably collecting data, etc, in the meantime.)

From time to time, the master issues a "slave A," or "slave B, talk to me" command. They (hopefully) do... and if they don't the master assumes the relevant machine is down. (see note below). No slave ever presumes to stay active on the net for more than a brief time. If it gets no reply from the master after a transmission, it doesn't retry very often.... it goes back to waiting to be "spoken to".

How do the Arduinos "talk"? They all "listen" by monitoring the voltage in the line between them. When the master wishes, or when a slave has been told to, they "speak" by pulling the line between them low in a pattern, i.e. a serial data stream. As the master is moderating the conversation, there shouldn't be cases of two units "speaking" at once. In any case, the communications should have check bytes to see that transmissions didn't fail for any reason.

You can either have the slaves reset every so often, just in case, or you can build extra circuitry which causes a reset in the slaves if the line between the Arduinos is pulled low for a "long" (relative to any other lows which will be seen) time.

All this "inspired" by what happens in 1-Wire MicroLans, and by how a pre-1960 city wide fire alarm street corner pull-box system worked. The one I knew was in Ithaca, New York, but I believe the same system was widely used... it was brilliantly simple, nearly Murphy-proof.

I think you've described, in abstract, a half-duplex protocol.
One might put something like that across RS485 if distance, more than two end points, and a lack of a common-ground-referece is part of the problem.

The I2C protocol, also half duplex, does some of what you've described, but without retries or checksums. It provides the protocol for identifying who is talked to (i.e. slave addressing), defines the packet format, and handshakes.

The protocol you've described also has 'liveness' messages used by many proper comms protocols.

A point to add is the master may be the one dying. So it may need to reset too.
If the master does die, the protocol gets a bit harder if the data sent by slaves must never be lost.

This is fairly complex code.

There is an onboard watchdog timer, which you could use to 'tick' down a self reset.

fredlaatnaarbed - What is the problem you're trying to solve?
Do you know if the master never seems to die?
If the master does die, is it okay if data from slaves be lost very occasionally (as a pure guess, less than 1/month-1/century)?

Alternatively, when a slave successfully responds to a request for data, and a master completes the 'conversation' (transaction) could they both just reset then? The system would spend a lot of time resetting, but there should be no problems of locking up :slight_smile:

gbulmer,
1 slave sending data (1 Hz) to 2 slaves and also asking data from 1 slave. It works fine for appr 24 hours then no data is going up or down.
after a reset (or plug in en out the usb from the master) it is back online again.

1 slave is 40 meters away from the master connected via I2C bus extenders. If I disconnect that one the system keeps working for ever.
So the error is caused by the long distance communication.

If the communication is lost the arduino's keep on doing what they should do except talking to each other.

I have not tried this yet, but I am planning to loop the Tx of board 1, into the Rx of board 2, then the Tx of board 2 into the Rx of board 3, and so on.

This is basically token passing as used by HDLC and it works well. Obviously some form of protocol still needs to be designed but once started the bytes can just keep going around in circles with each node say placing it's data in the Nth byte and reading data from the Nth+1 byte or whatever.