Sobre el bus I2C y sus limitaciones.

Hola a todos.

Os voy a contar un poco en lo que consiste el proyecto que tengo en mente.

Estoy diseñando un "automata tonto" con arduino como corazón del sistema. Digo tonto por que en realidad no va a realizar (de momento) ninguna acción importante. Este automata se comunicará con el ordenador a través de RS485, con
modbus como protocolo, y será este el que decida lo que se ha de hacer. El mayor problema es que desconozco el número total de entradas o salidas que voy a necesitar y por eso estoy pensando en hacerlo modular. Digamos que es una especie de tarjeta de entradas/salidas modular para el ordenador.

Quiero poner una base que es una CPU (arduino/atmega), que será la que tenga la comunicación RS485 y despues añadir modulos según se necesite. Que necesito entradas pues un modulo de entradas, que necesito salidas, pues un modulo de salidas. Además tendrá la fuente de alimentación.

Será a esta CPU a quien conecte los modulos. Aprovechando que tengo unos MCP23017 y que puedo conectar hasta 8 con un total de 128 puntos E/S. Estos modulos serán placas independientes, a las que quiero llevar el cable con la alimentación (+5, GND) y las líneas de bus I2C (SCL, SDA) que será lo que entre y salga de dicha expansión. Los modulos se pondrán unos al lado de los otros por lo que la longitud de dicho cable rondará los 10-20 cm, tirando alto.

He probado en la protoboard a programar a ver como funcionan las entradas/salidas de los chips y me gusta como funciona. Usando simples cables desde la placa de arduino.

Pero si os digo la verdad, desconozco del todo la funcionalidad del I2C y he estado mirando por la red limitaciones fisicas para poder realizar mi proyecto: distancia máximas, limitaciones de velocidad, ruidos, etc.

Así que acudo a los expertos para que me aconsejen sobre el bus I2C y ver si mi proyecto sería viable.

PD. Lo dejo en hardware, porque de momento el proyecto está en la cabeza y no hay nada implementado. En su momento y si los administradores lo desean, lo pondré en proyectos e iré comentando los avances.

PD2. He vuelto a mirar el post, pero hoy me he machacado la mano izquierda y llevo una buena venda y mucho dolor, así que disculpen las faltas de ortografía si las hubiera.

Hay un hilo de no mas de 3 meses en el que justamete debatimos el tema distancias del I2C que puede ser su único problema. Llegamos a la conclusión que con line drivers no hay límites aparentes, asi que podrias armar la topologia que gustes. Tu único problema es el polleo pero hasta eso es un compromiso tmb.

i2c capacitancia y distancias

En cuanto las distancias no son excesivamente grandes, en el post que me comentas hablaís de 5-6 metros. Creo que si en el peor de los casos podría llegar a los 2 metros, eso si se me ocurre montar 8 modulos... Teniendo en cuenta el cable que une cada modulo y la longitud interior de la PCB...

En cuanto al polling, no creo que sea un problema, ya que el tiempo no es determinante ni critico. No le voy a pedir tiempo de respuesta de milisegundos, y creo que me los puede dar.

Lo que no sabia es lo de la capacitancia, que tendré que tener en cuenta en el diseño de la placa.

Cuando investigué para hacer algo como lo que tu quieres hacer, porque se trataba de una maquiina vieja de impresión que tenia diseminadas contactos por muchos sitios, encontré una nota que decía que puedes usar cable USB para comunicar los dispositivos I2C ya que es un cable apropiado en capacitancia por metro.
Revisalo.

Pues de momento tengo montado el módulo CPU y un modulo de entradas. He aquí unas fotos de las criaturas:

Módulo CPU:

Modulo de entradas:

Conectados y funcionando:

De momento parece funcionar bastante bien. El código del sketch se ejecuta en 7-8 ms y eso incluye la petición modbus y lectura de todas las entradas una a una.

Ahora voy a ver si diseño un módulo de salidas (16) y veo que tal responde.

Una pregunta: varias personas han preguntado por problemas cuando quieren enviar datos por i2c como floats por ejemplo. No es tu caso pero probaste hacerlo?

No lo he probado. De momento me he limitado a usar i2c con circuitos integrados, de los cuales ya está la libreria escrita y generalmente la uso.

Creo que te refieres a comunicación "a pelo" por ejemplo, entre arduinos. Y supongo que el mayor problema de es el código que se usa. Me dices que se tienen problemas con datos como floats, bueno, hay que mandar el float con 4 bytes y eso no es algo que se haga a la primera.

Dime donde lo has visto y le echo un vistazo, seguro que algo aprendo.

Buen trabajo!!

Hola Victorjam,
estoy desarrollando un proyecto muy similar al tuyo, en mi caso dispongo de un arduino que actúa como esclavo I2C y otro que actúa como maestro I2C y a su vez esclavo Modbus RTU/485.

Para ello uso las librerias "Wire" y "SimpleModbusSlave". La parte Modbus me funciona correctamente, he conseguido leer las entradas del esclavo I2C desde un maestro modbus, pero tengo problemas para activar las salidas del esclavo I2C. El código que uso para recibir la orden de activar los bits en el esclavo I2C es este:

void recibidoEvento(int howMany) // Evento de recepcion
{
unsigned char Salidas; //Las 6 primeras serán DIO y las 4 últimas RELES
while( Wire.available()) // Leemos hasta que no haya datos
{
Salidas = Wire.read(); // Leemos el byte de reles que envia el maestro
}

if((Salidas & 0x01) == 0x01) digitalWrite(DO1,HIGH); else digitalWrite(DIO1,LOW);
if((Salidas & 0x02) == 0x02) digitalWrite(DO2,HIGH); else digitalWrite(DIO2,LOW);

Pero mis salidas DO1 y DO2 no se activan, es muy extraño porque poniendo un "println" dentro del if puedo ver como la condición se cumple, entra en el if pero no se ejecuta la instrucción "digtalWrite". Y todavía más, haciendo pruebas puse como condición del if "Salidas == 1" y funcionó ... (no entiendo por qué)

Estaba probando a ajustar los tiempos de peticiones Modbus por si el problema viniese por ahí, pero he visto tu respuesta, a ti te tarda entre 7 y 8 ms! y yo las peticiones Modbus no las hago con tanta frecuencia...

¿Se os ocurre algo de por qué no se ejecuta la instrucción "digitalWrite" a pesar de que la condición del if se cumpla?

¿Podrías decirme que librerías usas y como gestionas las comunicaciones I2C y Modbus simultáneamente?

Muchas gracias