INTRODUCCIÓN AL I2C
en Arduino.

INTRODUCCIÓN AL I²C-bus.

Hablar del I²C bus, en nuestros días es, poco menos que arriesgado, hay que afinar mucho en lo que se dice, ya que cualquiera ha realizado su descripción y creo realmente que hay muy buenas descripciones y de esas, se bebe el conocimiento, por parte de muchos aficionados a la electrónica, cuando éste, tiene que utilizar dicha técnica de transmisión de datos como es el I²C-bus. I²C es un acrónimo de “Inter-Integrated Circuit”. En esta ocasión, espero exponer mi puntual experiencia y dar un poco de luz a los que estén interesados en conocer los pasos a seguir para utilizar con éxito esta técnica de transmisión I²C-bus.

Hace ya muchos años cuando tuve conocimiento del sistema I2C bus, en aquellos momentos mi trabajo estaba relacionado directamente con la electrónica más puntera de la época, lo que se conocía como, “la cresta de la ola”. Ciertamente que no estaba en mi camino el hacer prácticas (por motivos que no vienen al caso) de esta novedosa técnica que, presentó la firma “Philips Semiconductors” (ahora NXP) a principios de los 80s, sin embargo, si puse en manos de bastantes ingenieros de la época y las Universidades de la zona, la extensa información que proveía la mencionada empresa.

Los ingenieros de “Philips” vieron la necesidad de la simplificación y normalización de las líneas de datos que viajan entre los diversos circuitos integrados en sus productos. Su solución fue el bus I2C. Esto redujo el número de cables a dos (SDA – los datos, y SCL – reloj).

Esta documentación, nace sabiendo que existen otras muchas más profundas, solamente pretende explicar desde mi punto de vista que es y como se comporta superficialmente un bus I²C, por si alguien necesita un detalle diferente.

Un motivo para usar el I2C

Beneficios para diseñadores y fabricantes del I2C-bus. La mayoría de los sistemas integrados tienen uno o más dispositivos (en electrónica de consumo, telecomunicaciones y electrónica industrial, a menudo hay muchas similitudes entre los diseños aparentemente no relacionados), están conectados al procesador principal o microcontrolador. Estos dispositivos realizan funciones específicas, como el puerto UART o la conversión A/D. A veces usamos expansores de puerto, porque no hay suficiente pines del microcontrolador o es mucho más fácil a los atajos de la ruta sólo unos pocos para controlar en una parte remota los pines de E/S de la placa. Una forma muy popular para conectar varios dispositivos con un microcontrolador es por bus I2C. Por ejemplo, casi todos los sistemas incluyen:

· Algunos de control inteligente, por lo general un solo chip microcontrolador.
· Medidas generales de uso de circuitos como los controladores de LCD, E/S remotas, puertos, RAM, EEPROM, 
   o convertidores de datos.
· Orientadas a la aplicación, tales como circuitos de sintonización digital y circuitos de procesamiento 
   de señales para sistemas de radio y video, o DTMF generadores para teléfonos con marcación por tonos.

Para aprovechar estas similitudes, con el beneficio de ambos sistemas, diseñadores y fabricantes de equipos, así como para maximizar la eficiencia del hardware y la sencillez del circuito, Philips desarrolló un sencillo bus bidireccional de 2 cables, para un eficiente control inter-IC. Este bus se le llamó el Inter IC o I2C-bus.

Todos los dispositivos compatibles de I2C bus, incorporan una interfaz en el chip que les permite comunicarse directamente entre sí a través del bus I2C. Este concepto de diseño resuelve muchos de los problemas de interconexión encontrados en el diseño de circuitos digitales de control.

Por mi parte, he de decir que, hasta hace algún tiempo, no había puesto ningún empeño en ampliar mis conocimientos sobre la transmisión de datos, tal vez, por que no había tenido la necesidad. Sin embargo hace poco más de un año cuando empecé a utilizar en mis ratos libres el Arduino, descubrí que disponía de dos patillas que están dotadas de este protocolo o sistema de transmisión y bueno, mi interés no paso de la curiosidad del momento, por lo que no entre en detalle.

Por aquellos días, tuve un encuentro casual con un amigo que, me propuso realizar un sistema de acceso a una empresa. En el proyecto por denominarlo de algún modo, se debía controlar los vehículos que entraban y salían de la empresa, por puertas de entrada y salida, el sistema debía enviar datos a un PC central, en el cual se encuentran los permisos de los vehículos autorizados... En cierto momento del proyecto, se presentó la necesidad de utilizar el sistema del bus I2C, para economizar en las E/S del Arduino y ese es el momento en el que surge la necesidad de conocer más a fondo el modo en que se basa y como trabaja el mencionado protocolo.

Mis primeros pasos fueron la adquisición de datos, aquellos libros de Philips que guarde, ahora serían vitales, además de información que, extraje de varios documentos de dominio público que, se encuentran en la red y otros libros actuales que lo relacionan con Arduino, aunque ahora, quiero hablar del I2C-bus en general.

Algunas de las características de la I2C-bus:

· Sólo son necesarias dos líneas de bus, una línea de datos serie (SDA) y una línea de reloj serie (SCL).
· Cada dispositivo conectado al bus es un software direccionable por una dirección única y simple 
  relación existente en todo momento maestro/esclavo. Maestros pueden operar como maestro o como 
  maestro transmisor-receptor.
· Es un verdadero multi-maestro de bus incluyendo la detección de colisiones y el arbitraje para prevenir 
  la corrupción de datos, si dos o más maestros al mismo tiempo inician la transferencia de datos.
· 8-bits orientados Serie, transferencias de datos bi-direccional, se puede hacer a velocidades de 
  hasta 100 kbit/s en el modo normal, hasta 400 kbit/s en el modo rápido o de hasta 3,4 Mbit/s en el modo 
  de alta velocidad.
· En el chip el filtrado rechaza los picos en la línea de bus de datos preservando la integridad de 
  los datos.
· El número de circuitos que pueden ser conectados al mismo bus sólo está limitado por una capacidad 
  máxima del bus de 400pF.

I2C-bus. Beneficios de diseño.

El I2C-bus permite un sistema rápido, al progreso de diseño, directamente compatible, desde un diagrama de bloques funcionales a un prototipo. Por otra parte, puesto que directamente puede 'pegar' sobre el I2C-bus sin ningún tipo de interfaz externos adicionales (como una mochila), permite que un prototipo de sistema ser modificado o actualizado simplemente por "pegar" o "despegar" hacia o desde el bus. Todos ellos tienen:

· El consumo de corriente extremadamente bajo.
· Alta inmunidad al ruido.
· Suministro de amplio rango de tensión.
· Amplia gama de temperaturas.

Además de estas ventajas, una amplia oferta circuitos integrados CMOS diseñados en I2C-bus de características especiales compatibles que son particularmente atractivos para los equipos portátiles y con batería de respaldo de sistemas.

Es sabido que el llamado "playgrund" de Arduino tiene una descripción sobre el I²C - TWI (Two-Wire Interface), se trata del bus I²C. En dicho documento, se habla del I²C-bus y se refiere a enlaces relevantes, para los que tengan interés en el tema.

Entre la documentación de TWI (Two-Wire Interface) que es incompleta y no explica cada función, como corresponde a una función I²C-bus, los ejemplos de código que son anticuados y de vez en cuando incorrectos, mi carencia de familiaridad con bus I²C en general, además, no teniendo un circuito bus I²C en funcionamiento como referencia y desde luego mis despistes y mis muchos errores, esto puso por un momento a relucir una falta de experiencia desconcertante por mi parte. Esto para mi, fue un reto.

Después, me procuré una serie de circuitos integrados que tuvieran este protocolo entre sus cualidades, encontré bastantes dispositivos basados en este protocolo del bus I²C, entre ellos el PCF8574A y ya sólo tenía que poner manos a la obra, practicar y practicar, buscar la forma de servirme de aquellas posibilidades y adaptarlas a mis necesidades. No pasó mucho tiempo para tener el éxito esperado, al principio estuvo el tema de direccionar cada dispositivo, todos los dispositivos diseñados para funcionar en este bus poseen su propia y única dirección de acceso, preestablecida por el fabricante. Poder leer una dirección, ni que decir, de escribir en una dirección, recomiendo leer las HD del fabricante para conocer dicha dirección. Con esto quiero decir a los interesados que, es bastante fácil aprender y aplicar el protocolo del bus I²C.

El chip PCF8574 (ver hoja de datos), implementa el bus I2C en modo esclavo y ofrece ocho Entradas/Salidas independientes. Por lo tanto, usted puede utilizarlo fácilmente, para agregar 8 pines digitales a la placa Arduino. El PCF8574 consta de 3 pines (A0, A1, A2) para indicar su dirección de esclavo. Esto admite que pueda conectar hasta 8 unidades en el mismo bus y obtener 64 pines extra. Y, lo que es más, hay otra versión, la PCF8574A con exactamente las mismas especificaciones, salvo que las direcciones se generan en un rango diferente. Lo que puede añadir 64 más pines digitales. ¿Se imagina un Arduino con 128 pines digitales? Veamos como funciona.

EL I²C-BUS.

El I²C bus, no tan sólo son dos cables, usados para realizar una transmisión bidireccional de datos entre distintos sistemas gobernados por microcontroladores de forma eficaz. Se trata de, un bus bidireccional que utiliza dos líneas, una de datos serie (SDA) y otra de reloj serie (SCL), que requiere resistencias de polarización a positivo. SCL es la línea de reloj, se utiliza para sincronizar todos los datos SDA de las transferencias durante bus I²C. SDA es la línea de datos.

Las líneas SCL y SDA están conectadas a todos los dispositivos en el I²C bus. Ambas líneas SCL y SDA son del tipo drenador abierto asociados a un transistor de efecto de campo (o FET), es decir, un estado similar al de colector abierto. Esto significa que el chip puede manejar su salida a BAJO, por tanto, no puede manejar a ALTO. Para que la línea pueda ir a ALTO, se deben proporcionar resistencias de polarización a 5V. Necesita de una resistencia de la línea SCL a la línea de 5V y otra de la línea SDA a la línea de 5V. Sólo necesita un conjunto de resistencias de RPA (pull-up) para todo el I²C bus, no son necesarias para cada dispositivo. La alimentación del sistema, debe tener una masa común. También, puede haber una alimentación compartida que se distribuye entre los dispositivos.

Los dispositivos en el I²C bus son maestros o esclavos. El maestro es siempre el dispositivo que maneja la línea de reloj SCL. Los esclavos son los dispositivos que responden al maestro. Un esclavo no puede iniciar una transferencia a través del I²C bus, sólo un maestro puede hacer esa función. Generalmente son, varios esclavos en el I²C bus, sin embargo, normalmente hay un solo maestro. Es posible tener varios maestros, pero es inusual y no se comentará aquí. Los esclavos nunca inician una transferencia. Tanto el maestro como el esclavo puede transferir datos a través del I²C bus, pero la transferencia siempre es controlada por el maestro.

Red I²C

Todas las direcciones I²C bus son de 7 bits o 10 bits. Esto significa que se pueden tener hasta 128 dispositivos en el bus I²C, ya que un número de 7bit puede estar de 0 a 127. El I²C tiene un diseño de espacio de referencia de 7 bits de direcciones, reservado con 16 direcciones, de modo que finalmente, pueden comunicarse en el mismo bus un máximo de 112 nodos. El número máximo de nodos está limitado por el espacio de direcciones y también por la capacidad total de los buses de 400 pF, lo que restringe la práctica de comunicación a distancias de unos pocos metros.

Cuando se envía la dirección de 7 bits, siempre seguimos enviando 8 bits. El bit extra (bit 8) se usa para informar al esclavo si el maestro está escribiendo o leyendo de él. Si el bit es 0, está escribiendo el maestro al esclavo. Si el bit es 1, el maestro esta en la lectura del esclavo. Existen disposiciones en la norma de I²C para entornos multi-master, así como de 10 bits frente a la más simple y la más comúnmente usada, es la configuración de un solo maestro, de 7 bits de direccionamiento. Yo se que, la localización de la dirección de 7 bits en la parte superior del byte, es una fuente de confusión para los recién llegados.

Por ejemplo, para escribir en la dirección 0x21, realmente se tiene que enviar 0x42, que es el 21 desplazado 1 bit a la izquierda, para indicar el bit de lectura/escritura (R/W).

 b 00100001  = 21 h; b00100001 x 10 = b01000010;
 b 01000010  = 42 h

Esto es la base del protocolo I²C-bus, el bus tiene dos funciones para los nodos: maestro y esclavo. El resultado de este sistema produce un anillo compuesto por dos vías (hilos) para el desarrollo de la función de comunicarse entre sí los dispositivos interconectados a las mencionadas vías, esto permite comunicarse entre ellos mismos con un protocolo que, consiste en que en cada momento hay un MAESTRO y el resto son ESCLAVOS. Un símil sería que, -mientras uno habla, el resto escuchan-, es decir, uno escribe y el resto leen.

Condiciones Start y Stop

En la figura anterior se puede apreciar que, la condición START está definida, cuando la señal de reloj SCL permanece estable ALTO (H) además, el nivel de la señal de "no reconocimiento", debe ser también ALTA (H), si en ese preciso instante se produce un descenso (flanco de bajada) en la señal de datos, automáticamente se produce la condición de START (inicio) de la transmisión y el dispositivo que la produjo se convierte en MAESTRO, dando comienzo a la transmisión. El pulso de reconocer o reconocimiento, conocido como ACK (del inglés Acknowledge), se logra colocando la línea de datos a un nivel lógico bajo, durante el transcurso del noveno pulso de reloj. Yo se, que esta parte, es mas compleja de lo que parece, debe observar con atención los pasos que sigue el inicio de una transmisión en la figura que sigue.

Pasos de la transmisión.

El primer byte que se envía es START, después de la condición de inicio (START) se envía un byte que, contiene siete bits que componen la dirección del dispositivo que se quiere seleccionar y un octavo bit R/W (que corresponde a la operación que se quiere realizar con él, lectura o escritura). El siguiente byte contiene la dirección del registro que se desea leer/escribir. Puede realizarse un reinicio como se muestra en la figura. El tercer paso, aquí se escribe la dirección con el bit menos significativo LSB a nivel 1, para indicar que se lee. El cuarto paso y siguientes continúan la misma función de lectura, no tiene por qué ser sólo uno. A cada byte transferido al bus le sigue un noveno pulso de reloj durante el cual, el dispositivo receptor del byte debe generar un pulso de reconocido.

Para pasar a la función de escritura en el mismo dispositivo, puede realizarse, enviando un bit de STOP o de reinicio, considerado como parada e inicio. El paso que sigue es, escribir el byte que contiene siete bits que componen la dirección del dispositivo que se quiere seleccionar y un octavo bit a 0 que corresponde a la operación que se quiere realizar con él, ahora escritura. Y los pasos siguientes pueden ser como en el caso anterior.

Dicho esto, se debe resaltar que en el I2C-bus se definen tres tipos básicos de mensajes, cada uno de los cuales comienza con un START y se termina con una STOP.

   - Simple mensaje, donde un maestro escribe datos a un esclavo. 
   - Simple mensaje, donde un maestro lee datos de un esclavo.
   - Mensajes combinados, donde un maestro publica y al menos dos leen/escriben a uno  
     o varios esclavos.

En un mensaje combinado, cada uno, sea de lectura o escritura comienza con un START y la dirección de esclavo. Después del primer START, también se pueden hacer llamados repetidos bits de START, esto confirma que repetidos bits START no vienen precedidos por bits de STOP, que es como los esclavos conocen la próxima transferencia que, es parte del mismo mensaje. Todo esclavo puede sólo responder a mensajes particulares, tal como se define por su documentación de producto.

Cuando el maestro ha terminado de escribir todos los datos en el esclavo, se envía una secuencia de parada que completa la transacción. Así que para escribir en un dispositivo esclavo:

 1. Enviar una secuencia de inicio (START).
 2. Enviar la dirección I2C del esclavo más el bit bajo R/W.  (0xC0  =  b1100 0000) 
 3. Enviar el número de registro interno al que se quiere escribir. (ej. 0x00 = b0000 0000)
 4. Enviar el byte de datos. (0x01 = b 0000 0001)  
 5. [Opcionalmente, envíe algunos otros bytes de datos]. 
 6. Enviar la secuencia de parada (STOP).

Para lograr este propósito, se parte de una palabra de dirección, un byte, en los que debemos distinguir: el bit START, con dirección del esclavo al que interrogará. Esta dirección está formada por 4 bits de código de control más tres bits (A0..A2) de selección de dispositivo y el bit de escritura/lectura (R/W), por último se envía el bit ACK (reconocer) por que es el maestro el que está transmitiendo.

Palabra de direccionamiento

FUNCIÓN ESCRITURA.

Cuando un dispositivo quiere "decir algo" se dirige al dispositivo con el que quiere hablar, envía una señal START (inicio) condicional y se procede al envío de un byte con los siete bits que componen la dirección del dispositivo esclavo con el que se quiere comunicar, mas un octavo bit de menor peso que corresponde con la operación deseada (E/L), escritura = 0 (enviar al esclavo) y lectura = 1 (recibir del esclavo), seguido del bit reconocer ACK.

La dirección enviada es comparada por cada uno de los esclavos del bus con su propia dirección, si ambas coinciden, el esclavo se considera direccionado como esclavo-receptor o esclavo-transmisor dependiendo del bit de menor peso E/L. El esclavo responde enviando un bit de reconocer ACK que le indica al dispositivo maestro que el esclavo reconoce la solicitud y están en condiciones de comunicarse. Y comienza el intercambio de información entre ambos dispositivos.

El maestro envía la dirección del registro interno del dispositivo, en el que se desea leer o escribir, el esclavo responde con otro bit de reconocer, ahora el maestro puede empezar a leer o escribir bytes de datos. Todos los bytes de datos deben constar de 8 bits, el número máximo de bytes que pueden ser enviados en una transmisión no está restringido, siendo el esclavo quien fija esta cantidad dependiendo de sus características. Esto se consigue por que cada byte leído/escrito por el maestro debe ser obligatoriamente reconocido por un bit de reconocer por el dispositivo maestro/esclavo.

Es conveniente recordar estos puntos que, el número de bytes de datos transferidos entre las condiciones de inicio y parada del transmisor al receptor no esta limitado. Cada byte de ocho bits es seguido por un bit reconocer (ver Fig. 6). El bit reconocer es un nivel ALTO puesto en el bus por el transmisor mientras que el maestro genera un pulso de reloj extra reconocer relacionado.

Un receptor esclavo cuando es direccionado debe generar un reconocer después de la recepción de cada byte. También un maestro debe generar un reconocer después de la recepción de cada byte que ha sido registrado desde el esclavo transmisor. El dispositivo que reconoce tiene que poner a BAJO la línea SDA durante el pulso de reloj reconocer, por lo que la línea SDA es estable BAJO, durante el período ALTO del pulso de reloj reconocer relacionado, los tiempos de configuración y mantenimiento deben ser tenidos en cuenta.

A pesar de que el maestro normalmente controla el estado de la línea de reloj SCL , puede que un esclavo de baja velocidad o que un esclavo deba detener la transferencia de datos mientras efectúa otra función, podría forzar la línea SCL a nivel bajo. Esto haría que el maestro entrase en un estado de espera, durante el cual, no transmitiría información esperando a que el esclavo esté listo para continuar la transferencia en el punto donde había sido detenida. Cuando finaliza la comunicación, el maestro transmite una condición de "stop" para dejar libre el bus.

Escritura
Pulsar para ampliar
.

FUNCIÓN LECTURA.

La figura que sigue, corresponde al registro en el modo lectura. Siga las señales de la figura para comprender su funcionamiento.

Lectura
Pulsar para ampliar
.

Esto es para comunicaciones simples I²C casi todo, pero hay una complicación más. Cuando el maestro lee del esclavo, es el esclavo el que coloca los datos sobre la línea SDA, pero es el maestro quien controla el reloj. ¿Qué pasa si el esclavo no está listo para enviar los datos? Con dispositivos tales como memorias EEPROM esto no es un problema, pero cuando el dispositivo esclavo es en realidad un microprocesador con otras cosas que hacer, puede ser un problema.

El microprocesador del dispositivo esclavo tendrá que ir a una rutina de interrupción, guardará sus registros de trabajo, averiguará de que dirección quiere leer el maestro, para obtener los datos y colocarlos en su registro de transmisión. Esto puede tomar muchos µS para que ocurra, mientras que el maestro está felizmente enviando pulsos de reloj por la línea SCL que, el esclavo no puede responder.

El protocolo I²C proporciona una solución a esto: el esclavo está autorizado a mantener la línea SCL baja. Esto se llama estiramiento de reloj. Cuando el esclavo recibe la orden de lectura del maestro, éste mantiene la línea de reloj baja. El microprocesador obtiene los datos solicitados, los coloca en el registro de transmisión y libera la línea de reloj que habilita la resistencia RPA para finalmente dejarla a alto.

Desde el punto de vista de los maestros, se emitirá el primer pulso de reloj de lectura, haciendo SCL ALTO y luego verificará si realmente se ha ido a ALTO. Si es todavía BAJO, entonces es el esclavo quien lo mantendrá BAJO y el maestro deberá  esperar hasta que este vaya a ALTO antes de continuar. Por suerte, los puertos de hardware I2C en la mayoría de los microprocesadores se encargará de forma automática.

NOTA.

Como se ha visto, el dispositivo maestro, para el caso de lectura, enviará el primer pulso de reloj para la lectura de datos del esclavo, liberando la línea SCL para que pase a ALTO, pero antes de continuar comprobará que SCL realmente haya ido al nivel lógico 1, si la línea SCL permanece en BAJO, el dispositivo maestro interpreta que el esclavo la mantiene así y espera a que SCL vaya a ALTO antes de continuar. Cuando el maestro está leyendo desde el esclavo, es el dispositivo esclavo quien pone los datos en la línea SDA del bus y el maestro es el que controla el pulso de reloj.

Esto es lo que ocurre normalmente, sin embargo, que ocurre si el esclavo no está listo para enviar un dato. Con dispositivos como una EEPROM esto no será problema, ya que son esclavos de otro dispositivo. Cuando el dispositivo "esclavo" se trata de un microprocesador, el cual se supone que tiene otras tareas que atender, aquí es donde surge el problema. Dicho microprocesador, para atender la llamada del dispositivo maestro, como ya se ha comentado, deberá utilizar una interrupción, guardando el estado de sus registros de trabajo en ese momento, determinar la dirección que desea leer el maestro, tomar el dato y ponerlo en el registro de transmisión.

En el tiempo que transcurre (microsegundos) con esta transacción, el dispositivo maestro estaría enviando pulsos de reloj ciegamente por la línea SCL, sin que el dispositivo esclavo le respondiera. Para este caso, el protocolo I2C ofrece una solución; el esclavo puede mantener la línea SCL en BAJO, a esto se le llama estiramiento del reloj. Por este motivo, cuando el esclavo recibe el comando de lectura, lo primero que hace es poner la línea de reloj en BAJO, hasta que obtiene el dato solicitado, entonces lo pone en el registro de transmisión e inmediatamente libera la línea de reloj, que pasará de inmediato a ALTO debido al nivel que aporta la resistencia de polarización.

Mi experiencia personal en el uso del I2C bus, evidentemente debe mejorar con la práctica, del mismo modo que ocurrirá con la del lector interesado, si sigue realizando proyectos y practicando con el sistema de transmisión de datos entre dispositivos con microcontroladores. La práctica ha ido mejorando mis conocimientos sobre el I2C y algunas muestras se encuentran en este sitio. Para una mayor información refiérase a las indicaciones del fabricante en especificaciones del I2C de Philips.

El I²C-bus con Arduino.

Actualmente existen muchas aplicaciones, para aplicar con la placa Arduino; como un reloj en tiempo real, potenciómetros digitales, sensores de temperatura, brújulas digitales, chips de memoria, servos, circuitos de radio FM, E/S expansores, controladores de LCD, amplificadores, etc. Y además usted puede tener más de una idea para aplicar este bus, en cualquier momento, como se ha dicho, el número máximo de dispositivos I²C utiliza en un momento dado es de 112.

Debe tenerse muy en cuenta el Arduino que está utilizando, si es un Arduino Mega, el pin SDA, es pin 20 y el SCL, es el pin 21, así que, tenga en cuenta que en los escudos con I²C, necesitan ser específicamente para el Mega. Si usted tiene otro tipo de tarjeta, revise la hoja de datos o consulte la página web de pruebas de hardware de Arduino. Y por último, si usted está usando un microcontrolador ATMega328 base DIP-PU, deberá a utilizar para SDA el pin 27 y SCL el pin 28.

Si sólo está utilizando un dispositivo I²C, las resistencias RPA, no son necesarias ya que el microcontrolador ATMega328 en nuestro Arduino las ha incorporado Sin embargo, si está empleando una serie de dispositivos utilice dos resistencias de 10k ohmios. Como todo algunas pruebas en un circuito protoboard o prototipo determinará su necesidad. La longitud máxima de un bus I²C es de alrededor de un metro y es una función de la capacidad del bus. Esta distancia se puede ampliar con el uso de un circuito especial que no examinaremos en el presente trabajo.

Cada dispositivo se puede conectar al bus en cualquier orden, y como ya se ha mencionado, los dispositivos pueden ser maestros o esclavos. En nuestra aplicación el IDE Arduino, es el maestro y los dispositivos que "colguemos" en el bus I²C son los esclavos. Podemos escribir datos en un dispositivo o leer datos de un dispositivo. A estas alturas ya debe estar pensando "¿cómo podemos diferenciar cada dispositivo en el bus?" Más arriba, de modo general, ya se ha documentado. Decíamos que, cada dispositivo tiene una dirección única. Usaremos esa dirección, en las funciones descritas más adelante para dirigir nuestras peticiones de lectura o escritura al dispositivo correcto.

Al igual que en la mayoría de dispositivos, haremos uso de una librería para Arduino, en este caso <wire.h>. A continuación, utilizamos la function Wire.begin(); dentro de la configuración del void setup() y estaremos listos para empezar.

ENVIO de datos (sending), desde nuestro Arduino a los dispositivos I²C depende de dos cosas: la dirección única del dispositivo (que necesitamos esté en hexadecimal) y al menos un byte de datos a enviar. (Como ya se ha descrito arriba).

Por ejemplo; la dirección del dispositivo en el ejemplo (abajo) es 01101000 (binario), que es 0x68 en hexadecimal.

Entonces, debemos establecer el valor del puntero, que es un valor entre 0 y 127, o sea 0×00 y 0x7F en hexadecimal. Así que, para establecer el puntero a cero, usaríamos las funciones siguientes:

  Wire.beginTransmission(0x68);    // dirección única 0x68 del ds1307 o 01101000b

Esto envía la dirección del dispositivo por la línea del bus SDA (datos). Viaja a lo largo del bus, y "avisa" al dispositivo correspondiente que tiene algunos datos que vienen ...

  Wire.send(0x00);                 // inicia el puntero de la memoria del ds1307 (es el byte)

Esto envía el byte de datos en el dispositivo - en el registro del dispositivo (o la memoria de todo tipo), que está esperando con los brazos abiertos. Cualquier otro dispositivo en el bus pasará esto por alto. Tenga en cuenta que sólo puede realizar una operación I²C a la vez! Luego, cuando hemos terminado de enviar datos al dispositivo, la "transmisión finaliza". Esto le dice al dispositivo que hemos terminado y libera el bus I²C para la siguiente operación:

  Wire.endTransmission();          // termina la transmisión

Algunos dispositivos pueden tener más de un registro y por lo tanto requieren más bytes de datos en cada transmisión. Por ejemplo, el DS1307 reloj en tiempo real tiene 8 registros para almacenar los datos de tiempo, cada uno requiere 8 bits de datos (un byte), o si es una RAM, puede almacenar más datos.

Sin embargo, con el DS1307 - como requiere ocho bits de datos, enviar la totalidad del lote necesita volver a reescribir cada vez. Así que, en este caso, será necesario utilizar ocho funciones de wire.send (), cada vez. Cada dispositivo interpreta los bytes de datos enviados al mismo, por lo que se necesita la hoja de datos del dispositivo, para entender cómo usarlo.

Recepción de datos (Receiving) desde un dispositivo I²C con nuestro Arduino, requiere dos cosas: la dirección única del dispositivo (que necesitamos esté en hexadecimal) y el número de bytes de datos a aceptar desde el dispositivo. La recepción de datos en este momento es un proceso que consta de dos etapas. Si revisamos el cuadro anterior de la hoja de datos del DS1307, tengamos en cuenta que hay ocho registros o bytes de datos allí. Lo primero que tenemos que hacer es iniciar el dispositivo I²C leyendo el primer registro, que se realiza mediante el envío de un cero al dispositivo:

  Wire.beginTransmission(device_address);  // device_address, es la dirección del dispositivo

  Wire.send(0); 

  Wire.endTransmission();

Entonces, el dispositivo I2C enviará los datos del primer registro cuando se le solicite. Ahora, necesitamos pedir al dispositivo los datos y la cantidad de bytes que queremos. Por ejemplo, si un dispositivo necesita tres bytes de datos, le pedimos para tres y almacenará cada byte en su propia variable (por ejemplo, tenemos tres variables de tipo byte: a, b, y c. La primera función a ejecutar es la siguiente:

  Wire.requestFrom(device_address, 3);

Que le dice al dispositivo, "envía tres bytes de datos de vuelta" al Arduino. A continuación, inmediatamente después de esto con:

  *a = Wire.receive();

  *b = Wire.receive();

  *c = Wire.receive();

No es necesario utilizar Wire.endTransmission() al leer los datos. Ahora que, los datos solicitados se encuentran en sus respectivas variables, se pueden tratar como cualquier otra variable de bytes ordinaria.

Para una explicación más detallada del bus I2C, lea el documento explicativo u hojas de datos. Ahora vamos a utilizar nuestro conocimiento I2C mediante el control de una amplia gama de dispositivos ...

Esto es todo, por parte de este sencillo tutorial que pretende dar mi punto de vista sobre el I2C bus. Si tiene interés en leer más artículos sobre Arduino, revele esta sección. ( Mostrar/Ocultar)


 

Volver al Ídice de artículos Arduino.

 

Creada el: 10-11-09 
Actualizada el: 20-12-2011    

Licencia de Creative Commons

Hispavila.com. | Declaración de privacidad | LSSI | Póngase en contacto con nosotros
Electrónica Hispavila by V. García  Esta obra está bajo una licencia de Creative Commons Attribution-NonCommercial-NoDerivs 3.0
Unported License.Based on a work at Electrónica Digital.Permissions beyond the scope of this license may be available at Contacte