Estoy construyendo un pequeño proyecto de hobby de domótica para el que intento conectar 4 sensores de temperatura/humedad ( AM2320 ) a un bus I2C en la Raspberry Pi. Al conectar inicialmente los sensores funcionan bien, pero después de unas cuantas llamadas (de 10 a 50) con intervalo de 4s, la lectura falla con un "OSError: [Errno 6] No hay tal dispositivo o dirección". Después de eso, una llamada a i2cdetect en el bus resulta en una respuesta muy lenta donde cada dirección sondeada toma alrededor de 1s (igual al problema descrito aquí ). Después de esto i2cdetect no detecta el sensor.
Desconectando y volviendo a conectar físicamente el sensor se reinicia el bus.
Creo que la raíz del problema está en la capacitancia de la línea de conexión entre los sensores y la Pi, sin embargo no consigo entender por qué. Espero que alguien pueda aclarar cuál es el problema.
Detalles del montaje
Estoy usando 4 sensores idénticos conectados a una sola Raspberry pi. Cada sensor está conectado a ella a través de un cable Cat5 pelado (4 hilos (2 pares trenzados) por sensor, sin apantallamiento ni aislamiento exterior) de aproximadamente 2 m de longitud.
Como los sensores son bastante simples y baratos, no tienen una dirección I2C configurable. Cada uno tiene la dirección 0x5c. Para acomodar 4 de ellos he configurado algunos pines GPIO para tener 3 buses I2C adicionales junto al bus estándar número 1. Esto se hace añadiendo las siguientes líneas al archivo de configuración. (Según este instructivo .)
dtoverlay=i2c-gpio,bus=5,i2c_gpio_delay_us=1,i2c_gpio_sda=23,i2c_gpio_scl=24
dtoverlay=i2c-gpio,bus=4,i2c_gpio_delay_us=1,i2c_gpio_sda=17,i2c_gpio_scl=27
dtoverlay=i2c-gpio,bus=3,i2c_gpio_delay_us=1,i2c_gpio_sda=4,i2c_gpio_scl=18
Todos los sensores se alimentan desde el carril de 3,3V de la Pi. Todas las líneas SDA y SCL tienen una resistencia pull-up de 3,3 kOhm. Sólo para el bus I2C 'estándar' número 1 confío en las resistencias de 1,8 kOhm que están en la propia Pi.
Leo los sensores mediante este script de Python: https://github.com/Gozem/am2320/blob/master/am2320.py .
Cosas que he probado
He probado las siguientes cosas, por sí mismas y varias permutaciones de estas cosas. Ninguna parece tener un efecto positivo o negativo apreciable.
- Diferentes parámetros de tiempo de espera en el script.
- Diferentes velocidades I2C (desde la estándar de 100 kHz hasta 50 kHz, 25 kHz, 10 kHz, 5 kHz y 0,5 kHz).
- Diferentes valores de resistencia de pull-up: 150 Ohm, 230 Ohm, 1,8 kOhm, 3,3 kOhm, 10 kOhm, e Inf (sin pull-up). Así como el Raspberry Pi construir en pull-ups.
- Diferente número de sensores (conectar sólo 1, conectar 2, conectar los 4)
- Diferentes sensores en diferentes autobuses (varias permutaciones).
- Desenrollar los cables: En el caso de un sensor, he desenroscado los cables para intentar reducir la capacitancia entre ellos.
- Restablecimiento por software del bus (a través de este método ) no resuelve el problema. Sólo funciona una desconexión/reconexión física.
- Reiniciar la RaspBerry Pi a veces reinicia el bus, pero no siempre.
Lo único que parece haber resuelto el problema : Fue cuando moví un sensor más cerca de la Pi. Con un cable de par trenzado de ~0,2 m de longitud parece funcionar bien (probado durante ~media hora). Esto me indica que la longitud del cable, y por lo tanto probablemente la capacitancia del cable o la resistencia del cable es el problema. Sin embargo, al mirar la forma de calcular los valores máximos permitidos (según este documento de TI ), y observando las características del cable Cat 5 ( wiki ) Pensaría que debería estar muy por debajo de la capacidad máxima de 400 pF, y debería haber dado con una resistencia de terminación adecuada en algún lugar dados todos los diversos valores de resistencia y velocidades de comunicación que he probado.
(Lamentablemente no tengo un osciloscopio para medir directamente las señales en la línea).
Así que para resumir la pregunta: Estoy en la cuerda floja y espero que haya alguien que pueda explicarme qué está pasando.
Editado en base a los comentarios:
(2021-01-11 16:00)
Estoy usando una Raspberry Pi 3B+ Tenía los cables en pares trenzados como ((V;GND) y (SDA;SCL)).
Ahora he reducido la complejidad de la configuración. Sólo tengo 1 sensor conectado directamente al bus I2C de la Pi (GPIO 2 y 3), con sólo las resistencias pull up de la Pi. Los cables entre ellos son sin torsión ~ 2m de largo. He desactivado todos los buses I2C adicionales. He añadido un condensador de 4,7 nF y otro de 47 uF entre V+ y GND en el lado del sensor (según la sugerencia de Justme de añadir algunos. He elegido los valores de los condensadores de forma arbitraria). Esto parece funcionar sin problemas (!) (Más de 400 ciclos, intervalo de 4s. He parado y arrancado el script algunas veces entre medias).
A partir de este punto amplié para incluir un sensor más. Añadí un bus I2C número 3 en GPIO 17 y 27 con pull-ups de 3,2 kOhm. A esto le añadí un segundo sensor. El sensor también tiene condensadores de 4,7 nF y 47 uF añadidos en el extremo del sensor. Esto todavía está conectado a través de pares de cables trenzados. El segundo sensor funcionó mal después de ~200 ciclos. En ese momento i2cdetect también sólo leyó direcciones 'en modo lento'. El sensor en el bus 1 continuó felizmente. Cambié los dos sensores. El mismo resultado después de ~330 ciclos: El sensor en el bus 3 (par no trenzado) falló, el sensor en el bus 1 (par trenzado) continuó. Así que, o bien es la diferencia en las resistencias pull-up (que hay que investigar), o bien es que el bus I2C adicional es inestable por alguna razón (como se sugiere en los comentarios de tflong01).
(2021-01-11 17:30)
El bus 3 es inestable con cualquier sensor y cualquier resistencia de pull-up. A veces funciona durante más de 100 ciclos, a veces falla en el primer intento. Cualquier sensor en el bus 1, sin embargo, es una roca estable ahora que las tapas se añaden al sensor.
0 votos
Los comentarios no son para ampliar la discusión; esta conversación ha sido trasladado al chat .