6
\$\begingroup\$

This is a combined mechanical/electrical question. It is mainly about getting the I²C connection reliable; this question does not concern itself with the software side (i.e., how to handle an I²C fault on the microcontroller).

I have an Arduino (Pro Micro) and an I²C slave device (an MPU 6050 sensor). The Arduino is already there (happily doing other stuff, connected to a PC via USB) and around 1 m away from where the slave will be placed. The slave is the usual small board similar to https://www.sparkfun.com/products/11028. It provides some capacitors and 10k I²C pull-up resistors.

So far, so good. In the good old "get'er done" spirit, I have hacked everything together with some RJ45 connectors and a 1 m Cat 5 cable I had lying around (carrying VCC, GND, INT, I²C). It kind of works, until it does not. The I²C communication breaks down regularly (after a few hundred or sometimes thousand transactions).

I admit that I still have to figure out who exactly the culprit is; i.e., I will connect the slave directly to the PCB and see if it still happens (that would rule out the cable connection). The software side is probably fine; said problem happens with several different firmware, even the most trivial ones. I have played around with the pull-up resistors (i.e., with/without the additional Arduino pull-up resistors; and with extra external 4.7 Ω resistors), and that did not change anything. The environment is not particularly noisy, I think. I unfortunately have no equipment to measure what goes on on the lines.

Meanwhile: Can you suggest a practical and reliable way to do such a connection? What I thought about:

  • The "easiest" one would be to get a second Arduino, place it right next to the slave, connect it with USB directly to the PC; that would eliminate the whole problem, but I would really prefer not to do that if I can avoid it.
  • Try to split the SCL/SCA lines into differential pairs; I don't see how that would work with the I²C open-drain protocol though. I don't want to stick with I²C necessarily; there is no need to fix that if there is an easier alternative.
  • P82B715PN line buffers
  • Something like CAN or RS-485 would likely force me to add at least two more chips, or even more per side (for protocol conversion and drivers).

Is there a practical (for a hobbyist), simple, go-to solution for this kind of problem (which seems to crop up once in a while...)? I'm really open to anything here.

I checked my cables... I previously had (INT+nothing), (SCL+nothing), (SDA+nothing), and (VCC+GND). I have added the GND to all pairs, so it's now (INT+GND), (SCL+GND), (SDA+GND), and (VCC+GND) as per @FiddyOhm 's answer. Unfortunately, no change whatsoever :( That wasn't it.

\$\endgroup\$
  • 5
    \$\begingroup\$ What frequency are you running your I2C at? Have you tried slowing it down? What VCC voltage have you got at the far end of the cable? What are you doing with the cable shield? \$\endgroup\$ – Wossname Oct 4 '16 at 9:27
  • \$\begingroup\$ Exactly, your clock frequency is key. I would not expect any particular problem for 1m cables, even at 400kHz. We regularily do this at work with three twisted cables, SDA, SCL and ground, no shield a lot of coupling and not an issue, and length is about 1m. Also reducing your pullup resistors to something like 1k might help. \$\endgroup\$ – Vladimir Cravero Oct 4 '16 at 9:30
  • \$\begingroup\$ Random thought: Are you running SCL and SDA together in a single twisted pair? It might be worth rigging up your connections so that you have ... (GND+SDA), (VCC+VCC), (GND+SCL), (INT+GND). Theory being that you might get spurious edges due to close coupling. \$\endgroup\$ – Wossname Oct 4 '16 at 9:35
  • 1
    \$\begingroup\$ Things that work for 100 or 1000 times and then suddenly stop working can very well be a software problem (race conditions which might be even in you most trivial code). \$\endgroup\$ – Arsenal Oct 4 '16 at 10:01
  • \$\begingroup\$ When I had a longish run I2C via a PIC processor, the issue was crosstalk between the clock and data lines. Certainly selecting the twisted pairs right can reduce that. But another thing was that the PIC I2C module had an option bit to limit rise/fall times. That reduced crosstalk immensely. I have no idea if your processor has such an option \$\endgroup\$ – infixed Oct 4 '16 at 15:18
19
\$\begingroup\$

Your 1 meter connection should work fine if you take the following precautions for your particular situation.

A. A good ground connection between the two boards is essential. You may be able to fulfill this requirement with your CAT-5 cable. If you run into problems after trying all of the following, run an extra 20 AWG wire along side the CAT-5 cable ( tie wrap it in one or two places.

B. It is best that you use one source of Vcc ( I assume this is 5 volts in your application). You imply this in your description with the inclusion of "Vcc" in the CAT-5 wiring description. The worst thing you can do in this respect is to tie two separate sources of Vcc together with the cable. Indeed, this may be your whole problem to begin with. Voltage drop across the 1 meter cable carrying the Vcc could be an issue. You will need to test this with a DVM at the load end of the cable to make sure it is in range of your peripheral device.

C. DO NOT twist I2C Clock and Data lines together! Twist each with a ground wire, but not with each other. In other words, choose the twisted pairs within your CAT-5 cable carefully. Allow the ground wires to serve double duty as additional power grounds as well - i.e. connect them to GND on the respective boards at both ends. (If problems persist, try clipping these lines one-by-one.)

D. DO twist Vcc and GND wires together. If you have two extra pairs after doing "C" above, use two twisted pairs of Vcc & GND and connect them in parallel at both ends ( i.e. on the respective PCBs. )

E. Use the smallest pull-up resistors possible. This is likely 1.0 K. If you have an O-Scope, you can perform a simple test to determine the lowest practical resistor for your specific application. Scope the signals as the app is running and decrease the resistor value until the signal shows signs of being loaded down below acceptable logic levels ( approx. 3.2 volts for a 5 volt system). You may find that CLK and DATA will tolerate different values of resistors, this is OK.

F. If communication speed is not an issue, run the I2C link at as low a frequency which is practical for your application. 100 KHz clock is generally the "low" frequency for I2C, but it can run at any speed because it is a synchronous protocol. I have run I2C at 1 KHz in some circumstances.

G. Make sure you have adequate Vcc-to-Gnd bypass caps at both ends of the cable. One 4.7 tantalum and one 0.1 or 0.01 mfd at least on the load end is about right. If worst comes to worst, repeat these caps at the supply end of the cable.

H. If all of this doesn't work, as a last Act of Desperation, slice open the CAT-5 cable and separate the various twisted pairs from each other about 1 inch. Don't untwist the wires, just separate the pairs. Hold them apart with masking tape or similar. If this works, you are dealing with some sort of inter-pair coupling problem (not likely in my experience with this length of cable). In this case you will need to shield the Data and Clock twisted pairs (each twisted pair within its own shield - e.g. braid you scavenge from a coax cable or microphone cable). Ground the shields only at one end, preferably the Arduino end.

If these points don't solve the problem, I'd guess there's something unusual about your set-up, or something you are not knowledable enough to recognize as a problem, and are therefore not describing in your otherwise excellent description of your set-up and problem.

\$\endgroup\$
  • \$\begingroup\$ +1. I concur. The original question and your answer remind me of this guy. \$\endgroup\$ – Nick Alexeev Oct 4 '16 at 14:22
  • \$\begingroup\$ Years ago I was connecting an mpu6050 to a microcontroller in a very similar scenario. The thing that worked the best (And was also the easiest) was to make sure to use only 1 of each twisted pair and ground the other. \$\endgroup\$ – thermite Oct 4 '16 at 19:57
  • \$\begingroup\$ B: yes, there is only one VCC source. C+D: done, see EDIT of the question. F: Tried down to 10kHz, no change. G: the slave is this breakout board haoyuelectronics.com/Attachment/GY-521/GY-521-SCH.jpg . Plenty of caps around there, hope they're fine. \$\endgroup\$ – AnoE Oct 4 '16 at 23:24
  • \$\begingroup\$ While pondering your hint about the capacitors, I stumbled across forum.arduino.cc/index.php?topic=394691.0 . According to that, some batch(es?) of that breakout board seem to have been produced with a wrong cap. I have replaced the slave with a known good one, and - voilá - now it works. It is running a burn-in-test today while I'm at work, but it just seems to be a faulty device. I guess I'll try the bad one a final time this evening just to make sure it was not just a cold solder joint or something like that, but the question at hand is done, if the "burn-in" succeeds. \$\endgroup\$ – AnoE Oct 5 '16 at 8:32
  • 1
    \$\begingroup\$ Absolutely agree with point C. Never put the clock and data on the same pair - this will cause excessive crosstalk. I have seen causing data significant errors on a 0.5m cable. \$\endgroup\$ – SpaceCadet Oct 27 '16 at 12:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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