Conexión Raspberry Pi Zero al sensor (con interfaz de bus I²C o SPI) a larga distancia

RESUMEN:

Esto es lo que funciona:

Raspberry Pi (I²C) <-> 1 m de cable <-> sensor (I²C)

Esto es lo que estoy tratando de hacer (no funciona, de ahí la pregunta):

Raspberry Pi (I²C) <-> cable de 30 m <-> sensor (I²C)

La "ecuación" a resolver es así:

Raspberry Pi (I²C, SPI y otros) <-> X <-> cable de 30 m <-> Y <-> sensor (I²C/SPI)

Resolver para X e Y

DETALLE:

Estoy trabajando con un montón de sensores configurados en una red/topología en estrella.

Ingrese la descripción de la imagen aquí

Se utiliza una Raspberry Pi Zero como "hub" central, donde se recopilan y procesan todos los datos del sensor. Todos los sensores son iguales y utilizan un protocolo I²C (también ofrecen una interfaz de bus SPI). Dicho esto, actualmente tengo un multiplexor I²C conectado a Raspberry Pi Zero para habilitar múltiples dispositivos configurados con la misma dirección de hardware I²C. Todos los sensores están conectados a la Raspberry Pi Zero mediante un cable blindado 26/4. Actualmente todo funciona según lo previsto.

Con la prueba de concepto en su lugar, ahora quiero extender el alcance de la topología/red en estrella en 20-30 m en cada conexión de sensor-hub. Pensé que podría usar un cable más largo, pero aparentemente el protocolo I²C limita la longitud de la extensión del cable. He leído varios trucos/soluciones sobre cómo extender la longitud, como bajar la frecuencia, cambiar resistencias, etc.

Seré honesto; No soy ingeniero eléctrico, por lo que algunas de esas cosas parecen un poco más avanzadas, y realmente no tengo el conocimiento o las herramientas para evaluar la efectividad de ese tipo de altercados.

De todos modos, investigué un poco y encontré varios chips que potencialmente puedo implementar como una solución más "plug and play". Dicho esto, gran parte del material que leí era de hace años, y no sé si esas soluciones siguen siendo viables. Aquí están las fichas que he encontrado.

  • P82B96, que aparentemente tiene un sucesor: ¿PCA9600?
  • P82B715

Comparando los dos, he leído que el primer elemento es más versátil. También he leído que el segundo elemento es más antiguo y requiere mucha energía , lo que hace que las implementaciones remotas (alimentadas por batería) sean menos prácticas. Recientemente me encontré con otra solución, en la que usa un convertidor de I²C a 1 cable, ya que el protocolo de 1 cable no es tan sensible a los aumentos en la longitud del cable.

  • DS28E17 (y potencialmente agregar DS2484 en el concentrador)

Esto parece una solución potencial, pero no he escuchado mucho acerca de que otros lo usen. La única fuente de información que obtuve fue la página web y los videos de la empresa. Si leí la hoja de datos correctamente, la solución tampoco requiere mucha energía. Me pregunto si otros están comprando lo que están vendiendo y si funciona.

De todos modos, de nuevo, no soy ingeniero eléctrico, así que me vendría bien un consejo. Parece que el protocolo I²C es lo que utilizan muchos sensores (al menos en el mercado integrado de bricolaje), así que imagino que no soy el único que enfrenta el problema de extender la comunicación I²C .

Estos son los requisitos de mi solución:

  • extienda cada sensor fuera del cubo central 20-30 m
  • debe ser una conexión por cable
  • bajo consumo de energía (estoy ejecutando la red con batería)

EDITAR: Investigué un poco más durante el fin de semana y me encontré con este conjunto de chips (MCP25 *), que suena como una interfaz CAN a SPI. ESTO NO FUNCIONARÁ... MIRA los comentarios de @Maple a continuación.Ciertamente no digo que sea el único conjunto de chips que ofrece esta conversión, es solo el primero que encontré. Los sensores que estoy usando tienen una interfaz de bus SPI, así que creo que podría conectar directamente uno de estos chips a cada sensor. Solo tengo 5 nodos de sensores conectados a Raspberry Pi en mi topología en estrella, por lo que creo que estoy dentro de las limitaciones en cuanto a la cantidad de nodos que puede admitir el bus CAN. La pregunta sería entonces cómo configurar el resto del bus. ¿Simplemente conectaría un extremo de un cable Cat 5 a uno de los chips CAN a SPI? Luego, el cable recorrería 20-30 m hasta la Raspberry Pi. ¿Podría entonces agregar un chip más en la Raspberry Pi para "invertir" la conversión y comunicarme con la Raspberry Pi? ¿Habría alguna forma de conectar los cinco nodos a la misma interfaz/chip? Yo no' No creo que Raspberry Pi tenga soporte de bus CAN nativo, pero obviamente tiene SPI (¿creo que solo puedes conectar dos dispositivos?). Si esos chips pudieran agregarse en los nodos sensores, ¿qué se necesitaría para conectar la Raspberry Pi?

EDIT_2: Después de recopilar más conocimientos de los comentarios de todos (gracias), decidí seguir investigando. ¡Sin sorpresa, me encontré con otra posible solución! Estaba leyendo los comentarios en uno de los enlaces que señalé anteriormente , y alguien mencionó un chip PCA9615 . Una búsqueda rápida en Google en este chip presenta "I²C diferencial". Desde el punto de vista de un profano, esto suena como una solución que no requeriría que cambie mi software. Aparte de eso, no conozco completamente los pros y los contras o si cumple con los tres requisitos enumerados. Leeré más en la hoja de datos, pero si alguien tiene comentarios sobre esta solución, ¡soy todo oídos!

20-30 m es un poco exagerado para el bus I2C, a menos que lo ejecute a una frecuencia de reloj de 1 kHz. Y tenga una fuente de alimentación central desde el mismo concentrador raíz. Y utilice cables blindados. Es un gran tramo.
La potencia de la señal debe compararse con la potencia del ruido cercano y la relación de impedancia de acoplamiento con el bus.
@NickAlexeev Sí, creo que me he encontrado con esa encrucijada y estoy tratando de evitar cometer el error de sobreutilizar i2c
@ThatsRightJack Volver a EDITAR. No existe tal cosa como la interfaz "spi-to-can". Esos son controladores CAN con interfaz SPI. Su MCU envía comandos SPI al controlador para que envíe/reciba datos a través de CAN. Básicamente, el controlador CAN es el dispositivo esclavo, al igual que su sensor SPI. No puede conectar dos sensores juntos aunque ambos tengan interfaces SPI.
@Maple ¿Está diciendo que la Raspberry Pi (SPI) <-> controlador CAN <-> cable de 30 m <-> controlador CAN <-> Sensor (SPI) tiene demasiados "esclavos" conectados entre sí?
Estoy diciendo que "controlador CAN <-> Sensor (SPI)" no tiene ningún sentido. El controlador CAN es exactamente como el propio sensor. No se pueden conectar dos sensores juntos. Solo puede conectar el dispositivo SPI a MCU, porque debe ser controlado por su código. El sensor no tiene código, no puede controlar el controlador CAN.
Además (aunque no importa en este caso) no puede conectar el controlador CAN directamente al cable. Necesita chips transceptores CAN entre los controladores y el cable. El que te sugerí en mi respuesta.
Con respecto al chip PCA9615. Es solo otro transceptor de un solo extremo a diferencial. Y no muy bueno, en mi opinión. La velocidad máxima cae rápidamente más allá de los 3 m de longitud del cable y el consumo de energía es bastante alto. Por cierto, la mayoría de las soluciones propuestas hasta ahora no requerían ningún cambio de software.

Respuestas (4)

La solución Onewire con el DS28E17 es la que funciona principalmente de forma inmediata. Incluso puede usar el host bitbanging (por ejemplo, en GPIO4) y salirse con la suya casi sin hardware adicional. Cada DS28E17 en el bus aparece automáticamente como un adaptador de host I²C, no se necesitan cambios de software. Inconvenientes:

  • El Onewire tiene que ser un autobús, no una estrella. Si tenía un diseño de estrella, use lóbulos para convertirlo en un autobús físico. O use varios buses Onewire, el DS2482-800 ofrece ocho.
  • Es de baja velocidad, solo alrededor de 15 kbaudios con mucha sobrecarga. No puede usarlo para sensores de alto rendimiento.

Olvídese del DS2484 detrás de una idea DS28E17 . Eso simplemente cuadra la sobrecarga, tanto enviar unos pocos bytes toma un segundo más o menos. (DS28E17 detrás de un DS2484 o DS2482-800 por el contrario es el uso previsto y evita el bitbanging).

La razón por la que otras personas aún no usan mucho ese chip es que salió en 2016 y el controlador de Linux está disponible desde el kernel 4.15.

(Y una precaución: el DS28E17 es un dispositivo de solo 3,3 V).

Creo que " incluso puede usar el host bitbanging" debería reemplazarse por "tiene que usar bitbanging" para conectarse a Raspberry Pi. AFAIK no hay pasador de drenaje abierto bidireccional en RasPi. Aparte de eso, esta es sin duda una opción convincente.
Simplemente conectando GPIO4 con un pullup de ~1.5kΩ a 3.3V funciona muy bien. El controlador del núcleo Onewire cambia entre salida y entrada de baja tensión. Esto es exactamente lo mismo que un drenaje abierto bidireccional. El controlador del kernel DS28E17 enumera automáticamente todos los DS28E17 en el bus y los presenta al usuario como hosts I²C.
"el controlador del kernel cambia entre la salida y la entrada de baja extracción". también conocido como "poco golpeando"
También podría, por ejemplo, usar un DS2482-800 en el I²C local para crear 8 buses Onewire, luego usar uno o más DS28E17 en cada uno de estos para obtener buses I²C remotos. Lo único desaconsejable es poner otro puente I²C-Onewire detrás del DS28E17. He editado esto en mi respuesta.
Estoy un poco perdido con su uso de "detrás" y contra qué advierte exactamente. Solo hay dos conexiones posibles: I2Cmaster - DS2484/DS2482-800 - 1 cable, o 1 cable - DS28E17 - I2Cslave. El primero se puede sustituir por golpes de bits.
@Maple ¿Quizás la misma trampa en la que caí? I2Cmaster <-> DS2484/DS2482-800 <-> 1 cable <-> DS28E17 <-> I2Cslave. Como señaló con mi solución CAN, ¿esto no funciona?
@ThatsRightJack Esto funciona , porque estos chips no son controladores, son puentes. Esto es exactamente para lo que están hechos.
Lo que "funciona" pero apesta mucho es usar otro DS2484 en lugar del esclavo I²C en el DS28E17, y luego tener otra sección Onewire. Es demasiado lento. Tengo la impresión de que estás planeando algo como esto porque hablaste de un "centro". Pero ahora me doy cuenta de que llamaste a la Raspberry Pi "el centro".
¿Quién en su sano juicio convertiría 1 cable en I2C y luego volvería a 1 cable? Tenga en cuenta que DS2484 no es solo un esclavo I2C. Tiene registros internos de estado y configuración, lo que supone una conexión a la MCU host. Finalmente entiendo contra qué advierte, pero dado que es una configuración poco realista, esta advertencia no ayuda, solo crea confusión.
En realidad, eso era lo que alguien quería crear cuando pidió un controlador DS28E17 en la lista OWFS. La idea era tener un divisor de bus, tal.
@Janka Perdón por la confusión sobre mi terminología (es decir, el uso de la palabra "hub"). Como se muestra en la imagen, se supone que Raspberry Pi es el nodo central, que recopila todos los datos de los 5 nodos sensores.
@Maple OK, solo para aclarar esta solución potencial, así es como veo las conexiones para la topología en estrella: Raspberry Pi (I2Cmaster) <-> DS2482-800 ("puente" i2c a 1 cable en 5 buses individuales) < -> Cable de 30 m (cada una de las 5 patas del sensor) <-> DS28E17 ("puente" de 1 cable de regreso a i2c) <-> sensor (I2Cslave). Tal vez el DS2482-800 se pueda reemplazar con golpes de bits, pero dado que tengo 5 buses, supongo que usaré el hardware. Según sus comentarios, creo que esto funcionaría desde el punto de vista de la comunicación.
@ThatsRightJack Finalmente lo hiciste bien;). Bit banging 5 buses es una gran carga para la CPU, incluso con un bus tan lento como 1-Wire, es mejor adherirse al hardware. En caso de apuro, puede usar 5 chips DS2484 en el lado Pi, todos en el mismo hardware I2C. Sí, esto funcionaría, pero primero verifique sus requisitos para las velocidades de datos del sensor. Si necesita más de 16 kbit, entonces necesita algo mejor (más rápido) que 1 cable.
@ThatsRightJack Por otro lado, si necesita mucho menos que eso, y algunos de sus sensores están ubicados cerca uno del otro, entonces puede colocar varios DS28E17 en el mismo bus de 1 cable en diferentes puntos, creando una topología mixta.
@Maple Sí, miraré un poco más de cerca las velocidades de datos y las especificaciones de energía para ver si la solución funcionará. Al menos desde el punto de vista de la configuración, ¡ha sido de gran ayuda!
@Maple ¿Puede dar más detalles sobre lo que quiere decir con "pero primero verifique sus requisitos para las velocidades de datos del sensor. Si necesita más de 16 kbit, entonces necesita algo mejor (más rápido) que 1 cable"? Miré la hoja de datos y no veo nada que me llame la atención al proporcionar esta información. Tal vez si fueras tan increíble como para echar un vistazo rápido a la hoja de datos ( te.com/usa-en/product-CAT-BLPS0013.html ) y decirme qué es lo que debería estar buscando.
La hoja de datos indica que la conversión tarda unos 8,22 ms. Iniciar una conversión tomará alrededor de 15 ms a través del DS28E17, leyendo el resultado otros 15 ms. Por lo tanto, se trata de 40 ms por muestra o 25 muestras por segundo. Con I²C puro, podría alcanzar 100 muestras por segundo.
@Janka 20 bits para iniciar una conversión y 38 bits para leer el resultado, por lo que los números serán ligeramente diferentes, pero en el mismo estadio. Obtuve un máximo teórico de 119 muestras / s para I2C puro, pero la vida real nunca juega junto con la teoría de todos modos.

Sospecho que hay otros tipos de extensores I2C, pero solo estoy familiarizado con dos: búferes (como PCA9605, P82B715) y divisores (como PCA9600, P82B96). Todos ellos diseñados para aislar la capacitancia de bus más alta de los recorridos largos al aumentar la capacidad de sumidero de las salidas. Parece que todos los búferes se están acercando al EOL ahora.

Tenga en cuenta, sin embargo, que aumentar la capacidad de hundimiento básicamente significa aumentar las corrientes, lo que no es un buen augurio para su requisito de bajo consumo de energía.

Hay muchas notas de aplicación que recomendaría leer, como las sugeridas por @ali-chen AN11084 o AN11075 , AN10658 . Sin embargo, es interesante que incluso aquellos que usan pares trenzados en su topología todavía dependen de la señalización de un solo extremo. Estoy bastante seguro de que cualquier nota de aplicación o dispositivo que elija debería funcionar bien.

Sin embargo, lo que me gustaría sugerir es echar un vistazo a este dispositivo primero. Lo describen como "extensor PCA9600". Sin embargo, en lo profundo de la descripción técnica, puede encontrar un uso inteligente del chip transceptor CAN PCA82C251 para transformar señales I2C (divididas en Tx, Rx por PCA9600) en señales diferenciales.

Lo anterior ya tiene la ventaja de una alta inmunidad al ruido sin ningún tipo de blindaje. Y puede brindarle comunicación de alta velocidad en distancias de 100 m. Pero aquí hay otro truco para ti: el bus CAN puede funcionar a 3,3 V con la misma velocidad y fiabilidad que a 5 V, mientras que al mismo tiempo reduce el consumo de energía en más del 50 %. Creo que esto justifica una mirada más cercana a su aplicación.

Esta nota de NXP describe métodos para lograr que el sistema de bus I2C tenga más de 300 m de largo a 60 kbits/s, AN11084 . Las soluciones incluyen líneas trenzadas, repetidores PCA9605 y lógica de generación de retardo en cada esclavo. Buena suerte.

También argumento para mirar esto . https://en.m.wikipedia.org/wiki/Señalización_diferencial_de_bajo-voltaje

Es inmune al ruido de modo común, independiente de la conexión a tierra y también funciona durante unas pocas decenas de metros fácilmente y aún proporciona una alta tasa de bits en comparación con el estándar I2C.

Si puede proporcionar los esquemas del diagrama de bloques de la conexión prevista, se puede elaborar un mejor esquema para reducir aún más el consumo de energía.

M LVDS (multi LVDS) puede ser el candidato adecuado. Puede usar canales individuales para reloj y datos I2C.

La línea de datos es bidireccional pero es posible manejarla mediante arbitraje.