¿Por qué poner resistencias entre Vcc/SDA y Vcc/SCL en I2C da como resultado una onda cuadrada?

Estoy tratando de entender por qué colocar resistencias entre Vcc y las líneas de datos/reloj ayuda a que mi forma de onda sea cuadrada, cuando me comunico entre Arduino y un chip EEPROM. Si no se colocan resistencias en el circuito, las ondas parecen aletas de tiburón. El circuito aún funciona, pero definitivamente son ondas de aspecto extraño.

Como antecedentes, esta pregunta surgió después de conectar un Arduino a un Microchip 24LC256 (EEPROM) usando I2C. Al inspeccionar las señales con mi osciloscopio ( tratando de depurar algo no relacionado ) noté que las ondas se veían, bueno, horribles. Parecían aletas de tiburón para mí (¿hay una frase EE más aceptada para esto?). Revisé varias veces para asegurarme de que los osciloscopios de mi sonda estuvieran ajustados/compensados ​​correctamente, y verifiqué que no obtuve ese comportamiento en otros circuitos. Así se veía el cableado:

Configuración de cableado original

La señal amarilla es la línea SDA y la azul es SCL

En una conversación casual, le conté a un EE sobre esto, y dijeron que esto no es poco común para I2C. Recomendó colocar una resistencia de 10k Ohm entre Vcc y SCL y probar una resistencia más baja entre Vcc y SDA. Además, recomendó reducir la velocidad I2C a la configuración más baja (31 KHz para Uno). Efectivamente, si pongo una resistencia de 10k entre Vcc/SCL y una resistencia de 4,7k entre Vcc/SDA, se ven bien y cuadrados. También bajé la velocidad de normal a 31 KHz, pero eso tuvo un impacto mucho menor (si lo hubo).

¡Desafortunadamente nunca tuve la oportunidad de preguntar por qué! Soy un novato en electrónica, pero tengo mucha curiosidad por qué una resistencia colocada de esta manera hace que se vean mejor como ondas cuadradas. Esta foto a continuación es después de usar resistencias, pero antes de elegir los valores de resistencia 'óptimos' para las ondas cuadradas de mejor aspecto. Creo que se ve mucho mejor.

ingrese la descripción de la imagen aquí

Busqué explicaciones en Stack Exchange pero fue en vano. Estos parecían (potencialmente) similares a mi problema: Problema con la comunicación I2C EEPROM (sus ondas se parecen a las mías, pero la respuesta no respondió a mi pregunta) Interfaz I2C entre dos chips (este también parecía bastante prometedor pero no No profundice en el "por qué") Extrañas señales I2C emitidas por FPGA (esto parecía estar relacionado con otra cosa... aunque similar en que sus ondas se ven "feas")

¡Gracias por la ayuda!

En pocas palabras (y simplificado en exceso): se supone que debe ser cuadrado y es la falta de resistencia lo que hace que no sea cuadrado. O, en realidad, la resistencia era demasiado alta y la resistencia adicional la redujo (porque era paralela) lo suficiente como para fijar el tiempo de subida. Mire los tiempos de RC.

Respuestas (2)

I2C es un bus que utiliza salidas de drenaje abierto. Un drenaje abierto es como un interruptor conectado entre la salida y tierra. No funcionará sin resistencias pullup porque no hay nada que lo haga subir.

Si las resistencias pullup tienen un valor demasiado alto , no funcionarán (o no funcionarán de manera confiable) porque la resistencia no cargará la capacitancia de las entradas, la salida, el cable y tal vez una sonda de alcance lo suficientemente rápido . Si son demasiado bajos, la salida no será lo suficientemente fuerte como para bajarla.

Observa que en la medición de su osciloscopio, las salidas bajan muy rápidamente, pero son lentas para subir al nivel lógico 1.

Si el código en su Arduino está usando las resistencias pullup internas en el ATMega para golpear una interfaz I2C, entonces probablemente tengan un valor demasiado alto (decenas de K ohmios y no estén bien especificados) para funcionar de manera confiable, por lo que necesitan estar en paralelo con resistencias externas.

Personalmente, habría escrito el código para no usar los pullups internos (por defecto) para evitar la situación de que el bus "casi" no funciona, y forzar al usuario a usar las resistencias o elegir deliberadamente usar las internas. Es posible que sean aceptables si los chips están muy juntos, se usa baja velocidad (100K) y no se conectan sondas de alcance (especialmente en x1).

He visto una situación muy similar en la que se instalaron accidentalmente redes de resistencias de 47K en lugar de 4,7K.

Gracias Spehro, esto es muy útil. No estoy seguro de si la biblioteca de "cables" en Arduino hace uso de las resistencias pull-up internas de forma predeterminada, pero no estoy haciendo nada explícito en mi código para utilizarlas. Estoy de acuerdo en que prefiero que esas resistencias se elijan deliberadamente en lugar de confiar en ellas en el código. Podría ayudar a prevenir situaciones como estas. Lo sentimos, una pregunta de seguimiento rápida: ¿Por qué tener sondas de alcance (especialmente en x1) afectaría eso?
Las sondas de alcance en modo x1 agregan quizás 30-40pF a la capacitancia, lo que puede más que duplicar lo que ya existe debido a otros factores. En x10, la carga adicional es más como 1/10 de eso.

Se supone que I2C no funciona en absoluto sin resistencias pull-up; se requieren explícitamente en el diseño del autobús.

Entonces, en efecto, su pregunta es discutible: hágalo mal y sucederán cosas malas.

Si realmente quiere entender exactamente lo que está sucediendo, es probable que esté obteniendo algún tipo de efecto pull-up débil de una corriente de fuga o posiblemente incluso una resistencia pullup interna que es alrededor de 10 veces más grande de lo que debería ser la resistencia del bus I2C. Esto hace que la forma de onda ascendente RC exponencial, la clásica de un capacitor que se carga a través de una resistencia. Con una resistencia pull-up de valor adecuado, todavía sucede, pero lo suficientemente rápido como para que el exponencial se vea vertical en el osciloscopio.

Cualquiera que sea la fuente de corriente que esté elevando la línea en ausencia de una verdadera resistencia pull-up, es débil (es decir, el circuito tiene una impedancia muy alta), por lo que también es extremadamente susceptible al acoplamiento capacitivo de la línea del reloj, por lo tanto, verá la parte superior de la forma de onda de la línea de datos muestra artefactos cuando cambia el reloj.

Utilice las resistencias pull-up requeridas. Coloque un capacitor de derivación de suministro a través de su chip. Mantenga los tramos de cableado lo más cortos posible. Siga las reglas y evitará los problemas que normalmente surgen al romperlas.

Gracias, Chris. Supongo que esto es un peligro de seguir ciegamente un tutorial en línea donde no se usan resistencias pull-up. Gracias por la explicación (y sí, quería saber cuál era la razón subyacente de lo que estaba sucediendo).
@Thomas: desafortunadamente, el mundo de los tutoriales en línea de Arduino es tanto una colección de lo que no se debe hacer como lo que se debe hacer, incluidos incluso algunos de los oficiales de Arduino. Eso no quiere decir que no puedan ser útiles, pero a menudo tienes que examinar y rechazar tres o cuatro malos para encontrar algo que realmente funcione y ejercite de manera útil cualquier chip que se esperaba sacar un Arduino podría ayudar a evaluar rápidamente.