Diferencia entre revisiones de «I2C»

De Proyecto Butiá
Saltar a: navegación, buscar
(Bloques)
(Configuración del hardware)
 
(No se muestran 53 ediciones intermedias de 2 usuarios)
Línea 1: Línea 1:
== Autores: ==
+
== Autores ==
 
*Federico Kauffman
 
*Federico Kauffman
 
*Maximiliano Kotvinsky
 
*Maximiliano Kotvinsky
 
*Andrés Vasilev
 
*Andrés Vasilev
 +
 +
== Protocolo I2C ==
 +
 +
Lo primero que ocurre en un bus I2C es que el dispositivo maestro envía una secuencia de inicio (StartI2C). Esto alerta a los dispositivos esclavos, poniéndolos a la espera de una transacción. Éstos quedan atentos para ver si se trata de una solicitud para ellos.
 +
 +
A continuación el dispositivo maestro envía la dirección de dispositivo (WriteI2C con la dirección y el bit de R/W). El dispositivo esclavo que posee esa dirección continuará con la transacción, y los otros ignorarán el resto de los intercambios, esperando la próxima secuencia de inicio.
 +
 +
Una vez que el maestro ha enviado la dirección del dispositivo en el bus I2C, puede enviar (WriteI2C con el byte a enviar) ahora el byte de datos. El dispositivo maestro puede seguir enviando bytes al esclavo consecutivamente (WriteI2C consecutivos).
 +
 +
De forma análoga podrá leer bytes enviados por el esclavo (ReadI2C).
 +
 +
Cuando el maestro ha terminado de escribir datos en el esclavo, envía una secuencia de parada (StopI2C) que concluye la transacción.
 +
 +
Al momento de indicar la dirección del esclavo para comenzar la comunicación, se debe indicar si se desea realizar una lectura o una escritura en el bit menos significativo (ver Sección Bloques-WriteI2C). Por lo que para realizar una lectura luego de haber realizado una escritura, se deberá iniciar la comunicación nuevamente con el bit apropiado.
  
 
== Paleta ==
 
== Paleta ==
Línea 16: Línea 30:
  
 
'''OpenI2C'''  
 
'''OpenI2C'''  
 +
 
Inicializa el módulo I2C.
 
Inicializa el módulo I2C.
 +
 +
 +
  
 
*[[Archivo:starti2c.png]]
 
*[[Archivo:starti2c.png]]
 +
  
 
'''StartI2C'''
 
'''StartI2C'''
 +
 
Es el mensaje que inicia la comunicación I2C.
 
Es el mensaje que inicia la comunicación I2C.
 +
 
Envía la condición de Start de I2C, y espera hasta que la secuencia de señal de Start termine.
 
Envía la condición de Start de I2C, y espera hasta que la secuencia de señal de Start termine.
 +
 +
  
  
Línea 28: Línea 51:
  
 
'''StopI2C'''
 
'''StopI2C'''
 +
 
Es el mensaje que finaliza la comunicación I2C.
 
Es el mensaje que finaliza la comunicación I2C.
 +
 
Envía la condición de Stop de I2C, y espera hasta que la secuencia de señal de Stop termine.
 
Envía la condición de Stop de I2C, y espera hasta que la secuencia de señal de Stop termine.
 +
 +
  
  
Línea 35: Línea 62:
  
 
'''CloseI2C'''
 
'''CloseI2C'''
 +
 
Finaliza el módulo I2C.
 
Finaliza el módulo I2C.
 +
 +
  
  
Línea 43: Línea 73:
  
 
Escribe un solo byte en el bus I2C.
 
Escribe un solo byte en el bus I2C.
 +
 
También es utilizado para enviar la dirección del esclavo al que se desea comunicar.
 
También es utilizado para enviar la dirección del esclavo al que se desea comunicar.
 +
 
La dirección se debe escribir de la siguiente forma en el byte a enviar:
 
La dirección se debe escribir de la siguiente forma en el byte a enviar:
  
[[Archivo:I2c-address.png]]
+
[[Archivo:I2c-address.png|500px]]
 +
 
 +
 
 +
 
  
 
*[[Archivo:readi2c.png]]
 
*[[Archivo:readi2c.png]]
Línea 52: Línea 87:
 
'''ReadI2C'''
 
'''ReadI2C'''
  
Lee un solo byte del bus I2C
+
Lee un solo byte del bus I2C.
 +
 
 +
Para leer varios bytes, se envía un AckI2C luego de cada byte leído.
 +
 
 +
Cuando se lee el último byte se debe enviar un NotAckI2C.
 +
 
 +
Esto aplica para leer un solo byte, se envía un NotAckI2C luego de la lectura del byte.
 +
 
 +
 
 +
 
  
 
*[[Archivo:acki2c.png]]
 
*[[Archivo:acki2c.png]]
  
 
'''AckI2C'''
 
'''AckI2C'''
 +
 +
Envía un acknowledgement de que el byte se leyó, y se procederá a leer otro.
 +
 +
 +
  
 
*[[Archivo:notacki2c.png]]
 
*[[Archivo:notacki2c.png]]
  
 
'''NotAckI2C'''
 
'''NotAckI2C'''
 +
 +
Envía un negative acknowledgement para indicar que se leyó el byte, y se finalizará la lectura.
  
 
== Descarga e instalación ==
 
== Descarga e instalación ==
Línea 66: Línea 117:
 
Como instalarlo:
 
Como instalarlo:
 
<br/>
 
<br/>
1- Descargar el archivo: i2c_plugin.zip<br/>
+
1- Descargar el archivo: [[Archivo:I2c plugins.zip]]<br/>
 
2- Descomprimir el archivo.<br/>
 
2- Descomprimir el archivo.<br/>
 
3- Copiar todo el contenido a la carpeta "plugins" que se encuentra dentro de la actividad TurtleBots.<br/>
 
3- Copiar todo el contenido a la carpeta "plugins" que se encuentra dentro de la actividad TurtleBots.<br/>
 +
 +
Nota: Debe estar instalado en la USB4Butiá el firmware con soporte para I2C.
  
 
== Ejemplo de uso ==
 
== Ejemplo de uso ==
  
== Notas ==
+
=== Ejemplo de comunicación con placa Arduino ===
 +
 
 +
Nota: La placa Arduino se utilizará como esclavo en la dirección 0x04.
 +
 
 +
[[Archivo:I2c_schematics.png| thumb | Diagrama del circuito utilizado.]]
 +
 
 +
[[Archivo:I2c_usb4butia.jpg | thumb | USB4Butiá acondicionada para la prueba.]]
 +
 
 +
=== Configuración del hardware ===
 +
 
 +
Para poder realizar el siguiente ejemplo se necesitan los siguientes materiales:
 +
 
 +
*1 x Arduino UNO
 +
*1 x Protoboard
 +
*2 x Resistencias de 1k ohms
 +
*3 x Cables Dupont Macho-Macho
 +
*4 x Cables Dupont Macho-Hembra
 +
*1 x Cable de red
 +
 
 +
 
 +
Como se muestra en el diagrama del circuito, se debe conectar  el pin de GND de la arduino a GND en la protoboard (cable negro). <br/>
 +
Luego se conecta el pin A5 o SCL a la protoboard (cable verde) y se le conecta a Vcc a través de una resistencia de 1k ohm. <br/>
 +
Por último se realiza el mismo procedimiento con el pin A4 o SDA (cable amarillo). <br/>
 +
 
 +
Como primer paso para que la USB4Butiá pueda comunicarse utilizando I2C por el puerto 5 (el único con soporte I2C), primero se debe eliminar la resistencia de 10k ohm conectada al pin 33 del pic18F4550.<br/>
 +
 
 +
Para realizar la conexión con la USB4Butiá se debe cortar un extremo del cable de red y conectar la ficha rj45 al puerto 5 de dicha placa. <br/>
 +
Con el extremo cortado del cable de red, se realizan las siguientes conexiones: <br/>
 +
*GND en la USB4Butiá a GND en la protoboard
 +
*Vcc en la USB4Butiá a Vcc en la protoboard
 +
*Línea de datos (pin 34 del pic18F4550) al la línea SCL de la protoboard (cable verde )
 +
*Línea de identificación (pin 33 del pic18F4550) al la línea SDA de la protoboard (cable amarillo)
 +
 
 +
 
 +
Nota: Se recomienda utilizar un tester en modo continuidad para encontrar cuáles de los 8 cables son GND, Vcc, datos (pin 34), Identificación (pin 33)
 +
 
 +
=== Enviar un mensaje a la placa ===
 +
 
 +
[[Archivo:I2c_write.png|600px]]
 +
 
 +
Lo primero que se necesita hacer es inicializar el módulo I2C con '''OpenI2C'''.
 +
 
 +
 
 +
Luego se debe enviar un mensaje indicando a los dispositivos esclavos conectados que se comenzará una comunicación I2C. Esto se hace enviando un '''StartI2C'''.
 +
 
 +
 
 +
Una vez que los dispositivos saben que se comenzó la comunicación, se debe enviar un mensaje con la dirección del dispositivo esclavo e indicar si se va a realizar una escritura o lectura.
 +
 
 +
En este caso se envía la dirección y el bit menos significativo en 0, ya que se desea hacer una escritura:
 +
 
 +
ADDR : 0x04 (0000 0100)
 +
 
 +
Bit R/W : 0
 +
 
 +
Byte a enviar : 0x08 (0000 1000 | 0 : 0000 1000 (0x08) )
 +
 
 +
'''WriteI2C(0x08)'''
 +
 
 +
 
 +
Luego de enviar la dirección del dispositivo esclavo, se procede a enviar los mensajes con '''WriteI2C'''.
 +
 
 +
 
 +
Finalmente, para terminar la comunicación con el dispositivo se envía un '''StopI2C''', y si no se realizará otra comunicación se cierra el modulo I2C con '''CloseI2C'''.
 +
 
 +
<br/>
 +
'''En funcionamiento:'''
 +
 
 +
<youtube>1n0N8AQDT5M</youtube>
 +
 
 +
 
 +
Código arduino utilizado: [[Archivo:I2c_slave_sender.zip]]
 +
 
 +
=== Leer un mensaje desde la placa ===
 +
 
 +
[[Archivo:I2c_read.png|600px]]
 +
 
 +
Para realizar una lectura se realizan los dos primeros pasos de igual forma: '''OpenI2C''', y '''StartI2C'''.
 +
 
 +
Luego se debe enviar la dirección del esclavo, e indicar que se realizará una lectura (bit de R/W en 1):
 +
 
 +
ADDR : 0x04 (0000 0100)
 +
 
 +
Bit R/W : 1
 +
 
 +
Byte a enviar : 0x09 (0000 1000 | 1 : 0000 1001(0x09) )
 +
 
 +
'''WriteI2C(0x09)'''
 +
 
 +
Una vez enviada la dirección con el bit de R/W correspondiente se procede a leer los bytes enviados por el esclavo con '''ReadI2C'''.
 +
 
 +
Después de cada lectura se debe indicar con un '''AckI2C''' o '''NotAckI2C''' según corresponda, como se explicó en la sección Bloques.
 +
 
 +
Para finalizar la comunicación se procede igual que con la escritura, es decir, '''StopI2C''', y '''CloseI2C'''.
 +
 
 +
<br/>
 +
'''En funcionamiento''':
 +
 
 +
<youtube>xr6-U5snzp0</youtube>
 +
 
 +
Código arduino utilizado: [[Archivo:I2c_slave_reader.zip]]
  
 
== Trabajo a futuro ==
 
== Trabajo a futuro ==
  
Configuración de la frecuencia de trabajo.
+
Hoy en día no es posible configurar desde la paleta la frecuencia de trabajo de I2C y por defecto dicha frecuencia se encuentra configurada en 100Kbps. <br/>
 +
Como el protocolo soporta frecuencias mayores, se espera en un futuro contar con la opción de configurar la frecuencia deseada.<br/><br/>
 +
 
 +
Otro tema importante es que en la versión actual de la USB4Butiá el soporte I2C se encuentra en las líneas de datos (SCL) e identificación (SDA) del puerto 5. El problema entonces es que existe una resistencia pull-down de identificación en el pin 33 que impide utilizar I2C, siendo imposible utilizar el puerto 5 para conectar sensores y dar soporte I2C al mismo tiempo.
 +
Se han presentado alternativas a este problema y se espera poderlas implementar a futuro.

Revisión actual del 17:01 14 dic 2016

Autores

  • Federico Kauffman
  • Maximiliano Kotvinsky
  • Andrés Vasilev

Protocolo I2C

Lo primero que ocurre en un bus I2C es que el dispositivo maestro envía una secuencia de inicio (StartI2C). Esto alerta a los dispositivos esclavos, poniéndolos a la espera de una transacción. Éstos quedan atentos para ver si se trata de una solicitud para ellos.

A continuación el dispositivo maestro envía la dirección de dispositivo (WriteI2C con la dirección y el bit de R/W). El dispositivo esclavo que posee esa dirección continuará con la transacción, y los otros ignorarán el resto de los intercambios, esperando la próxima secuencia de inicio.

Una vez que el maestro ha enviado la dirección del dispositivo en el bus I2C, puede enviar (WriteI2C con el byte a enviar) ahora el byte de datos. El dispositivo maestro puede seguir enviando bytes al esclavo consecutivamente (WriteI2C consecutivos).

De forma análoga podrá leer bytes enviados por el esclavo (ReadI2C).

Cuando el maestro ha terminado de escribir datos en el esclavo, envía una secuencia de parada (StopI2C) que concluye la transacción.

Al momento de indicar la dirección del esclavo para comenzar la comunicación, se debe indicar si se desea realizar una lectura o una escritura en el bit menos significativo (ver Sección Bloques-WriteI2C). Por lo que para realizar una lectura luego de haber realizado una escritura, se deberá iniciar la comunicación nuevamente con el bit apropiado.

Paleta

Paleta i2c.png

Esta paleta le agrega el soporte del bus I²C a la placa USB4Butiá.

Bloques

  • Openi2c.png

OpenI2C

Inicializa el módulo I2C.



  • Starti2c.png


StartI2C

Es el mensaje que inicia la comunicación I2C.

Envía la condición de Start de I2C, y espera hasta que la secuencia de señal de Start termine.



  • Stopi2c.png

StopI2C

Es el mensaje que finaliza la comunicación I2C.

Envía la condición de Stop de I2C, y espera hasta que la secuencia de señal de Stop termine.



  • Closei2c.png

CloseI2C

Finaliza el módulo I2C.



  • Writei2c.png

WriteI2C

Escribe un solo byte en el bus I2C.

También es utilizado para enviar la dirección del esclavo al que se desea comunicar.

La dirección se debe escribir de la siguiente forma en el byte a enviar:

I2c-address.png



  • Readi2c.png

ReadI2C

Lee un solo byte del bus I2C.

Para leer varios bytes, se envía un AckI2C luego de cada byte leído.

Cuando se lee el último byte se debe enviar un NotAckI2C.

Esto aplica para leer un solo byte, se envía un NotAckI2C luego de la lectura del byte.



  • Acki2c.png

AckI2C

Envía un acknowledgement de que el byte se leyó, y se procederá a leer otro.



  • Notacki2c.png

NotAckI2C

Envía un negative acknowledgement para indicar que se leyó el byte, y se finalizará la lectura.

Descarga e instalación

Como instalarlo:
1- Descargar el archivo: Archivo:I2c plugins.zip
2- Descomprimir el archivo.
3- Copiar todo el contenido a la carpeta "plugins" que se encuentra dentro de la actividad TurtleBots.

Nota: Debe estar instalado en la USB4Butiá el firmware con soporte para I2C.

Ejemplo de uso

Ejemplo de comunicación con placa Arduino

Nota: La placa Arduino se utilizará como esclavo en la dirección 0x04.

Diagrama del circuito utilizado.
USB4Butiá acondicionada para la prueba.

Configuración del hardware

Para poder realizar el siguiente ejemplo se necesitan los siguientes materiales:

  • 1 x Arduino UNO
  • 1 x Protoboard
  • 2 x Resistencias de 1k ohms
  • 3 x Cables Dupont Macho-Macho
  • 4 x Cables Dupont Macho-Hembra
  • 1 x Cable de red


Como se muestra en el diagrama del circuito, se debe conectar el pin de GND de la arduino a GND en la protoboard (cable negro).
Luego se conecta el pin A5 o SCL a la protoboard (cable verde) y se le conecta a Vcc a través de una resistencia de 1k ohm.
Por último se realiza el mismo procedimiento con el pin A4 o SDA (cable amarillo).

Como primer paso para que la USB4Butiá pueda comunicarse utilizando I2C por el puerto 5 (el único con soporte I2C), primero se debe eliminar la resistencia de 10k ohm conectada al pin 33 del pic18F4550.

Para realizar la conexión con la USB4Butiá se debe cortar un extremo del cable de red y conectar la ficha rj45 al puerto 5 de dicha placa.
Con el extremo cortado del cable de red, se realizan las siguientes conexiones:

  • GND en la USB4Butiá a GND en la protoboard
  • Vcc en la USB4Butiá a Vcc en la protoboard
  • Línea de datos (pin 34 del pic18F4550) al la línea SCL de la protoboard (cable verde )
  • Línea de identificación (pin 33 del pic18F4550) al la línea SDA de la protoboard (cable amarillo)


Nota: Se recomienda utilizar un tester en modo continuidad para encontrar cuáles de los 8 cables son GND, Vcc, datos (pin 34), Identificación (pin 33)

Enviar un mensaje a la placa

I2c write.png

Lo primero que se necesita hacer es inicializar el módulo I2C con OpenI2C.


Luego se debe enviar un mensaje indicando a los dispositivos esclavos conectados que se comenzará una comunicación I2C. Esto se hace enviando un StartI2C.


Una vez que los dispositivos saben que se comenzó la comunicación, se debe enviar un mensaje con la dirección del dispositivo esclavo e indicar si se va a realizar una escritura o lectura.

En este caso se envía la dirección y el bit menos significativo en 0, ya que se desea hacer una escritura:

ADDR : 0x04 (0000 0100)

Bit R/W : 0

Byte a enviar : 0x08 (0000 1000 | 0 : 0000 1000 (0x08) )

WriteI2C(0x08)


Luego de enviar la dirección del dispositivo esclavo, se procede a enviar los mensajes con WriteI2C.


Finalmente, para terminar la comunicación con el dispositivo se envía un StopI2C, y si no se realizará otra comunicación se cierra el modulo I2C con CloseI2C.


En funcionamiento:


Código arduino utilizado: Archivo:I2c slave sender.zip

Leer un mensaje desde la placa

I2c read.png

Para realizar una lectura se realizan los dos primeros pasos de igual forma: OpenI2C, y StartI2C.

Luego se debe enviar la dirección del esclavo, e indicar que se realizará una lectura (bit de R/W en 1):

ADDR : 0x04 (0000 0100)

Bit R/W : 1

Byte a enviar : 0x09 (0000 1000 | 1 : 0000 1001(0x09) )

WriteI2C(0x09)

Una vez enviada la dirección con el bit de R/W correspondiente se procede a leer los bytes enviados por el esclavo con ReadI2C.

Después de cada lectura se debe indicar con un AckI2C o NotAckI2C según corresponda, como se explicó en la sección Bloques.

Para finalizar la comunicación se procede igual que con la escritura, es decir, StopI2C, y CloseI2C.


En funcionamiento:

Código arduino utilizado: Archivo:I2c slave reader.zip

Trabajo a futuro

Hoy en día no es posible configurar desde la paleta la frecuencia de trabajo de I2C y por defecto dicha frecuencia se encuentra configurada en 100Kbps.
Como el protocolo soporta frecuencias mayores, se espera en un futuro contar con la opción de configurar la frecuencia deseada.

Otro tema importante es que en la versión actual de la USB4Butiá el soporte I2C se encuentra en las líneas de datos (SCL) e identificación (SDA) del puerto 5. El problema entonces es que existe una resistencia pull-down de identificación en el pin 33 que impide utilizar I2C, siendo imposible utilizar el puerto 5 para conectar sensores y dar soporte I2C al mismo tiempo. Se han presentado alternativas a este problema y se espera poderlas implementar a futuro.