Archivo de la etiqueta: i2C

Bus I2C de Raspberry Pi II

@cmdearcos
Grupo TIECs

Empezaré este artículo intentando contestar a una pregunta que me habéis hecho llegar durante estos días: ¿Qué relación tiene la programación en C y el Rasperry PI con la factura eléctrica y las medidas de eficiencia energética?.

Las Tecnologías de la Información, Energía y Comunicaciones tienen dos aspectos básicos:

  • Tanto las TICs como la Energía son materias transversales a todos los sectores. Una solución TIEC tendrá en cuenta el gasto energético tanto de la solución como del resto de los sistemas que interactúen con la solución para conseguir un sistema que cumpla con los objetivos de diseño y que para ello consuma la menor cantidad de energía posible (eficiencia en todos los sentidos).
  • Todas las medidas de eficiencia energética necesitan de las TIC para su control y fiscalización y poder corregir errores en caso de producirse desviaciones de consumo no previstas. No se puede entender la eficiencia energética sin las TIC.

Dicho esto, un Raspberry Pi (RPi) gasta 2W. ¿Veis ahora la relación?. Si una misma aplicación (solución TIC) la podemos hacer “correr” en un RPi tenemos una solución TIEC.

Este artículo quiere ampliar la entrada que hice hace algunos días sobre la configuración del bus I2C. Una vez que tenemos nuestra RPi configurada y con un esclavo conectado a nuestro bus es el momento de comunicarse con dicho esclavo a través de un programa en C.

Todo programa que vaya a utilizar el bus I2C deberá incluir el fichero de cabecera wiringPiI2C.h y a la hora de “lincar” el programa la librería lwiringPi.

Esta librería tiene las siguientes funciones:

int wiringPiI2CSetup (int devId)

Esta función nos devuelve un “file descriptor” que utilizaremos para comunicarnos con el esclavo y que necesitaremos en el resto de funciones. devld es la dirección del esclavo que podemos sacar o de la documentación del mismo o al ejectutar el comando i2cdetect como explicamos en el artículo anterior.

add = 0x39;

fd = wiringPiI2CSetup (add);

Esta función devuelve -1 si no puede abrir las comunicaciones o el descriptor de fichero si todo ha ido correctamente.

Una vez que tenemos abierta las comunicaciones solo podemos hacer dos cosas: leer datos de los esclavos y escribir datos en los algunos registros del esclavos.

int wiringPiI2CRead (int fd)

Esta es la función básica de lectura. No todos los esclavos permiten esta función.

int wiringPiI2CWrite (int fd, int data)

Esta es la función básica para escribir un dato en un esclavo. data es el dato que se quiere escribir en el esclavo. No se especifica ningún registro del dispositivo y no todos los esclavos permiten esta función.

También es posible leer el valor de registros de los dispositivos. El valor de dichos registros y el dato que devuelve (especialmente su tamaño) deben venir especificados en la documentación del esclavo. Las funciones que lo posibilitan en casa caso son:

int wiringPiI2CReadReg8 (int fd, int reg)

int wiringPiI2CReadReg16 (int fd, int reg)

donde reg es la dirección del registro.

Por último también podemos escribir datos en un registro concreto, por ejemplo, para configurar el funcionamiento del esclavo. Al igual que ocurría con las de lectura tenemos dos funciones según el registro necesite 1 o 2 bytes. Las funciones son las siguientes:

int wiringPiI2CWriteReg8 (int fd, int reg, int data)

int wiringPiI2CWriteReg16 (int fd, int reg, int data)

La dirección de los registros son diferentes en cada esclavo y deben venir especificadas en la documentación para poder comunicarse con él.

Con estas 7 funciones podemos controlar y comunicarnos con un esclavo a través del bus I2C. A modo de ejemplo os dejo la documentación de un adaptador serie/I2C de un Nuchuck “de la Wii”, cuyo ejemplo en python podéis ver en esta entrada. En C habría que realizar el “mismo” programa pero con las funciones que os he comentado en este artículo.

Todo un nuevo mundo de posibilidad se abre a nuestra RPi con este bus. Ahora a disfrutar!!!.

@cmdearcos
Grupo TIECs

Bus I2C de Raspberry Pi I

@cmdearcos
Grupo TIECs

¿Qué es el bus I2C?. Empezaremos diciendo que I2C significa “Inter Integrated Circuits”.

Este bus fue desarrollado por la empresa Philips Semiconductors (ahora nxp semiconductors) a principios de los 80´s. Aquí os dejo las especificaciones del bus y el manual de usuario de fecha de 9 de octubre de 2012.

Este bus tiene una topología maestro-esclavo. En este caso el maestro es nuestro Raspberry pi (y los esclavos una multitud de dispositivos y sensores que podéis conseguir en el mercado). A continuación podéis ver un esquema del bus.

 

i2c_diagram

Las transferencias de datos se llevan a cabo mediante la línea serie de datos SDA. La línea SCL lleva la señal de reloj que sincroniza los datos de la línea SDA.

El dispositivo maestro (microcontrolador, en nuestro caso Raspberry pi) es quien siempre tiene la iniciativa de la comunicación. El maestro genera la señal de reloj y controla cuando se transmiten o reciben los datos.

Puede haber varios esclavos en la red I2C, pero el maestro solo se comunica con uno a la vez con un protocolo de pregunta/respuesta. Para poder localizar a cada dispositivo es necesario que cada uno tenga una dirección única dentro del bus.

En terminología I2C los datos se organizan en transferencias. Las transferencias comienzan con una señal de START y termina con otra de STOP. Los datos tienen una longitud de 1 byte y terminan con bit de ACK (o NACK). A continuación podéis ver una transferencia en la siguiente figura:

trama ack

Una condición START es una transición de Alto a Bajo en la línea SDA cuando SCL está en Alto. Después de Start el bus se considera ocupado.

Una condición STOP es una transición de Bajo a Alto en la línea SDA mientras SCL está en Alto. Después de Stop las dos líneas están en Alto y el bus se considera libre.

Siendo una comunicación serie donde cada dato por la línea SDA esrá sincronizado con el reloj, es este último quien marca la velocidad de transmisión. Una velocidad de 100 kbits/s implica que cada bit se transmite en 1s/100k = 10µs. Estos datos se detallan en el Estándar I2C y también suelen ir indicados en los datasheets de los dispositivos I2C.

El estándar del bus I2C soporta cuatro modos de operación:

  • Standard Mode, con una velocidad de hasta 100 kbit/s.
  • Fast mode, con una velocidad de hasta 400 kbit/s.
  • Fast mode plus, con una velocidad de hasta 1 Mbit/s.
  • High-speed mode, con una velocidad de hasta 3.4 Mbit/s.

Ahora pasamos a configurar nuestro Raspberry para poder programar aplicaciones donde se comuniquen diferentes dispositivos.

¿Dónde se encuentra el bus I2C en nuestra Raspberry?. Se encuentra en nuestra en el pin 3 (SDA) y el pin 5 (SCL).

Para poder acceder desde un programa en C es necesario instalar la librería wiringPi.

wiringPi se mantiene bajo GIT, por ello, si no está instalado es necesario instalarlo. Si este fuera el caso, lo podéis instalar con el siguiente comando:

sudo apt-get install git-core

Si este comando diera error es aconsejable actualizar el Raspbian a la última versión disponible. Para ello ejecutad:

sudo apt-get update

sudo apt-get upgrade

Una vez instalado GIT es necesario descargarse la librería wiringPi:

git clone git://git.drogon.net/wiringPi

Este comando creará el directorio en el directorio actual llamado wiringPi donde se encuentra la librería. Para poder utilizarla es necesario “construirla”:

cd wiringPi

./build

Una vez ejecutado el script de construcción podemos comprobar que se ha instalado adecuadamente con los siguientes comandos:

gpio -v

gpio readall

Una vez instalada la librería debemos instar las i2c-tools:

apt-get install i2c-tools

Para poder acceder a la librería en un primer momento podemos ejecutar el siguiente comando:

gpio load i2c

En el caso de los que los dispositivos esclavos lo permitieran se puede poner la velocidad del bus a 400 kbps de la siguiente forma:

gpio load i2c 400

Para que se cargue el modulo i2c una vez que arranque el sistema es necesario incluir los módulos i2c-bcm2708 y i2c-dev en el fichero /etc/modules y por otro lado comentar las entradas con un # del fichero /etc/modprobe.d/raspi_blacklist.conf:

  • blacklist spi-bcm2708
  • blacklist i2c-bcm2708

Una vez cargados los modulos de I2C se podrá ejecutar el siguiente comando donde nos muestra la dirección del dispositivo conectado a nuestra bus (si es que tenemos alguno):

  • i2cdetect -y 0 (para la Rev 1)
  • i2cdetect -y 1 (para la Rev 2)

Aquí os dejo la salida de mi Raspberry donde tengo conectado un esclavo con dirección 0x39.

Ahora ya tenéis vuestra Raspberry preparado para empezar a utilizar el bus I2C en vuestros programas.

@cmdearcos
Grupo TIECs