Problemas al iniciar la comunicación I2C entre Arduino y el esclavo de 3,3 V

Estoy tratando de ingresar a la detección capacitiva y, por lo tanto, necesito una comunicación estable entre un Arduino y un TI FDC2114 , que ya está soldado en un EVM. Ambos son compatibles con I2C, y debido a la diferente tensión de funcionamiento de 5 V para Arduino y 3,3 V para FDC, estoy usando un cambiador de nivel bidireccional PCA9512A y pullups de 10k a 5 V (Arduino Mega interno), así como a 3,3 V.

Al escanear la dirección del FDC, a veces obtengo una respuesta positiva (ACK en el último reloj después de la dirección de 7 bits solicitada), pero principalmente un NACK. Incluso si recibo un ACK, algunos segundos después, el FDC ya no puede bajar el SDA a 0 V y obtengo NACK nuevamente. En el caso de NACK, puede ayudar desconectar SDA y SCL mientras están bajo voltaje y volver a conectarlos, pero no siempre funciona. Ya cambié todos los cables, por lo que no debería ser un problema mecánico. También observé que el voltaje máximo es de 3,4 V en SCL y más de 3,6 V en SDA, pero no sé si esto podría causar algún problema y también de dónde resulta la diferencia de voltaje.

Cuando se usa la MCU incluida del EVM, no hay ningún problema. ¿Qué me estoy perdiendo, por qué no funciona de manera confiable?

Alambrado

¿Podrías publicar un esquema de tu instalación? Un esquema a lápiz o un dibujo en una pizarra blanca servirían. La foto de la placa de prueba no funcionaría (al menos no por sí sola).
Una prueba simple para un bus I2C es medir la corriente para bajar SDA o SCL a GND con un multímetro. Mida tanto el lado de 5V como el de 3.3V, que son 4 de corriente. No deben exceder los 3mA. Una placa de prueba puede tener malas conexiones. Los cables largos podrían perturbar las señales. ¿Tienes una placa Arduino de 3.3V? ¿Un Arduino Due o Zero o un Arduino básico a 3.3V y 8MHz? El 3.6V es demasiado, podría ser un cableado incorrecto.
(a) " También observé que el voltaje máximo es de 3,4 V en SCL y más de 3,6 V en SDA ". Además de proporcionar el esquema ya solicitado, actualice su pregunta para explicar exactamente cómo observó esos voltajes, por ejemplo, ¿Osciloscopio? ¿Lecturas máximas en un multímetro? ¿Algo más? Y explique dónde observó esos voltajes (muestre esos puntos en el diagrama esquemático). (b) ¿Tiene acceso a un osciloscopio y experiencia en su uso? Si es así, suministre imágenes de rastreo (lo ideal es que incluyan SDA y SCL) tanto del lado de 5 V como del lado de 3,3 V del PCA9512A durante el escaneo I2C.
Agregué un esquema simple a la publicación de inicio. Arduino y FDC comparten un terreno común. Los cables no superan los 20 cm, por lo que esto no debería ser un problema. Usé un osciloscopio de 2 canales. SCL en el primero y SDA en el segundo canal. Medí la diferencia entre ALTO y BAJO tanto en SDA como en SCL, lo que resultó en 3,6 V (¡algunos picos de hasta 3,9 V!). Además, tanto SDA como SCL son una señal cuadrada perfecta. Observé esos puntos justo en frente de SDAOUT y SCLOUT. Subiré imágenes de seguimiento el miércoles, porque no es mi propio osciloscopio. Lo mismo se aplica a la medición de corrientes.
Mirando ese esquema, tengo algunos puntos, que incluyen: (a) El esquema parece incompleto, por ejemplo, no muestra cómo está ACCconectado el pin en el PCA9512A. (b) La ubicación física de los capacitores es importante. (c) Dijiste: " 10k pullups a 5V (Arduino Mega interno) " Un Arduino Mega usa el MCU ATmega1280, pero su especificación (ver página 355) dice que las resistencias pull-up internas están entre 20k y 50k. (e) Espero ver los rastros del alcance.
@J.Mustard Creo que el problema no está en SDA-OUT y SCL-OUT, sino en SDA-IN y SCL-IN. La resistencia interna de pull-up es demasiado grande. ¿Qué frecuencia estás usando? ¿Probaste con un valor más bajo?
¿Los tres dispositivos comparten un terreno común sólido?

Respuestas (6)

¡Problema resuelto!

Intenté hacer funcionar el FDC con un Arduino Mini Pro 3,3V y tuve el mismo problema que antes.

Al final, la solución fue simple: el FDC tiene un pin de apagado (SD), que lo pone en reposo cuando está ALTO y lo activa cuando está BAJO. Cuando conecté SD a GND, todos los problemas desaparecieron. Ahora tengo una señal estable entre Arduino Mini Pro 3,3V y FDC2114. Creo que también funcionaría con Arduino Mega y el cambiador de nivel, pero no puedo probarlo.

De nuevo, gracias por tu ayuda.

Siento no haber contestado estos últimos días. Parece que el PCA9512A ya no funciona, porque no hay ni reloj ni señal de datos en el lado de 3.3V. Por lo tanto, pedí un Arduino Mini Pro 3,3V para evitar el problema del cambio de nivel, aunque sería mejor resolver el problema en lugar de evitarlo. Pero quiero avanzar en mi proyecto, así que esta parece ser la forma más rápida.

Pero algunos puntos de aclaración: en los esquemas, los pullups en el lado de 5V son incorrectos. Son internos, no externos como sugiere la imagen. Además, en realidad son 10k, porque es un Arduino Mega 2560. Todos los dispositivos comparten un terreno común sólido. Probé frecuencias entre 100kHz y 400kHz, pero ninguna parecía funcionar. El pin ACC se eleva a 3,3 V mediante una resistencia de 10 k, lo que permite los aceleradores de tiempo de subida. Los condensadores están lo más cerca posible del FDC.

Debido a que el cambiador de nivel es defectuoso, no puedo cargar ninguna imagen de rastreo. Lo siento por eso, pero gracias por su ayuda de todos modos.

@SamGibson (sí, pero la resistencia de 10kOhm está en la placa ArduinoMega2560: es decir, habrá 10kOhm en paralelo al pull-up interno de 50kOhm. Pero tal vez 10kOhm aún sea demasiado grande para transferencias de alta velocidad).
@next-hack: gracias, ahora puedo ver la confusión entre el OP que dice "interno", lo que interpreté como que me dijeron que los pull-ups de 10kΩ eran internos de la MCU (que usted y yo estamos de acuerdo en que no lo son) vs. " on-board", que describiría las resistencias adicionales instaladas en la placa de circuito impreso. Los pull-ups de 10kΩ incorporados en paralelo con los 20kΩ-50kΩ internos de la MCU dan efectivamente 6,67kΩ-8,33kΩ, lo que debería estar bien para I2C "estándar" de 100 kHz hasta aproximadamente 150pF de capacitancia de bus, pero es marginal para 400 kHz "rápido". mode" I2C por encima de solo unos 50pF, por lo que todo depende del cableado. Eliminaré y mejoraré mis comentarios anteriores.
J. Mustard: después del útil comentario del próximo truco, ahora veo la confusión: dijiste "interno" que significa "en el PCB Arduino"; Pensé que querías decir "interno a la MCU". Entonces, mis comentarios actualizados son: (a) Los dos capacitores en el esquema deberían haber estado cerca del PCA9512, no del FDC (dado que ya tiene desacoplamiento en el PCB FDC EVM), aunque tal vez cualquier ruptura PCA9512 que usó ya tenía en- desacoplamiento de la placa también. (b) Al elegir pull-ups I2C, considere la información aquí y aquí .

El Arduino ya tiene resistencias pullup incorporadas. Esto puede estar afectando su capacidad para bajar las líneas lo suficiente. Deshabilite los pullups integrados o elimine los pullups externos de 10KΩ y vea si la situación mejora.

Sí, se muestran pull-ups separados de 10k en el lado de Arduino del esquema. Sin embargo, como destaqué en un comentario anterior, el texto de la pregunta afirma que los pull-ups de 10k a 5V son internos , lo que lo contradice. Además, las resistencias pull-up internas ATmega1280 no son de 10k. En resumen, ¡hay demasiadas inconsistencias para estar seguro de cuál es realmente la situación con respecto a los pull-ups ! Las imágenes de seguimiento del osciloscopio que solicité, y que el OP nos ha dicho que esperemos hoy, mostrarán si Arduino no puede desplegar las señales I2C (dudo que ese sea el caso con esos valores).
Las resistencias internas son de 20k - 50k.

Aquí hay algunas ideas, lo siento si ya las ha considerado.

Su problema podría no ser eléctrico, podría ser lógico. El cambiador de nivel I2C que está utilizando está diseñado para detectar las condiciones de INICIO y DETENCIÓN en el bus, por lo que si su software es incorrecto, es posible que el búfer no esté en el modo correcto.

Cuando inicie la comunicación I2S, intente hacer un preámbulo de cada operación con un bit de INICIO seguido de un bit de PARADA. Eso debería restablecer el búfer al estado correcto. Luego, examine su código I2C para ver si hay un problema en la forma en que maneja las condiciones de PARADA. Use suficientes retrasos para que su velocidad de comunicación I2C no sea demasiado rápida. 400kHz debería funcionar de manera confiable.

Finalmente, en su código I2C en Arduino, no configure la salida en alto cuando desee transmitir un nivel alto. En su lugar, configure el pin (SDA o SCL) para que se ingrese, luego las resistencias se encargarán de subir los pines. Si es posible que nunca lleve los pines SDA y SCL a un nivel alto, puede quitar el cambiador de nivel por completo y usar solo la resistencia pull-up a 3.3 voltios para esos pines. 3,3 voltios en los pines de entrada de Arduino deben ser lo suficientemente altos para detectar un estado alto.

" [...] use solo la resistencia pull-up a 3,3 voltios para esos pines. 3,3 voltios en los pines de entrada de Arduino deberían ser lo suficientemente altos como para detectar un estado alto ". Desafortunadamente no. El umbral de nivel lógico para el ATmega1280 (como se usa en el Arduino Mega mencionado por el OP) se muestra en su hoja de datos , página 362, tabla 31-7. Observe cómo Vih es al menos 0,7 x Vcc. Entonces, con MCU Vcc = 5V, I2C Vih es (0.7 x 5 =) 3.5V. Por lo tanto, 3.3V, como sugirió, no es lo suficientemente alto.

Comience con un circuito más simple: está usando un arduino de 5v, solo use un Arduino de 3.3v y su dispositivo esclavo de 3.3v. El atmega328 está clasificado para operación de 2-5v a varias velocidades, por lo que si desea cambiar el cristal y la entrada, puede reutilizar el que tiene, solo consulte la hoja de especificaciones para saber qué velocidades debe funcionar y qué voltajes. He leído que algunas personas tienen suerte incluso con solo 20 mhz completos con solo 3.3v. Con solo el arduino y el dispositivo esclavo, puede estar más seguro del circuito y hacer que el boceto funcione correctamente. Luego agregue complejidad al circuito después del hecho si necesita usar el arduino de 5v por algún motivo. Los clones chinos de eBay en realidad funcionan muy bien, pero por lo general se basan en el atmel 32u4 que tiene un USB incorporado para evitar el costo de un chip externo. El mayor inconveniente para ellos es que el envío es de un mes.

¡Retire el convertidor de nivel!

Dado que los controladores I2C son de drenaje abierto, puede conectarlos sin usar un convertidor de nivel.

Los controladores de bus I2C son de "drenaje abierto", lo que significa que pueden bajar la línea de señal correspondiente, pero no pueden subirla.

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

Hmm, eso es correcto. Estaba pensando que las palabras "ya soldado" significan que no es posible ninguna modificación de hardware. Pero si se puede, entonces sí.
Los convertidores de nivel I2C existen por una razón :-) He agregado un comentario a la respuesta de PkP que explica por qué se necesita un convertidor/traductor de nivel de algún tipo en el diseño del OP (el elegido por el OP parece demasiado complicado para esto situación, pero ese es otro tema). La naturaleza de los controladores de drenaje abierto permite la funcionalidad I2C como el estiramiento del reloj y la operación multimaestro, pero no cambia el hecho de que diferentes dispositivos tendrán restricciones sobre su voltaje de entrada máximo, Vih/Vil, etc. ¿Por qué cree eso? ¿Un bus I2C sin convertidores de nivel cumple con los límites del dispositivo aquí?
Sí, el convertidor de nivel existe por una razón, pero eso es cuando está fuera de los parámetros de trabajo, lo que no ocurre con el diseño del OP.
" [...] ahí es cuando estás fuera de los parámetros de trabajo, lo que no ocurre con el diseño del OP ". Respetuosamente no estoy de acuerdo. La hoja de datos FDC2114 muestra que sus entradas no son tolerantes a 5V. Por lo tanto, debe usar un bus I2C con pull-ups a su Vdd, no superior . Entonces, como expliqué en mi comentario a PkP , para obtener un funcionamiento confiable en el diseño del OP, donde no se garantiza que el 5V ATmega1280 vea 3.3V como "alto" (Vih = 0.7 x Vcc), se necesita traducción de voltaje. Consulte la pregunta anterior: I2C: ¿dispositivos de 3,3 V y 5 V sin cambio de nivel en bus de 3,3 V?