Introducción
El bus I2C es interesante porque, del mismo modo que sucede con el bus SPI, un gran número de dispositivos tienen una conexión I2C, como acelerómetros, brújulas, pantallas, etc.
Requisitos
En el esquema del que partiremos, hemos usado un M-Duino 21+, pero toda la gama de Arduino PLC industriales de Industrial Shields también se puede usar con la misma finalidad:
- Familia de controladores WiFi y Bluetooth
- 20 E/S Familia de controladores
- Familia de controladores Ethernet
- Familia de controladores GPRS / GSM
I2C protocolo
En el bus I2C, cada dispositivo tiene una dirección, que se utiliza para acceder a los dispositivos individualmente. Esta dirección puede establecerse por hardware (en cuyo caso, con frecuencia, los últimos 3 bits pueden modificarse mediante puentes o conmutadores) o completamente por software.
En general, cada dispositivo conectado al bus debe tener una dirección única. Si tenemos varios dispositivos similares, tendremos que cambiar la dirección o, si no es posible, implementar un bus secundario.
El bus I2C tiene una arquitectura maestro-esclavo. El dispositivo maestro inicia la comunicación con los esclavos y puede enviar o recibir datos de los esclavos. Los esclavos no pueden iniciar la comunicación (el maestro tiene que preguntarles), ni hablar entre ellos directamente.
El bus I2C es síncrono. El maestro proporciona una señal de reloj, que mantiene todos los dispositivos en el bus sincronizados. Esto elimina la necesidad de que cada dispositivo tenga su propio reloj para tener que acordar una velocidad de transmisión y mecanismos para mantener la transmisión sincronizada (como en UART).
Para poder comunicarse con un solo cable de datos, el bus I2C utiliza un marco amplio. La comunicación consiste en:
- 7 bits a la dirección del dispositivo esclavo con el que queremos comunicarnos.
- Un bit restante indica si queremos enviar o recibir información.
- Un bit de validación.
- Uno o más bytes son los datos enviados o recibidos del esclavo.
- Un bit de validación.
El protocolo I2C proporciona resistencias pull-up de las líneas Vcc.
El uso de resistencias suaves significa que los bordes ascendentes de la señal serán menos rápidos, por tanto, podemos usar velocidades más bajas y distancias de comunicación más bajas. Si queremos usar velocidades más altas o distancias de transmisión, debemos colocar físicamente resistencias pull-up entre 1k y 4K7.
Here puedes encontrar resistencias I2C con adaptador de riel DIN.
Ventajas y desventajas
Ventajas:
Requiere pocos cables.
Tiene mecanismos para verificar que la señal ha llegado correctamente.
Desventajas:
Su velocidad es media-baja.
No es full duplex.
No hay un sistema de verificación que nos diga que el contenido del mensaje es correcto..
Conexiones I2C típicas
Como podemos ver en esta imagen, la forma de hacer la conexión es simplemente colocando cada pin SDA y SCL de los dispositivos en las líneas generales del maestro. Aquí puede consultar nuestra Resistencia I2C Pull-Up con adaptador de riel DIN.
Hardware
Cada controlador lógico programable de Industrial Shields tiene los pines SCL y SDA. Consulte el Manual del usuario de su versión de controlador PLC industrial para ver dónde se encuentran estos pines. Aquí tienes el ejemplo arduino del controlador M-Duino 21+:
Software
Para utilizar el puerto Wire en Arduino, el estándar IDE proporciona la biblioteca "Wire.h" que contiene las funciones necesarias para controlar el hardware I2C integrado.
Función Begin:
Wire.begin(); // Starts the I2C bus as master or slave
Para solicitar bytes de un dispositivo esclavo, utilizado por el maestro.
Wire.requestFrom(); // If true, sends a stop message after the request, releasing the I2C bus.
// If true, sends a restart message after the request, the bus won't be released, which prevents another master device from requesting between messages. This allows one master device to send multiple request while in control. The default value is true.
Comienza una transmisión al dispositivo esclavo I2C con la dirección dada.
Wire.beginTransmission(); // The 7-bit address of the device to transmit.
Termina una transmisión a un dispositivo esclavo que fue iniciada por beginTransmission() transmite los bytes que fueron puestos en cola por write().
Wire.endTransmission(); // If true, endTransmission() sends a stop message after transmission, releasing the I2C bus.
// If false, endTransmission() sends a restart message after transmission. The bus won't be released, which
prevents another master device from transmitting between messages. This allows one master device to send
multiple transmissions while in control.
Wire.write(); // Will return the number of bytes written, though reading that number is optional.
Devuelve el número de bytes disponibles para recuperar con read(). Debe llamarse en un dispositivo maestro después de una llamada a requestFrom() o en un esclavo dentro del manejador onReceive().
Wire.available(); // Will return the number of bytes available for reading.
Wire.read(); // Will return the next byte received.
Wire.setClock(); // ClockFrequency: the value of desired communication clock.
Accepted values are 100000(std mode) and 400000(fast mode).
Also some processors support 10000(low speed mode),1000000(fast mode plus) and 3400000(high speed mode).
Wire.onReceive(handler); // handler: the function to be called when the slave receives data; this should take as parameter the number
of bytes read from the master and returns nothing.
Wire.onRequest(handler); // handler: the function to be called, takes no parameters and returns nothing
handler: the function to be called, takes no parameters and returns nothing.