¿Qué es este blog?

La idea de este blog nace para compartir los avances que se vayan realizando a lo largo de un estudio sobre cómo interconectar los distintos sensores que se pueden encontrar en el mercado, o fabricar de forma casera, con la plataforma Mindstorms de LEGO. Para ello se hará uso ARDUINO, un entorno de desarrollo abierto basado en microcontrolador.

martes, 8 de marzo de 2011

Arduno y la comunicación I2C: Librería Wire()


En publicaciones anteriores del blog se comentaron las distintas herramientas de las que disponía el NXT para establecer la comunicación mediante I2C con dispositivos esclavos, e hicimos especial hincapié en el Sistema Operativo LejOs, que es con el que más estamos trabajando.

En el otro lado de la comunicación, y funcionando como esclavo, se va a encontrar nuestra placa de Arduino. En este epígrafe se va a describir el funcionamiento de la librería Wire(), que es aquella que nos va a permitir realizar esta comunicación, y se van a describir brevemente las funciones más interesantes de las que ésta dispone.

Principales funciones

Como se acaba de comentar, esta librería permite la comunicación de una placa Arduino con dispositivos I2C y TWI. En la mayoría de las placas Arduino, la línea de datos (SDA) se encuentra en el pin analógico 4, y la línea de reloj (SCL) se encuentra en el pin analógico 5. En el caso de la placa que nosotros usamos, Arduino Mega 2560, estas líneas están en los pines digitales 20 y 21 respectivamente.

Las principales funciones que nos ofrece esta librería son las siguientes:

- Wire.begin() y Wire.begin(dirección). Esta función inicializa la librería Wire y conecta Arduino al bus. Si no se especifica la dirección, Arduino se conectará al bus como maestro, mientras que si ésta se indica lo hará como esclavo y asumiendo la dirección que se la ha proporcionado. En ambos casos, esta función no devuelve ningún valor.

- Wire.requestFrom(dirección, cantidad). Solicita bytes desde otros dispositivos. Los bytes pueden ser recibidos con las funciones available() (que nos indica si hay datos disponibles para ser leídos en el bus) y receive() (que realiza la lectura de los datos). Esta función no devuelve nada.

  • El parámetro “dirección” es la dirección de 7 bits del dispositivo al que le queremos pedir los datos
  • El parámetro “cantidad” es el número de bytes a pedir.
- Wire.beginTransmission(dirección). Comienza una transmisión a un dispositivo I2esclavo con la dirección que se especifique en el parámetro “dirección”. Posteriormente, prepara los bytes a transmitir con la función send() y los transmite llamando a la función endTransmision(). Esta función no devuelve nada.

  • El parámetro “dirección” es la dirección de 7 bits del dispositivo al que le queremos pedir los datos.
- Wire.endTransmission(). Finaliza una transmisión a un esclavo que fue empezada por beginTransmission(), y realmente lo que hace es transmitir los bytes que fueron preparados por send(). Esta función tampoco devuelve nada.

- Wire.Send(valor), Wire.Send(string) o Wire.Send(dato, cantidad). Envía datos desde un esclavo como respuesta a una petición de un maestro, o prepara los bytes para transmitir desde un maestro a un esclavo (entre llamadas a beginTransmission() y endTransmission()).

  • El parámetro “valor” es un byte que se desee enviar.
  • El parámetro “string” es una cadena de tipo (char *) que se desee enviar.
  • El parámetro “dato” es un vector de datos para enviar (byte *).
  • El parámetro “cantidad” es el número de bytes que se desea transmitir

- Wire.available(). Devuelve el número de bytes disponibles para recuperar con receive(). Debería ser llamada por un maestro después de llamar a requestFrom() o por un esclavo dentro de la función a ejecutar por onReceive(), que será lo que nosotros hagamos al recibir datos del NXT. Esta función devuelve el número de bytes disponibles para leer.

- Wire.receive(). Recupera un byte que fue transmitido desde un dispositivo esclavo a un maestro después de una llamada a requestFrom() o que fue transmitido desde un maestro a un esclavo. Devuelve el byte recibido.

- Wire.onReceive(handler). Registra una función que será llamada cuando un dispositivo esclavo reciba una transmisión desde un maestro. Esta función no devuelve nada.

  • El parámetro “handler” corresponde a la función que será llamada cuando el esclavo recibe datos. Esta función debería coger un único parámetro entero (el número de bytes recibidos desde un maestro) y no devolver nada, por ejemplo: void myManejador(int numBytes).
- Wire.onRequest(handler). Registra una función que será llamada por el dispositivo esclavo cuando un maestro solicite datos. No devuelve nada.

  • El parámetro “handler” es la función que tiene que ser llamada.
A modo de ejemplo se muestra a continuación el código de un maestro y de un esclavo que hacen uso de esta librería. El esclavo envía datos, y el maestro los recibe y los imprime por puerto serie, con lo que se pueden monitorizar desde el PC.


En primer lugar el código del maestro:





Y a continuación el del esclavo:





--------------------------------------------------------------------
REFERENCIAS:
- Ejemplo de comunicación I2C entre dos Arduinos: http://arduino.cc/en/Tutorial/MasterReader
- Arduino Wire: http://arduino.cc/es/Reference/Wire
- I2C bus. TWI bus: http://www.i2c-bus.org/twi-bus/

No hay comentarios:

Publicar un comentario