2
\$\begingroup\$

I'm using an I2c sensor (Time of flight, VL6180X breakout board with voltage regulator onboard) at the end of a 1M cable. An arduino controls it.

As I2c was not meant to be far away from the PCB and the MCU, I used a 6 core shielded wire to connect the sensor to the Arduino Leonardo. I grounded one side of the cable mesh to the sensor. I'm using an USB 8 pin plug to connect the cable to the arduino control box.

I also added two 10k Pull-ups from the SDA and SCL lines to 5V, close to the MCU.

But, in the same cable I use the two other cores for powering a 2W led, at 500-600mA max. (4 cores for the sensor - 5V, GND, SCL and SDA and 2 for the led driver).

The sensor works normally when the led is off, 100% of the times. But when I turn the led on, mostly when the pwm duty is close to med-max, it makes the sensor fail almost everytime.

Am I adding capacitance to the whole cable when the led is on? Why does it happen? I measured the 5V VIN to the sensor with a multimeter and it doesn't change with the led on or off.

Is there a workaround for it? Having I2c working normally in a cable where 0.5A load is applied? Is there another type of cable that would make it work?

I could make the cables separate, but it wouldn't be the best option for me, for I would need more connectors, and a bulkier setup.

Edit: For testing purposes, I separated the cables. One for the led and another one for the sensor, on the same connector. It works much better, but it's not a solution I'd like to use for good....

Thanks for reading!

\$\endgroup\$
2
  • \$\begingroup\$ Comments are not for extended discussion; this conversation has been moved to chat. \$\endgroup\$
    – Voltage Spike
    Oct 9 '20 at 17:15
  • \$\begingroup\$ FWIW, in trying to get things "unstuck" make sure to re-initialize the I2C peripheral of the host processor. It may still not work, but it's worth a try, as whatever mixed-up state is preventing recovery after the readily understandable current-induced glitching could be in the MCU, not the I2C target. If you don't know how to re-initialize that, start by seeing if resetting the MCU gets I2C working again. \$\endgroup\$ Oct 9 '20 at 20:13
1
\$\begingroup\$

The best solution to a problem like this would be to put a small MCU at the sensor, and then send back something like a UART data stream via a differential transmitter. Something like an ATtiny would work well.

Additionally, it would be good to do the PWM switching at the location of the LEDs, and to bypass the supply for that with plenty of capacitance there, to try to keep the current through the supply lines mostly DC - eg, the long wires would carry the average current while the current pulses would stay local. You could also consider using a higher voltage supply, and using a regulator at the point of load and/or putting your LEDs in series to reduce the overall current.

In terms of what you can do right now, in addition to the suggestions in comments, you could try much smaller pull-up resistor. 10K is marginally too large for even an on-board situation. Hopefully you are benefitting from pullups already on the Arduino. If you look with a scope, too weak a pull-up would mean an RC character to the signal rise, while too strong a pull-up would mean that the signal never really gets to ground.

Its unclear if your application would permit it, but if you could disable the LEDs while taking a reading that would likely solve your problem.

\$\endgroup\$
7
  • \$\begingroup\$ I haven't downvoted but I did note with some amusement the use the the word "best" in the opening line because many times "we've" criticized people for asking for "best" solutions and then told them off because "best" is so under-defined. Maybe the downvote came from someone like that? \$\endgroup\$
    – Andy aka
    Oct 9 '20 at 15:11
  • \$\begingroup\$ Meh... it's pretty clear what the shape of a "good" solution for this sort of need would be, the dilemma is more if for the user's present purposes trying to fix a less sound one to the point where it works "well enough" may be an acceptable end point. \$\endgroup\$ Oct 9 '20 at 15:15
  • \$\begingroup\$ Thanks! I can't disable the led while reading. It must respond it's intensity while take readings. I was even thinking of using an Attiny85 (the final circuit is on an Attiny85) with the sensor, at the end of the cable, but the shell is too small to fit the whole circuitry... It can't be much bigger in size than it is now... I could use lower values of resistors indeed... \$\endgroup\$
    – Rodrigo
    Oct 9 '20 at 17:03
  • \$\begingroup\$ There's something 'odd' happening here. I'm entirely sure it's possible to do what you want. You say your sensor works fine. The only problem is that it doesn't work when the LED is on, leds shouldn't have that effect ! I suspect something related to the current path of the led. Maybe related to grounding. You should show how the led is powered. \$\endgroup\$ Oct 9 '20 at 20:08
  • \$\begingroup\$ @GrahamStevenson actually the setup described int the question would be expected to have precisely this effect due to things like ground bounce and induced currents in the I2C lines horribly corrupting the signaling. The one slightly odd thing is that the I2C peripheral can't be gotten "unstuck" by any command yet apparently tried, but I've seen that sort of thing in other cases too. Really the described setup is a poor design; I've tried to propose a better one, but it's possible that with diligent effort the existing setup can be rescued to work well enough for the askers purpose. \$\endgroup\$ Oct 9 '20 at 20:10
1
\$\begingroup\$

A distinct idea: Graham Stevenson's question about the I2C clock rate prompted a thought that it's not the clock rate which makes the system suspectible to induced noise, but rather the chance that a current spike happens during the I2C signalling itself.

So what if you were to coordinate the I2C and your 490 Hz PWM, such that the PWM on/off transitions happened during word-gaps in the I2C when you could actively clamp the I2C lines low, while the actual I2C signalling was confined to the portion of the PWM where the LED was steady powered or especially unpowered? When the I2C lines are low they are in a lower impedance state and less susceptible to coupling: at an extreme, you could even use an additional line to activate some FET's to clamp the lines to ground at the device end, or split the processor's view of I2C into a set of sense lines and a lines to drive far-end FET's.

It would be tricky, you'd probably need to bit-bang both (or at least implement at low level), but the timing can probably work unless you need nearly a full range of duty cycle variation.

And it raises questions about if the pulsing of your LEDs needs to be something specific to get the desired sensor result (though it's never been clear how your LED actually interacts with the sensor)

I don't like this as much as engineering a more sound system, but it might be a software hack that could save your current hardware.

\$\endgroup\$
1
  • \$\begingroup\$ I tend to agree. There's clearly some 'interaction' happening and an answer is to try to avoid this. I'm especially puzzled why 'the LED' is powered via the cable and not at the remote end via a transistor driver fed by a command signal, thereby eliminating a huge current loop. \$\endgroup\$ Oct 10 '20 at 5:55
1
\$\begingroup\$

I did a similar implementation a year ago. I used a VEML030 light sensor that was on a PCB and communicated with another PCB through I2C. On my experience, you would need level shifters to amplify the voltage on the cables, if not, you are risking the operation of the sensor. True that if you turn off the LED, the sensor will read properly, however, when you power on the LED you are taking energy from the power line. Using level shifters is not trivial, I used SN74LVC1T45DBVR from Texas Instruments, though when you connect it to your PCB, be very careful with how you route everything.

I have seen that other people have suggested other solutions so, I would recommend you considering this option as one of the last bullets.

Hope this help!

\$\endgroup\$
1
\$\begingroup\$

Thanks for all feedback, ideas and support! They were really helpful!

I manage to solve the problem by:

Lowering the values of the pull-ups on the SDA and SLC close to the arduino (470 ohms each)

And I used a thin Cat6A cable - less than 4mm diameter - (with 28 awg twisted pairs inside and no shielding), instead of my previous 6 core wire with shielding.

I wired one twisted pair with the SDA and 5V, another pair with SCL and GND, another pair with both wires together to the led cathode and the last pair with both wires together to the Led´s anode.

With this cable, at 1.5m length, the sensor works flawlessly everytime, at all led pwm levels. Never hangs anymore!

I know there are many other options, but in my case, for this cable length I need, this was a really simple workaround, that proved to work perfectly in my setup!

Thanks for all the help and input!

Regards!

\$\endgroup\$

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.