30
\$\begingroup\$

In my current project, I need to communicate between a microcontroller and some sensors over I2C. One of them is a temperature sensor, it needs to be placed at approximatively 2 meters far from the microcontroller. I cannot choose another protocol (the sensor is on a module with given connector/pins/protocol).

Do you think it is possible to communicate in this configuration? What information should I look up to ensure it can or can't be possible? Do you have some advice?

It is my first time communicating with IC outside the PCB.

\$\endgroup\$
6

8 Answers 8

42
\$\begingroup\$

I2C is not designed to be used over long distances but I know of several applications where it is actually used over a distance of about 2 meters. I also know of one case where they had issues with that and it was eventuelly fixed by fixing ground loops I believe.

To be sure that it will function, you should use an I2C bus extender like the P82B715.

However, the datasheet of the PB2B715 says the following in section 8.2:

For typical twisted pair or flat cables, as used for telephony or Ethernet (Cat5e) wiring, that capacitance is around 50 pF to 70 pF / meter so the cable could, in theory, be up to 50 m long. From practical experience, 30 m has proven a safe cable length to be driven in this simple way, up to 100 kHz, with the values shown. Longer distances and higher speeds are possible but require more careful design.

So the experts (NXP is the former Philips, the inventor of I2C) say that 30 meter has been proven a doable distance. My experience says 2 meters is a doable distance, and experiences that were reported back to me indicate that more heavily loaded I2C buses without any extender are also possible.

The key points to working I2C buses on long distances are:

  • Using a low capacitance cable (twisted-pair/Ethernet);
  • Limiting the bus speed;
  • Having pull-ups that are correctly sized.

Pullup calculation

Texas Instruments has a good application note (SLVA689) about pull-up calculation .

  • The lower bound of the pullup (minimum value) is determined by the current the weakest peripheral on the bus can pull, and the maximum voltage that represents 0 for any peripheral. So if 1V is still 0, your VCC is max 3V6 and your weakest device can only pull 20mA, the lower limit of the resistance is determined by the voltage loss over that resistor and the current pulled by that device: \$(3.6\ \mathrm{V}- 1\ \mathrm{V})\ /\ 20\ \mathrm{mA}=130\ \Omega\$ .
  • The upper bound is determined by the maximum rise time: your maximum I2C frequency is directly related to that, but there is also an upper limit defined by the protocol. The upper limit is \$R_{max}=t_r/(0.8473 * C_b)\$ . Where \$t_r\$ is the maximum rise time and \$C_b\$ is the bus capacitance. So if \$C_b\$ is 400pF, and the bus is operating in standard mode (\$t_r\$=1ms), then you'll find \$R_{max}=2950\ \Omega\$ . TI's application note has graphs so that you can find appropriate values quickly.
  • Of course the value for the pullup is the equivalent value of all pullups in parallel combined. You may have a pullup on the master end, the slave end, and any other slave/master on the bus. Remember that any resistor you add, lowers the effective pullup value. Note: one method is to use resistor values that are close to the maximum value.
  • Keep in mind the precision of the resistors.
  • The more you are "at the limit", the more you also need to account for "parasitics" such as the voltage drop in the cable.

With the above values in mind, at \$R_{max}=2950\ \Omega\$, you could use \$2800\ \Omega ±5%\$.
But an existing value is \$2700\ \Omega ±5%\$ for which the physical value could be as low as \$2565\ \Omega\$.
Therefore, 20 "worst case" resistors in parallel would be equivalent to \$128\ \Omega\$, which is acceptable if your lower limit is \$130\ \Omega\$ because not all resistors would be at the lowest value of their range.

However, you may not have control over the resistor values in the peripherals. You can probably know what their value is at a given point in time, and you may need to advice procurement and manufacturing to monitor or enforce this value - especially if you plan on having a loaded bus!

Power Rating: The power consumed in a resistor is \$V.I = \frac{V^2}{R}\$ - for a 5.5V drop and 1k that's less than 31mW. So there should not be an issue for discrete components.

\$\endgroup\$
2
  • \$\begingroup\$ Having pull-ups that are correctly sized? How to determine the value and power rating? \$\endgroup\$
    – gyuunyuu
    Oct 2, 2019 at 14:24
  • \$\begingroup\$ As Nick B commented on another answer, be wary of the possibility of the bus extender chip or whatever else heating the temp sensor by a couple degrees. \$\endgroup\$ Oct 3, 2019 at 7:39
17
\$\begingroup\$

You can, but it is not recommended.

Different buses for different purposes

I2C, like SPI, is designed for communication within a board or group of boards (think Raspberry Pi and its hats or arduino and its shields). It can work over longer distances (see other answers) but should not be used in those cases, simply because that's not what it was designed, optimised and qualified for.

The risk you take is that you may not be able to add more sensors in the future, or that your system will not work everywhere, or will fail under certain circumstances.

What you should be looking for is a field bus, something like 1-wire, CAN, RS-485, ethernet, etc.

Wireless systems like bluetooth or zigbee could also be an option.

\$\endgroup\$
16
\$\begingroup\$

You are generally limited by 400 pF maximum bus capacitance.

It should work fine if you lower your frequency to something like 1 kHz and provide power supply decoupling next to the sensor.

If you need something more robust then you can use differential I2C converters on both ends like PCA9615.

\$\endgroup\$
1
  • \$\begingroup\$ I dimly recall some sensors having a minimum I2C frequency (not sure why). \$\endgroup\$
    – Michael
    Oct 1, 2019 at 19:05
10
\$\begingroup\$

As noted by @filo, I2C is generally limited by the bus capacitance. However, there are ways to work around this:

  1. Use a bus extender. The P82B96 or PCA9600 would both be good options in your case.
  2. If you need higher speeds or extremely long cables, you can use a differential I2C transceiver like the PCA9600. However, this will make your circuit considerably more complicated, and you need an IC at both ends of the cable.

Take a look at AN10658 and AN11084 from NXP for more information.

\$\endgroup\$
2
  • 2
    \$\begingroup\$ This will work ok with a bus extender, as several others have said. Something not immediately obvious to watch for is that the bus extender at the sensor end can dissipate enough heat to raise the temperature sensors reading by a couple degrees if the sensor and bus extender are close together. \$\endgroup\$
    – Nick B
    Oct 2, 2019 at 17:45
  • \$\begingroup\$ The Application note AN11075 nxp.com/docs/en/application-note/AN11075.pdf for I2C over twisted paid is also an interesting read. \$\endgroup\$
    – kruemi
    Jul 6, 2022 at 13:06
5
\$\begingroup\$

I like the answers of filo and Caleb.

Another option is using one or multiple DS28E17 1-Wire-to-I2C Master Bridges at the individual sensors and wire up the bus as Onewire. This is good for >100m buses and well suited to low-throughput sensor array applications as distributed temperature and battery management.

\$\endgroup\$
4
  • \$\begingroup\$ Interesting thought, though it may introduce additional software overhead if the master does not have a 1-Wire interface. \$\endgroup\$ Oct 1, 2019 at 7:29
  • \$\begingroup\$ It mostly an option if you have a Linux host, as it has the full driver stack for this stunt. On a Raspberry Pi, you just have to connect GPIO4 to the 1W input of the DS28E17 through those 100m of wire (plus GND of course), edit config.txt and you are done. It's fully transparent, looks like a local I²C. Just slower. \$\endgroup\$
    – Janka
    Oct 1, 2019 at 10:20
  • \$\begingroup\$ Thanks. I was really surprised that 1-Wire can do that sort of distance. I guess it makes sense, since resistors are smaller. \$\endgroup\$
    – domen
    Oct 1, 2019 at 16:06
  • \$\begingroup\$ Onewire does not rely on rising edge timing but instead, all bit timing is done in relation to the falling edge, which is actively driven. That's why it is less susceptible to high capacitive loading. A few nF are ok. \$\endgroup\$
    – Janka
    Oct 1, 2019 at 18:13
0
\$\begingroup\$

Strongly recommend against.

You might get away with it, for weeks, years, thousands of production units even -- but it will not ultimately be reliable. The reason is EMI.

The 2m cable acts as an antenna, particularly resonant at 1/4 wave, or c*(1/4)/(2m) = 37.5MHz, and odd harmonics thereof (112.5MHz, ...). When such noise is picked up, current primarily flows along the low-impedance connections (VDD/GND) and not through the signal lines, which therefore see a voltage difference with respect to VDD/GND. When the noise exceeds the receivers' noise margins (typically 30% of VDD, or maybe a volt), the logic level is corrupted, and malfunction results. Typically, the effect is a denial-of-service (bus errors are generated, or whatever), but corruption of data already in transit can also occur.

Note, there is some noise immunity innate to the I2C hardware: they specify a 50ns glitch must be ignored. But there are two problems with this: 1. what if multiple glitches occur together, will they be sampled as the beginning (or end) of a pulse then? 2. RF is rectified by the input protection (ESD clamping) diodes, shifting the baseline, and this alone can cause invalid logic states to be received.

The Q factor of such an antenna might be ballpark 5-10, so that the ambient EM fields (in terms of V/m) might be this many times less, to generate the same magnitude of interference on the cable (i.e., this many times more sensitive). It will be much less sensitive at other frequencies, but there will always be random cases where these resonances are excited, and where it is exceptionally vulnerable. Alternately, the Q can be killed by placing a ferrite bead on the cable, at the host end; this merely flattens the response, so it's about the same sensitivity (~1V/m) at most frequencies. Improves the worst-case condition, but not the average. (IEC 61000-6-1 requires 3V/m radiated and 3V conducted.)

What I mean by "get away with it" is, EMI is not evenly distributed. Perhaps in these bands, the most likely culprits are VHF radios (CB, Walkie-Talkies / remote control toys), commercial radio (near your 3rd harmonic), and ESD (which is impulsive and broad spectrum; it'll excite such an antenna with a ringing waveform).

You might simply never have your device exposed to such sources, because of coincidence, or geography, or indeed careful placement. But it could always happen, out in the wild.

Note that -- if you don't need reliable communication, i.e. you can tolerate the sensor being unavailable for some length of time -- maybe mitigation isn't required. Retry immediately to check for impulsive noise (compare results from several consecutive acquisitions?); or if the sample rate can be some seconds, or minutes, maybe even hours -- that might be enough to get a sample through the noise, or wait it out entirely. (Some temperature or barometric pressure sensing applications might be examples for this, for example.)


Note the assumptions underlying this review: I'm assuming the simplest possible connection, using loose wires, or (unshielded) multiconductor or ribbon cable, and no filtering, just direct connection between sensor and host/base unit.

We can take some steps to greatly mitigate these issues. (But I still recommend against using I2C off-board.)


  1. Filtering.

At each end of the cable, add a bypass cap (0.1uF is fine) between VDD/GND.

For each signal (SCL/SDA), add a ferrite bead (220 to 1kΩ at 100MHz) in series, then a shunt capacitor of 220pF. Add ESD protection (usually clamp diodes, like BAT54S, from GND to signal to VDD), and finally a small resistor from ESD diode to the actual I2C interface (chip), typically 10-100 ohms. (The series resistance can't be very high, because of the required VOL into the pullup resistance.)

  1. Shielding.

Use a shielded cable, e.g. screened (preferably braided as well) multiconductor cable, or twin coax (probably much more expensive than required, but if you have it on hand for a one-off, sure why not; then route VDD alongside the pair, VDD signal quality doesn't matter).

Note this necessarily increases capacitance on the bus, reducing maximum speed and length.

The shield must be tied as closely to GND as possible, at both ends. Preferably using a shielded connector with wraparound connection to the shield (circular and D-sub connectors provide these features), with the connector's ground pins tied to PCB ground plane, early and often. (Use ground plane design techniques.) Do not use unshielded headers: the pin plus pigtail / unshielded lengths add up, allowing EMI into the signals, defeating your efforts. A solid ground is required. Even an inch of unshielded length is likely to fail commercial (8kV contact / 15kV air discharge) ESD.

  1. Use differential signaling.

This is mentioned in other answers, but a deeper explanation of why, is worthwhile.

When it comes to EMI, and RF magic, impedance is king.

The (regular, single-ended) I2C bus has wildly varying impedance. Which is why the rise and fall times are asymmetrical, why filtering sucks, and why cable length sucks.

It's really a quite well constructed standard, for what it is -- nearly minimal connections for on-board communication. That it fails in these ways, when taken off board, is no accident -- it's practically by intent!

But suppose we doubled the number of connections, and instead of having a static pull-up to VDD, we bias the line pair gently (either a bit negative, or just pulled to zero difference with a termination resistor), and drive the line pair, full strength, one up, one down. Well, we'd get a low impedance to start with (typically 100 ohms for twisted pair, would be used here), and we'd get only somewhat lower impedance when driven (CMOS pin drivers are usually 30-70 ohms, though a stronger driver might be used here to keep signal levels up). This makes filtering very easy: we merely need a matched-impedance filter, and this can be arbitrarily high-order to reject out-of-band noise. (Which, since the signals are low frequency pulses -- including down to DC -- a lowpass filter is the best we can do here. Note it should be near a Bessel response, because we're filtering pulses. In practice, we'd never bother with more than 2-3 order anyway, and this distinction is minor.)

Being differential, we can also use common-mode filtering to reject ambient noise sources, without having to compromise as much on (DM) filtering, or bandwidth -- and indeed, since it's differential, we can potentially go without DM filtering at all (at least beyond what's needed for effective CM filtering) and get much, much higher bandwidth while maintaining adequate immunity to ambient noise!

The biggest pitfall of differential I2C interfaces, at least among those that I've seen -- is the lack of extended common-mode input voltage range. That is, the differential bus interface is, probably just conventional CMOS input and output circuits -- internally on the chip, I mean -- they're limited to -0.3V to VDD+0.3V or thereabouts, implying clamp diodes (ESD protection) and all that. So you have really very little noise immunity without CM filtering: as soon as that ±1.5V or so (i.e. VDD/2) margin is exhausted, data corruption sets in. So they're best used with CM filtering.

(Contrast with RS-485, which is a differential line standard, with the same drive levels (3.3/5V), strong output drive (over 100mA), but also tolerates a -8/+12V input range -- considerably more common-mode range, enough for even industrial levels of noise (10V conducted, 10V/m radiated) with little or no filtering required. Unfortunately they didn't choose such a basis for these I2C interfaces; but such a multi-master differential bus does in fact exist: CANbus has RS-485-ish signal levels, even higher CMR, and uses the wired-OR arbitration mechanism of I2C.)


As for personal experience -- I've been required (read: by customer specification) to route I2C between boards before. One case was an HMI (human-machine interface, i.e. pushbuttons and display) board some 10cm away from the main board. I designed the connection to use 10 pin ribbon cable (unshielded), with VDD or GND (both serve as GND for RF purposes) interleaved between (and around) all signal lines (I2C plus a few other signals). Extra ground wires, affords a small degree of shielding by itself. Filtering was added to the signal lines, as described above (ferrite bead, 220pF, ESD diode). I believe the finding was, in EMC testing: it failed at 10V/m at 220MHz (makes sense: that's in the right range for the resonant frequency of the two boards joined by a short cable), and initially testing was done without the ferrite bead, and it was found adding one did the job.

If the cable were any longer, I would expect it to fail even with extra ferrite beads, and another shielding solution would be necessary (perhaps a metallic frame or enclosure to better (AC-)ground the two boards together, shorting out this resonant mode).

(That was a challenging project; the customer also demanded USB connectivity between boxes, carried on multiconductor cables joined with circular connectors. This configuration failed EFT (electrical fast transients, basically rapid-fire ESD produced by relay contacts opening under inductive load) by over a factor of 10. I was unable to find a solution that didn't involve shielded cables and connectors -- metallic circular connectors are readily available, but they cost several times more than the unshielded plastic kind. They got a functional product -- but as I heard it, the unit cost was about twofold higher than expected. This was noted early on; unfortunately, they didn't heed the warning.)

\$\endgroup\$
2
  • \$\begingroup\$ Why are you against it? First of all this is an old question with accepted answer. Secondly, I2C is routinely used by millions of devices daily over longer cables than 2m with ease. VGA, DVI and HDMI for example all carry I2C in the form of DDC bus. Certainly a measly 2 meters does not require differetintial buffers for I2C. \$\endgroup\$
    – Justme
    Jul 13, 2022 at 18:31
  • \$\begingroup\$ @Justme Indeed, the proper way to do it -- if you must -- is in a shielded cable, as those examples use. \$\endgroup\$ Jul 14, 2022 at 0:36
0
\$\begingroup\$

Adding my two cents, as I have implemented something like this in the past and come across some issues.

Firstly, yes you can do it. Calculation for maximum bus speed is based on pullup rail, pullup rail & bus capacitance. The NXP I2C specification gives some useful information on this https://www.nxp.com/docs/en/user-guide/UM10204.pdf section 7. To enable further reach, you will have have to use a buffer/repeater like PCA9508. This works by adding drive current capability to the drive side, helping overcome added capacitance. You can increase voltage from 3V3 to 5V on the line as well to reduce noise susceptibility. There is some good information in AN255 https://www.nxp.com/docs/en/application-note/AN255.pdf on the use of buffers in I2C buses. This would need to be used at two ends.

To implement, you should be aware of my mistakes:

  • The I2C bus is not shared with slaves of massivley different distances from the master. The round-trip time can interfere with the bus when several parts are present. It's fine to use several slaves at the 2m end because round trip is shared or you can use a I2C isolator if you need a local and remote slave on the same bus .
  • Using multicore alarm cable & running parallel data buses causes noise between lines due to shared return paths.
  • Digging the PVC sheather cable into the ground caused failures due to the porosity of PVC to water & added capacitance to the bus.
  • Arduino I2C library is aweful. If there is no ACK bit back, the MCU locks up due to the while(wait) loop.
  • Twisted pair cable like ethernet cable may have been a better choice than untwisted pairs. Coax is belt and braces.

Fixing the issues, I got the I2C to work reliably over 10m alarm cable. Next time I shall use RS422/485 as this is designed for long-distance cable runs.

\$\endgroup\$
1
  • \$\begingroup\$ The PCA9508 does not have a push-pull stage. Generally rise time accelerators with push stage just cause more problems than solve it, at least in systems that are free to implement their cable interface. Fortunately 2 meters is not extremely demanding as it just requires selecting suitable pull-ups and cable. \$\endgroup\$
    – Justme
    Jul 13, 2022 at 17:09
-1
\$\begingroup\$

Adafruit now (2021) sells the "LTC4311 I2C Extender / Active Terminator". It works by monitoring the SCL and SDA lines and then injecting current during the positive transitions to help overcome capacitive line loads and sharpen the waveform. I've not implemented any yet myself, but the description says they've been able to read sensor data at 100kHz over 100m of Cat5 cable, and 400kHz at a few meters.

https://www.adafruit.com/product/4756

You only need one of these near the head end of the bus, with no other wiring modifications. Seems like this could be a much simpler and cheaper off-the-shelf solution than other options like RS-485 or the PCA9615-based extenders that SparkFun offers.

https://electronics.stackexchange.com/a/564485/147302

\$\endgroup\$
2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.