3
\$\begingroup\$

I'm trying to get into capacitive sensing and therefore need a stable communication between an Arduino and a TI FDC2114, which is already soldered on an EVM. Both support I2C, and because of the different operating voltage of 5V for the Arduino and 3.3V for the FDC, I'm using an PCA9512A bidirectional level shifter and 10k pullups to 5V (Arduino Mega internal) as well as to 3.3V.

When scanning the address of the FDC, I sometimes get a positive response (ACK on last clock after the requested 7bit address) but mostly a NACK. Even if I receive a ACK, some seconds later the FDC can't pull down the SDA to 0V anymore and I get NACK again. In case of NACK, it may help to unplug SDA and SCL while under voltage and plug them back in, but it doesn't work every time. I've already changed all wires, so it shouldn't be an mechanical problem. I also observed that the peak Voltage is 3.4V on SCL and more than 3.6V on SDA, but I don't know if this could cause any problems and also where the voltage difference results from.

When using the included MCU of the EVM, there are no problems at all. What am I missing, why doesn't it work reliable?

Wiring

\$\endgroup\$
  • 3
    \$\begingroup\$ Could you post a schematic of your setup? Pencil schematic or white board drawing would do. Breadboard photo wouldn't do (at least not by itself). \$\endgroup\$ – Nick Alexeev Oct 2 '17 at 7:40
  • \$\begingroup\$ A simple test for a I2C bus is to measure the current to pull SDA or SCL down to GND with a multimeter. Measure both the 5V side and 3.3V side, that are 4 current. They should not exceed 3mA. A breadboard can have bad connections. Long wires could disturb the signals. Do you have a 3.3V Arduino board ? Either a Arduino Due or Zero or a basic Arduino at 3.3V and 8MHz ? The 3.6V is too much, it might be wrong wiring. \$\endgroup\$ – Jot Oct 2 '17 at 11:33
  • \$\begingroup\$ (a) "I also observed that the peak Voltage is 3.4V on SCL and more than 3.6V on SDA" In addition to supplying the schematic already requested, please update your question to explain exactly how you observed those voltages e.g. Oscilloscope? Peak readings on a multimeter? Something else? And explain where you observed those voltages (show those points on the schematic diagram). (b) Do you have access to an oscilloscope, and experience using it? If so, then please supply trace images (ideally including SDA and SCL) from both the 5V side and the 3.3V side of the PCA9512A during I2C scan. \$\endgroup\$ – SamGibson Oct 2 '17 at 12:56
  • 1
    \$\begingroup\$ @J.Mustard I think the problem is not on SDA-OUT and SCL-OUT, but on SDA-IN and SCL-IN. The internal pull-up resistance is too large. What frequency are you using? Did you try a lower value? \$\endgroup\$ – next-hack Oct 4 '17 at 10:57
  • 1
    \$\begingroup\$ Do all three devices share a solid, common ground? \$\endgroup\$ – bitsmack Oct 4 '17 at 18:07
2
\$\begingroup\$

Problem solved!

I tried to get the FDC working with an Arduino Mini Pro 3,3V and had the same problem as before.

In the end, the solution was simple: The FDC has a shutdown Pin (SD), which sets it into sleep when HIGH and sets it active when LOW. When I connected SD to GND, all problems went away. Now I have a stable signal between Arduino Mini Pro 3,3V and FDC2114. I think it would also work with the Arduino Mega and level shifter, but I can't test it out.

Thanks again for your help.

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

I'm sorry that I didn't answer the last few days. It seems that the PCA9512A doesn't work anymore, because there is neither a clock nor a data signal on the 3.3V-side. Therefore I ordered a Arduino Mini Pro 3,3V to avoid the problem of level shifting, although it would be better to solve the problem instead of just avoiding it. But I want to make progress in my project, so this seems the fastest way.

But a few points for clarification: In the schematics the pullups on the 5V-side are wrong. They are internal, not external as the image suggests. Furthermore they are actually 10k, because it's an Arduino Mega 2560. All devices share a solid common ground. I tried frequencies between 100kHz and 400kHz, but none of them seemed to work. ACC pin is pulled up to 3.3V by a 10k resistor, which enables rise time accelerators. The capacitors are as close to the FDC as possible.

Because the level shifter is defect, I can't upload any trace images. I'm sorry for that, but thanks for your help anyway.

\$\endgroup\$
  • \$\begingroup\$ @SamGibson (yes but the 10kOhm resistor are on the ArduinoMega2560 board: i.e. there will be 10kOhm in parallel to the 50kOhm internal pull-up. But maybe 10kOhm is still too large for high speed transfers). \$\endgroup\$ – next-hack Oct 7 '17 at 7:15
  • 1
    \$\begingroup\$ @next-hack - Thanks, I can now see the confusion between the OP saying "internal" which I interpreted as being told the 10kΩ pull-ups were internal to the MCU (which you & I agree they aren't) vs. "on-board" which would describe additional resistors fitted to the PCB. The on-board 10kΩ pull-ups in parallel with the MCU internal 20kΩ-50kΩ give effectively 6.67kΩ-8.33kΩ which should be OK for 100 kHz "standard" I2C up to about 150pF bus capacitance, but is marginal for 400 kHz "fast mode" I2C above only about 50pF, so it all depends on the cabling. I'll delete & improve my earlier comments. \$\endgroup\$ – SamGibson Oct 7 '17 at 10:41
  • \$\begingroup\$ J. Mustard - After the helpful comment from next-hack I now see the confusion - you said "internal" meaning "on the Arduino PCB"; I though you meant "internal to the MCU". So my updated comments are: (a) The two capacitors on the schematic should have been close to the PCA9512, not the FDC (since you already have decoupling on the FDC EVM PCB), although perhaps whatever PCA9512 breakout you used already had on-board decoupling too. (b) When choosing I2C pull-ups, consider the info here and here. \$\endgroup\$ – SamGibson Oct 7 '17 at 10:55
0
\$\begingroup\$

The Arduino has built-in pullup resistors already. This may be affecting its ability to pull the lines down far enough. Either disable the built-in pullups or remove the 10KΩ external pullups and see if the situation improves.

\$\endgroup\$
  • \$\begingroup\$ Yes, separate 10k pull-ups are shown on the Arduino-side of the schematic. However as I highlighted in an earlier comment, the question's text claims the 10k pull-ups to 5V are internal, which contradicts that. Also, internal ATmega1280 pull-up resistors are not 10k. In short, there are too many inconsistencies to be sure what the situation regarding pull-ups really is! The oscilloscope trace images which I requested, and which we have been told by the OP to expect today, will show whether the Arduino cannot pull-down the I2C signals (I doubt that will be the case with those values). \$\endgroup\$ – SamGibson Oct 4 '17 at 16:41
  • \$\begingroup\$ The internal resistors is 20k - 50k. \$\endgroup\$ – MatsK Oct 5 '17 at 4:21
0
\$\begingroup\$

Here's some ideas, sorry if you have already considered them.

Your problem might not be electrical, it might be logical. The I2C level shifter you are using is designed to detect the START and STOP conditions on the bus, so if your software is incorrect, it's conceivable that the buffer is not in the correct mode.

When you start I2S communication, try to preamble each operation with a START bit followed by a STOP bit. That should reset the buffer to the correct state. Then examine your I2C code to see if there is a problem in how you handle the STOP conditions. Use enough delays so that your I2C communication speed is not too fast. 400kHz should work reliably.

Finally, in your I2C code in the Arduino, don't set the output to high when you want to transmit a high level. Instead, set the pin (SDA or SCL) to be input, then the resistors will take care of pulling the pins high. If it's possible for you to never drive the SDA and SCL pins high, you could remove the level shifter altogether and use only the resistor pull-up to 3.3 volts for those pins. 3.3 volts in the Arduino input pins should be high enough to detect a high state.

\$\endgroup\$
  • \$\begingroup\$ "[...] use only the resistor pull-up to 3.3 volts for those pins. 3.3 volts in the Arduino input pins should be high enough to detect a high state." Unfortunately not. The logic level threshold for the ATmega1280 (as used on the Arduino Mega mentioned by the OP) is shown on its datasheet page 362, table 31-7. Notice how Vih is at least 0.7 x Vcc. So with the MCU Vcc = 5V, the I2C Vih is (0.7 x 5 =) 3.5V. Therefore 3.3V, as you suggested, is not high enough. \$\endgroup\$ – SamGibson Oct 5 '17 at 11:07
0
+100
\$\begingroup\$

Start with a simpler circuit - You are using a 5v arduino - just use a 3.3v Arduino and your 3.3v slave device. The atmega328 is rated for 2-5v operation at various speeds, so if you want to swap out crystal and input you could re-purpose the one you have - just check the specsheet for what speeds to run at what voltages. I have read some people have luck even just going full 20mhz with only 3.3v. With only the arduino and the slave device, you can be more sure of the circuit, and get the sketch working correctly. Then add complexity to the circuit after the fact if you need to use the 5v arduino for some reason. The chinese ebay clones actually work very well, but are usually based on the atmel 32u4 which has built in USB in order for them to avoid the cost of an external chip. The biggest downside to them is shipping is a month.

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

Remove the level converter!

Since I2C drivers are open drain, you can connect them without using a level converter.

I2C bus drivers are “open drain”, meaning that they can pull the corresponding signal line low, but cannot drive it high.

Ref.: https://learn.sparkfun.com/tutorials/i2c/i2c-at-the-hardware-level

\$\endgroup\$
  • \$\begingroup\$ Hmm, that's right. I was thinking that the words "already soldered" mean that no hardware mod is possible. But if can, then yes. \$\endgroup\$ – PkP Oct 5 '17 at 4:25
  • 1
    \$\begingroup\$ I2C level converters exist for a reason :-) I've added a comment to the answer from PkP explaining why a level converter / translator of some kind is needed in the OP's design (the one chosen by the OP seems over-complicated for this situation, but that's a different topic). The nature of open-drain drivers allows I2C functionality like clock-stretching & multi-master operation, but it doesn't change the fact that different devices will have restrictions about their maximum input voltage, Vih/Vil etc. Why do you believe that an I2C bus without level converters meets the device limits here? \$\endgroup\$ – SamGibson Oct 5 '17 at 11:13
  • \$\begingroup\$ Yes level converter exist for a reason, but that's when you are outside the working parameters, whitch the OP's design isn't. \$\endgroup\$ – MatsK Oct 5 '17 at 15:09
  • 1
    \$\begingroup\$ "[...] that's when you are outside the working parameters, whitch the OP's design isn't." I respectfully disagree. The FDC2114 datasheet shows that its inputs are not 5V tolerant. Therefore it must use an I2C bus with pull-ups to its Vdd, not higher. So as I explained in my comment to PkP, to get reliable operation in the OP's design, where 3.3V is not guaranteed to be seen by the 5V ATmega1280 as "high" (Vih = 0.7 x Vcc), voltage translation is needed. See previous question: I2C: 3.3V and 5V devices without level-shifting on 3.3V-bus? \$\endgroup\$ – SamGibson Oct 5 '17 at 15:35

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.