Odroid XU4 y Olimex MOD-IO por I2C mediante convertidor de nivel

Versión larga

Como algunos de ustedes, me dedico a la electrónica como hobby y estoy relativamente familiarizado con esto, así que tengo algunas preguntas sobre la comunicación entre mi Odroid XU4 y un buen módulo I2C de Olimex llamado MOD-IO . Déjame darte un poco de contexto.

Para uno de mis proyectos tenía una Raspberry Pi 3 conectada al MOD-IO como en la imagen de abajo:

Raspberry Pi 3 conectado a MOD-IO

Para detectar la dirección, acabo de usar la biblioteca i2c-tools i2cdetect -y 1y obtuve:

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- -- 

Recientemente había adquirido un Odroid XU4 para reemplazar el Raspberry Pi 3 ya que necesitaba más potencia de procesamiento para mi proyecto. Dado que la lógica del Odroid es de 1,8 V (a diferencia de los 3,3 V de la Raspberry Pi) y MOD-IO es de 3,3 VI, pensé que un cambiador de nivel debería funcionar. Las conexiones son como en la imagen:

Odriod XU4 conectado a MOD-IO usando un cambiador de nivel

Descubrí que Odroid i2c_1 está asignado a i2c-4 en el software. También confirmé esto ejecutando i2cdetect -y 4mientras sondeaba con un osciloscopio (soy un novato aquí, acabo de ver que solo en i2c-4 obtengo una lectura en el osciloscopio tanto en SDA como en SCL).

Sin embargo, cuando ejecuto i2cdetect -y 4obtengo resultados mixtos en la consola:

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- 07 -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- 1c -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- 36 -- -- -- -- -- -- -- -- -- 
40: 40 -- -- -- -- -- -- -- -- -- -- 4b 4c -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- -- 

ya sea lecturas aleatorias o ninguna en absoluto.

DEPURACIÓN o lo que probé.

  1. Eliminó completamente MOD-IO y usó el osciloscopio como referencia. Cuando ejecuto la detección directamente en los pines de Odroid (SDA o SCL), obtengo una lectura en el alcance. Además, cuando ejecuto la detección después del cambiador de nivel, hay una lectura en el alcance. De aquí deduje que el Shifter está bien.

  2. En segundo lugar, conecté otro dispositivo que usa 3,3 V y trabajé en la Raspberry Pi: un sensor BMP180 . Este se conecta de manera similar al MOD-IO. Cuando se ejecuta la detección, obtengo 0x77 como dirección. Incluso puedo obtener una lectura de la presión. Así que supongo que no hay nada terriblemente malo con la idea de la palanca de cambios.

  3. Leí en el foro de Rpi que la Raspberry Pi tiene una resistencia pull-up interna de 1.8k, pero no pude encontrar nada sobre el pull-up Odroid I2C. Intenté agregar una resistencia pull-up en el lado de 3,3 V del cambiador de nivel a 3,3 V VCC y al usar este documento de TI sobre el cálculo de la resistencia pull-up de bus I2C como referencia (por ejemplo, 4) elegí 1k como el valor, pero en vano.

Version corta

Estoy intentando conectar un Olimex MOD-IO (lógica 3.3V) a un Odroid XU4 (lógica 1.8V) por bus I2C, a través de un convertidor de nivel bidireccional y no consigo hacerlo funcionar.

¿Alguien tiene idea de lo que estoy haciendo mal? ¿Me puede apuntar en la dirección correcta?

Edición 1:

En primer lugar gracias chicos por todos sus aportes. Hoy di lo que creo que es un paso adelante.

Contexto: Intenté agregar varios pull-ups tanto a la línea de 1.8v como a la de 3.3v.

Primero configure 1k en 1.8v (SDA y SCL) y 4k7 en 3.3v. Fue entonces cuando obtuve mi primera lectura de la dirección I2C. Obtuve una lectura para la dirección 0x40, pero cuando probé una segunda lectura, volví al punto de partida.

Entonces, después de reiniciar el MOD-IO, obtengo una lectura y la misma dirección aleatoria en la segunda. Así que conecté el osciloscopio y seguí con la depuración.

Lo que intenté más fue cambiar las resistencias de 1.8v por una más grande de 2k2, pero esto no produjo ningún cambio en el resultado. Cambiar los pull-ups de 3.3v a 2k2 lo empeoró aún más, así que dejé de bajar con los pull-ups. Intenté cambiar el 3.3v con un 10k pero el resultado cambió poco o nada.

Entonces, la versión final de la configuración es ahora con 2k2 en la línea de 1.8v (SDA y SCL) y 10k en la de 3.3v (SDA y SCL).

Luego comencé a tomar fotografías del osciloscopio como lo hacía i2cdetect(no es un trabajo fácil: D).

Primero fue la línea de 1.8v. Esto lo hice directamente antes del cambiador de nivel con el MOD-IO desconectado ya que no pude obtener ninguna lectura tanto con el osciloscopio como con el MOD-IO. Esto es lo que obtuve: imgur

La segunda fue la línea de 3.3v. Esto se hizo con el MOD-IO conectado. En la primera detección obtuve la dirección correcta, pero en la segunda el proceso volvió a fallar con direcciones aleatorias. imgur

Lo que noté extraño aquí es el ruido en el SCL 3.3v y el SDA 3.3v bajando/después de la segunda detección y permaneció así hasta que se reinicia el MOD-IO (no funciona siempre, a veces necesito reiniciarlo varias veces para que el detector muestre la dirección correcta).

También tenga en cuenta que las imágenes se tomaron secuencialmente ya que el osciloscopio tiene un canal.

Entonces, ¿qué creen que debería hacer a continuación?

Edición 2:

Entonces, al no tener éxito en pedir prestado un buen visor, decidí ahorrar algo de dinero y comprar un visor decente. La entrega tardó un poco, así que aquí hay algunas imágenes de lo que logré obtener (todavía estoy en el alcance, así que sé amable: D).

Como mención, mantuve la misma configuración con un pull-up de 2k2 en 1.8V y 10k en 3.3v.

Entonces, ¿qué hago a continuación? ¿Qué es lo que ustedes hacen esto?

¿Tu palanca de cambios de nivel es bidireccional? Además, el protocolo I2C asume pull-ups tanto en SDA como en SCK
Eso sí, la palanca de cambios es bidireccional, al menos según ebay del fabricante . Intenté agregar 1k pull-up y no tuve éxito.
@VladIliescu - (a) Desde su punto de depuración "2", supongo que estaba usando el convertidor de nivel para esa prueba. ¿Es eso correcto? (b) Si tuviera su equipo en mi laboratorio, miraría las trazas de alcance del bus I2C, cuando esté usando ese convertidor de nivel I2C, verificando los niveles de voltaje y los tiempos de subida/bajada, en ambos "lados". del convertidor de nivel. Ha proporcionado mucha información en su pregunta (excelente primera pregunta, ya tengo +1). Una de las pocas cosas que faltan son algunos 'rastros de alcance'. ¿Puede su osciloscopio guardar las formas de onda como imágenes? Si no, ¿puedes tomar fotos de su exhibición?
@SamGibson muchas gracias por tu esfuerzo. Con respecto a sus preguntas: a) sí, lo único que cambió es BMP180 en lugar de MOD-IO. b) Intentaré mañana obtener una imagen clara de las trazas del osciloscopio; sin embargo, esto será todo un desafío ya que mi osciloscopio es un kit DYI rudimentario (DSO138). Solo lo he estado usando para confirmar que algo está sucediendo hasta ahora. Pero seguramente lo intentaré.
@Vlad - Gracias. (a) Compare las formas de onda I2C en ambos lados del convertidor: Odroid->convertidor->BMP180 (funciona) y Odroid->convertidor->MOD-IO (no funciona). (b) Re: su punto "3", revisé los últimos esquemas de Odroid XU4 y no veo ningún pull-up integrado en el bus h/w 1.8V I2C ("I2C#1"). Pero... (c) La foto de su placa BMP180 muestra pull-ups I2C. (d) Me he quedado sin espacio aquí, pero en resumen, sospecho que la falta de pull-ups en el "lado" ODroid XU4 de 1.8V del bus I2C, al usar su convertidor de nivel, puede ser importante (compruebe con ' alcance).
@VladIliescu Para la línea SDA, que es bidireccional, intente agregar pull-ups de 1K o 2.2K en ambos lados. Para la línea SCL, intente agregar un pull-up de 1K en el lado de 3.3V. Esto estaría tratando de solucionarse si el problema es un tiempo de subida lento debido a pull-ups débiles. Esto puede empeorar las cosas si el problema es que 1.8V es marginal para el encendido de Vgs.
@Vlad - Análisis re Edición 1: (e) Desafortunadamente, esas fotos de alcance muestran que su base de tiempo no fue lo suficientemente rápida, para que podamos ver el tiempo de subida/bajada de las señales I2C (es decir, la "forma" de los pulsos I2C individuales) que muestra si los valores de la resistencia pull-up son correctos. (f) Como suposición, parece que la velocidad del bus I2C puede ser ~ 125 kHz y la base de tiempo del osciloscopio debe ser al menos 10 veces más rápida; tal vez incluso un poco más. Si el tuyo no puede hacer eso, entonces esto puede ser un callejón sin salida. (g) La última foto muestra que algo estaba bajando la línea SDA lateral de 3,3 V (probablemente ese dispositivo se confundió por lo que vio en el bus I2C).
@SamGibson, lamentablemente, ajustar el tiempo del osciloscopio más rápido solo muestra una línea recta, esto fue lo mejor que pude hacer con la herramienta actual. Veré si puedo pedir prestado uno en la próxima semana. Mientras tanto, probaré diferentes valores de resistencia y comprobaré los resultados. Gracias por su apoyo y tan pronto como tenga algo, me aseguraré de agregarlo.

Respuestas (2)

Debe cambiar la palanca de cambios de nivel. El XU4 es muy exigente. Tenía un cambiador de nivel muy similar al tuyo, probablemente exactamente el mismo, pero el mío tiene una PCB azul, y no pude hacerlo funcionar. Luego compré el adecuado y las cosas funcionaron al primer intento. Hay muchas tiendas tanto en la UE como en los EE. UU., si no puede comprar en Corea.

Parece que su cambiador de nivel no puede funcionar con dispositivos I2C que usan la extensión del reloj. En consecuencia, el dispositivo termina en un estado en el que SCK/SDA están enganchados a GND.

El estiramiento del reloj permite que un dispositivo esclavo I2C suspenda la comunicación manteniendo el reloj en GND mientras procesa los datos (después de la fase de direccionamiento). Esto significa que tanto el esclavo como el maestro activan su salida de colector abierto al mismo tiempo.

En una configuración normal, sin cambio de nivel, el maestro liberaría el reloj y luego detectaría que el esclavo todavía mantiene el reloj presionado. Tan pronto como el esclavo suelta el reloj (que vuelve a estar alto), la comunicación puede continuar.

Con el cambio de nivel en el medio, esta lógica ya no funciona. Cuando el maestro mantiene pulsado CLK, el cambiador de nivel también tiene que bajar CLK en el lado esclavo. Cuando el esclavo mantiene presionado CLK, entonces el cambiador de nivel no envía esta información al maestro (cambiador unidireccional) o el cambiador bloquea el estado. Esto se debe a que no puede determinar si el maestro ya ha liberado el reloj.

No todos los dispositivos I2C utilizan la ampliación del reloj. Sospecho que el sensor BMP180, que está usando como referencia, funciona, porque no usa el estiramiento del reloj. Por otro lado, el MOD-IO se basa en un ATmega16L, que (muy probablemente) realizará una ampliación del reloj hasta que el software haya manejado la interrupción I2C.

Cuando observa un cambiador de nivel I2C adecuado como el TCA9800 y el P82B96, utilizan técnicas más avanzadas para resolver la situación de bloqueo.

El P82B96 usa dos niveles de tierra diferentes (0V y ~0.6V) para distinguir la parte dominante actual en el bus.

El TCA9800 mide la dirección del flujo de corriente para resolver el mismo problema.

Entonces, la respuesta se reduce a: ¡Obtenga un nivel de cambio I2C adecuado! (y quédate con el visor que compraste :)