En el tutorial anterior, discutimos los conceptos básicos del protocolo I2C. En la mayoría de los dispositivos integrados, se utiliza UART o I2C para los mensajes de la consola. En este tutorial, analizaremos la comunicación serie en Raspberry Pi utilizando el protocolo I2C.
I2C en frambuesa Pi
Para la comunicación en serie a través del protocolo I2C, el procesador Broadcom de Raspberry Pi tiene un controlador en serie Broadcom (BSC). Este controlador BSC maestro de modo estándar es compatible con I2C de NXP Semiconductor y admite una velocidad de transferencia de datos de 400 kbps. El controlador BSC admite direccionamiento de 7 y 10 bits. Se puede acceder a esta interfaz I2C en los pines GPIO2 (pin de la placa n.° 3) y GPIO3 (pin de la placa n.° 5). GPIO2 es una línea de datos en serie (SDA) y GPIO3 es una línea de reloj en serie (SCL) de I2C1. Estos pines I2C se elevan internamente hasta 3,3 V a través de resistencias de 1,8 kohm. Esta es la razón por la que estos pines no se pueden utilizar para E/S de uso general donde no se requiere pull-up.
Hay un periférico I2C BSC2 más en la Raspberry Pi identificado como I2C0. El maestro BSC2 está dedicado a la interfaz HDMI y los usuarios no pueden acceder a él. Esta interfaz I2C está presente en los pines 27 (ID_SD) y 28 (ID_SC) de la placa. I2C0 permanece reservado para leer EEPROM de placas complementarias Raspberry Pi llamadas placas Hardware on The Top (HAT). I2C0 solo puede comunicarse con HAT EEPROM en la dirección 0x50 durante el tiempo de arranque.
Puede acceder a I2C0 solo si la interfaz de la cámara y el puerto HDMI no están en uso. Para usar I2C0, agregue las siguientes líneas a boot/config.txt.
dtparam=i2c_vc=encendido
Los pines I2C0 no se tiran internamente, por lo que si se usan modificando el archivo de configuración de Raspberry Pi, se deben usar pull-ups externos (a 3,3 V) en las líneas SDA y SCL. Cuando se usa I2C0, los pines evitan usar la dirección HAT EEPROM.
Incluso I2C1 está deshabilitado en Raspberry Pi de forma predeterminada. Debe estar habilitado en la configuración de Raspberry Pi. Los controladores BSC de Raspberry Pi admiten I2C multimaestro y multiesclavo. Por lo tanto, I2C1 es suficiente para conectar múltiples esclavos I2C (máximo 112 esclavos) y cualquier cantidad de dispositivos maestros.
Habilitando I2C1 desde la GUI de Raspberry Pi
En Raspbian, navegue hasta Menú Inicio de Pi -> Preferencias -> Configuración de Raspberry Pi.
En la ventana emergente, haga clic en la pestaña 'Interfaces' y seleccione el botón de opción 'Habilitar' para I2C. También puede habilitar o deshabilitar otras interfaces según sea necesario.
Para que los cambios surtan efecto, reinicie la Raspberry Pi. Después del reinicio, GPIO3 y GPIO5 se pueden usar para conectar Raspberry Pi como maestro I2C con un bus I2C o a cualquier esclavo I2C.
Habilitación del terminal I2C1
La compatibilidad con I2C para el núcleo ARM de Raspberry Pi y el kernel de Linux también se puede habilitar en la Terminal (Bash Shell en Raspberry Pi). Abra Terminal y ejecute el siguiente comando:
sudo raspi-config
En la herramienta de configuración del software Raspberry Pi, navegue hasta "Opciones de interfaz".
En modelos de Raspberry Pi más antiguos, navegue hasta "Opciones avanzadas" y luego a "I2C".
En la ventana emergente, habilite la interfaz Arm I2C y seleccione 'Sí' para cargar el módulo kernel I2C.
Ahora reinicia tu Raspberry Pi escribiendo el siguiente comando:
reiniciar sudo
Después del reinicio, GPIO3 y GPIO5 se pueden usar para conectar Raspberry Pi como maestro I2C con un bus I2C o a cualquier esclavo I2C.
Prueba del puerto I2C
Después de habilitar el puerto de usuario I2C y reiniciar Raspberry Pi, podemos probar si el puerto está disponible como dispositivo Linux o no. En la ventana de Terminal, ejecute el siguiente comando:
ls /desarrollador/
O
ls /dev/*i2c*
I2C1 debería aparecer como uno de los dispositivos Linux disponibles como se muestra en la imagen a continuación.
Tenga en cuenta que en versiones anteriores de Raspberry Pi, el puerto de usuario I2C se identifica como I2C0 en lugar de I2C1. En todos los modelos Raspberry Pi 256M el puerto de usuario I2C es 0, y en el resto es 1.
Comprobación de esclavos I2C en Raspberry Pi
Después de habilitar el puerto de usuario I2C, los esclavos I2C conectados se pueden detectar utilizando i2c-tools. En primer lugar, instale i2c-tools ejecutando el siguiente comando en la terminal Raspberry Pi:
sudo apt-get install -y i2c-tools
Ahora ejecute el siguiente comando para verificar los esclavos I2C conectados:
sudo i2cdetect -y 1
Como ya se mencionó, en versiones anteriores de Raspberry Pi el puerto de usuario I2C es 0, en versiones anteriores cambie el número de puerto a 0 de la siguiente manera:
sudo i2cdetect -y 0
i2c-detect es una herramienta que verifica el puerto de usuario I2C y devuelve las direcciones I2C de los dispositivos esclavos conectados. La herramienta devuelve una tabla de direcciones de dispositivos esclavos I2C conectados como se muestra en la siguiente imagen:
Acceder a dispositivos I2C usando la biblioteca SMBus
En Raspberry Pi, se puede acceder al bus I2C en un script de Python utilizando la biblioteca SMBus. SMBus es un subconjunto de la interfaz I2C. La biblioteca Python para SMBus se puede utilizar para comunicarse con dispositivos basados en I2C. La biblioteca SMBus se puede instalar en Raspberry Pi ejecutando el siguiente comando:
sudo apt-get install python-smbus
En un script de Python, la biblioteca SMBus se puede importar usando la siguiente declaración:
importar smbus
Después de importar la biblioteca SMBus, se debe crear un objeto de clase SMBus utilizando el método SMBus. El método SMBus toma el número de puerto I2C como parámetro y debe usarse en una declaración de asignación para crear un objeto SMBus. Tiene la siguiente sintaxis:
El siguiente es un ejemplo válido de creación de un objeto SMBus:
Autobús i2c = smbus.SMBus(1)
Tenga en cuenta que en versiones anteriores de Raspberry Pi, el puerto de usuario I2C es 0, y en todas las versiones de Raspberry Pi superiores a 256 M RPi, es 1. Para usar la biblioteca SMBus2 más nueva, se puede instalar usando pip ejecutando el siguiente comando:
instalación de pip smbus2
En un script de Python, la biblioteca SMBus2 se puede importar usando la siguiente declaración:
desde smbus2 importe SMBus, i2c_msg
Se puede crear un objeto de clase SMBus utilizando el método smbus2.SMBus de la siguiente manera:
Autobús i2c = smbus2.SMBus(1)
La biblioteca smBus2 tiene dos clases: SMBus e i2c_msg. La clase SMBus admite los siguientes métodos:
smbus.SMBus /smbus2.SMBus : para crear un objeto SMBus en un script de Python.
open (bus) : para abrir un bus i2c determinado.
cerrar : para cerrar la conexión I2C.
Los datos en serie de un esclavo I2C se pueden leer en bytes, palabras o bloques de bytes. En algunos dispositivos esclavos I2C, el maestro necesita acceder a datos en serie desde registros específicos. Los siguientes métodos están disponibles en la biblioteca SMBus2 para leer datos seriales I2C desde dispositivos esclavos:
read_byte(i2c_addr,strength=None) : para leer un solo byte de un dispositivo.
read_byte_data(i2c_addr,registrar,force=None) : para leer un solo byte de un registro designado.
read_block_data(i2c_addr,registrar,force=None) : para leer un bloque de hasta 32 bytes de un registro determinado.
read_i2c_block_data(i2c_addr,record,length,strength=None) : para leer un bloque de datos de bytes de un registro determinado.
read_word_data(i2c_addr,registrar,force=None) : para leer una sola palabra (2 bytes) de un registro determinado.
Asimismo, los datos se pueden escribir en esclavos I2C en bytes, palabras o bloques de bytes. En algunos dispositivos esclavos I2C, los datos deben escribirse en registros específicos. Los siguientes métodos están disponibles en la biblioteca SMBus2 para escribir datos I2C serie desde dispositivos esclavos:
write_byte(i2c_addr,value,strength=None) : para escribir un solo byte en un dispositivo.
write_byte_data(i2c_addr,record,value,force=None) : para escribir un byte en un registro determinado.
write_block_data(i2c_addr,record,data,strength=None) : para escribir un bloque de datos de bytes en un registro determinado.
write_i2c_block_data(i2c_addr,register,data,strength=None) : para escribir un bloque de datos de bytes en un registro determinado.
write_word_data(i2c_addr,record,value,force=None) : para escribir un byte en un registro determinado.
write_quick(i2c_addr,strength=None) : para realizar transacciones rápidas. Lanza IOError si no tiene éxito.
Los siguientes métodos están disponibles para administrar procesos SMBus y combinar operaciones de lectura/escritura del bus I2C:
Process_call(i2c_addr,register,value,strength=None) : para ejecutar una llamada de proceso SMBus, enviando un valor de 16 bits y recibiendo una respuesta de 16 bits
block_process_call(i2c_addr,record,data,force=None) : para enviar un bloque de datos de tamaño variable y recibir otra respuesta de tamaño variable.
i2c_rdwr(*i2c_msgs) : para combinar una serie de operaciones de lectura y escritura de i2c en una sola transacción.
En el próximo tutorial, analizaremos la interfaz del sensor acelerómetro ADXL345 con Raspberry Pi a través del puerto I2C.