¡Acceso ilimitado 24/7 a todos nuestros libros y vídeos! Descubra la Biblioteca Online ENI. Pulse aquí
¡Acceso ilimitado 24/7 a todos nuestros libros y vídeos! Descubra la Biblioteca Online ENI. Pulse aquí
  1. Libros
  2. Arduino
  3. El bus I²C
Extrait - Arduino Hágalo jugar a los trenes
Extractos del libro
Arduino Hágalo jugar a los trenes Volver a la página de compra del libro

El bus I²C

Descripción

1. Las características

Después de un capítulo consagrado al protocolo DCC, he aquí otro sobre el protocolo I²C. Estudiar un protocolo siempre es un poco tedioso. Sin embargo, una implementación al final de este capítulo lo hará un poco más atractivo. Esta descripción es necesaria porque es el protocolo que se utilizará para las comunicaciones entre los Arduinos.

El bus I²C es un bus serie creado inicialmente por Philips para equipar sus aparatos electrónicos, como televisores, videograbadoras o lavadoras. Se ha mejorado regularmente y ahora sirve sobre todo para aplicaciones de domótica. Pero también se puede encontrar integrado en los conectores de vídeo VGA e incluso HDMI como bus de control. Asimismo se puede encontrar en productos de otros fabricantes bajo los nombres TWI (Two Wire Interface) o TWSI (Two Wire Serial Interface).

Sus principales características son las siguientes:

  • Bus serial sincrónico bidireccional

  • Operación maestro-esclavo

  • Comunicación a través de dos cables, más la tierra

  • Señales eléctricas de 5 V o de 3,3 V para los más recientes

  • Velocidad estándar de 100 kbit/s

  • Velocidades rápidas de 400 kbit/s, 1 Mbit/s y 3,4 Mbits/s

  • Direccionamiento de periféricos en 7 o 10 bits

Aunque está diseñado para usarse en el interior de un dispositivo electrónico, se puede hacer que una señal I²C recorra distancias bastante largas, lo que permite utilizarlo para cablear el bus de comunicación entre los distintos elementos de una red ferroviaria. Obviamente, hay que tomar algunas precauciones para proteger las señales de las interferencias: utilizar cables blindados (apantallados), reducir el valor de las resistencias pull-up (de polarización), limitar la velocidad del bus. Para realizar transmisiones fiables en distancias más largas, basta con utilizar amplificadores de bus.

Los Arduinos también disponen de un bus SPI, que no fue elegido por varias razones:

  • El bus SPI requiere más señales para comunicarse.

  • No hay direccionamiento, por lo que se necesitan tantas señales de selección como circuitos se han de controlar.

  • La distancia máxima es mucho menor.

No se pueden mezclar circuitos de 5 V y 3,3 V en el mismo bus I²C...

La biblioteca

1. Algunas explicaciones

Las tarjetas Arduino disponen de forma integrada de las señales SDA y SCL, lo que permite manejar periféricos I²C. Tenga en cuenta que, en el Arduino Uno y Nano, estas señales son comunes con los pines A4 y A5, por lo que hay que elegir. En Arduino Leonardo y Mega, estas señales están disponibles en pines separados.

La librería Wire es la que contiene todas las funciones que permiten acceder al bus I²C. Es posible utilizarlo tanto como maestro o como esclavo. Su documentación completa está disponible en la siguiente dirección: https://www.arduino.cc/en/Reference/Wire

La biblioteca se encarga de todo, por lo que no es necesario conocer forzosamente los detalles del protocolo, aunque siempre es interesante entender cómo funciona. Dicho esto, en algunos casos puede ser útil recurrir a un bus I²C administrado por software, ya sea para gestionar simultáneamente un bus I²C como maestro y el otro como esclavo o para liberar las entradas analógicas A4 y A5 en los Arduinos Uno y Nano.

2. El lado maestro

Wire.begin()

Inicializa la interfaz I²C en modo maestro. No hay nada más que hacer.

Wire.beginTransmission(address)

  • address: dirección del circuito esclavo que se debe contactar

Inicia una transmisión con el circuito cuya dirección se pasa como parámetro. Esta función se utiliza junto con las funciones Wire.write y Wire.end para enviar datos a un circuito esclavo. 

Wire.write(value)

Wire.write(string)

Wire.write(data...

Convenciones

1. Los conectores

No existe un conector estandarizado para el bus I²C, esto es algo normal: este bus nunca fue diseñado para ir más allá de la carcasa de un dispositivo electrónico. No obstante, se pueden encontrar implementaciones en varias generaciones de conectores de vídeo.

  • Péritel (SCART): SDA en el pin 12, SCL en el pin 10

  • VGA: SDA en el pin 12, SCL en el pin 15

  • HDMI: SDA en el pin 16, SCL en el pin 15

Si nos centramos en las interfaces I²C para Arduino, no es mucho mejor. Hay muchas variantes de cableado, tanto en lo que respecta al tipo de conector como al orden de las señales. Sin embargo, si se quiere tener conexiones fiables, se recomienda que los cables de datos y de reloj no estén uno al lado del otro, para evitar las perturbaciones por acoplamiento capacitivo. Así, si se utiliza cable plano flexible (Dupont), la fuente de alimentación debe colocarse en el centro para separar bien las señales SDA y SCL y, si se utiliza un cable de par trenzado (por ejemplo, un cable Ethernet), SDA y SCL deben colocarse en pares separados.

El bus I²C está formado por tres hilos, pero se agradece un hilo de alimentación adicional si se quiere alimentar un circuito externo. Por lo tanto, un conector HE13 con cuatro contactos es lo mínimo necesario; una conexión que se encuentra a menudo en las placas de expansión de Arduino, aunque el orden de los cables, por desgracia, es muy variable, lo que requiere una atención muy especial al conectar un nuevo dispositivo I²C.

HE13-4

1

2

3

4

Señal I²C

SDA

+5 V

GND

SCL

Para disponer de dos fuentes de alimentación (5 V y 7,5 V) simultáneamente, se puede pasar a seis cables, lo que también permite, en caso necesario, llevar una señal de interrupción. Como el conector HE13 no es muy fiable, los circuitos propuestos en este libro estarán equipados principalmente con conectores HE10. Los conectores HE10 tienen dos filas de conectores, lo que permite engarzarlos en el cable de cinta flexible: los números de los pines del conector corresponden también a los números de los hilos del cable. Esto permite enlazar varios circuitos. Dependiendo de lo que se encuentre disponible, se pueden utilizar conectores de 6 o 10 contactos. El pin 1 de los conectores está marcado...

El verificador de bus

1. El principio del eco

Cuando se verifica una red, siempre es útil saber si un circuito responde para poder diagnosticar los problemas. Del mismo modo que probamos la comunicación entre dos máquinas conectadas por el protocolo IP mediante el comando ping, se puede desarrollar un protocolo de prueba entre periféricos I²C. El principio es siempre el mismo, es un eco: basta con enviar los datos al periférico consultado y este los devuelve. Una comparación entre lo enviado y lo recibido es suficiente para garantizar la fiabilidad de la comunicación.

Así pues, se necesitan dos comandos para que el circuito funcione.

sendData: 0x22

Envía los datos del circuito maestro al esclavo. El segundo byte indica el número de bytes enviados, seguido de los bytes que se deben enviar.

recvData: 0x11

Recibe los datos devueltos por el esclavo. Este comando va seguido de un único byte que indica el número de bytes que debe devolver el esclavo.

2. El programa del lado maestro

El siguiente código es un fragmento de la función I2CTest del programa AT-MULTI2 que se presentó en el capítulo Los otros circuitos. En primer lugar, reservamos dos bloques de memoria para almacenar los datos enviados y los recibidos, lo que nos permitirá realizar la comparación.

#define DATASIZE 4 
 
 byte writeData[DATASIZE]; 
 byte readData[DATASIZE]; 

A continuación, tenemos que llenar esos cuatro bytes con algunos datos. Con la llamada a la función micros() se obtiene el número de microsegundos transcurridos desde el arranque del procesador, lo que permite disponer de valores variables. El valor leído se copia byte por byte en la tabla writeData.

unsigned long micSec = micros() 
 byte i; 
 for(i=0; i<DATASIZE; i++) 
 { 
   writeData[i]=micSec&0xFF 
   micSec>>=8; 
 } 

Luego, los datos se envían al circuito encargado de responder, situado en la dirección especificada en i2c_addr usando...