El popular protocolo I2C permite que dos o más placas Arduino se comuniquen. Descubre cómo conectarlos y codificarlos.

Si bien un solo Arduino puede realizar muchas tareas, algunos proyectos pueden requerir el uso de más de una placa para manejar diferentes funcionalidades. Entonces, para habilitar la transferencia de datos entre los dos microcontroladores, se debe configurar un protocolo de comunicación como CAN, SPI, I2C o UART.

En esta guía, cubriremos los conceptos básicos de cómo funciona I2C, las conexiones de hardware y la implementación del software necesarios para configurar dos placas Arduino como dispositivos maestro y esclavo I2C.

¿Qué es I2C?

El circuito interintegrado (I2C) es un protocolo de comunicación ampliamente utilizado en sistemas integrados y microcontroladores para permitir la transferencia de datos entre dispositivos electrónicos. A diferencia de SPI (interfaz periférica en serie), I2C le permite conectar más de un dispositivo maestro a un bus con uno o varios dispositivos esclavos. Fue utilizado por primera vez por Philips y también se conoce como el protocolo de comunicación de interfaz de dos hilos (TWI).

instagram viewer

¿Cómo funciona la comunicación I2C?

I2C utiliza dos líneas bidireccionales: datos en serie (SDA) y reloj en serie (SCL) para transferir datos y sincronizar la comunicación entre dispositivos. Cada dispositivo conectado al bus I2C tiene una dirección única que lo identifica durante la comunicación. El protocolo I2C permite que varios dispositivos compartan el mismo bus y cada dispositivo puede actuar como maestro o esclavo.

La comunicación la inicia el dispositivo maestro y el direccionamiento incorrecto de los dispositivos esclavos puede causar errores en la transferencia. Consulte nuestra guía detallada sobre cómo funcionan las comunicaciones seriales UART, SPI e I2C para darle un poco de contexto.

Una de las principales ventajas de la comunicación I2C que vale la pena señalar es la flexibilidad que ofrece en lo que respecta a la administración de energía. Los dispositivos que funcionan a diferentes niveles de voltaje aún pueden comunicarse de manera efectiva con la ayuda de los cambiadores de voltaje. Esto significa que los dispositivos que funcionan a 3,3 V necesitan cambiadores de voltaje para conectarse a un bus I2C de 5 V.

La biblioteca de cables

La biblioteca Wire es una biblioteca Arduino integrada que proporciona funciones para comunicarse a través de I2C. Utiliza dos pines, SDA y SCL, en la placa Arduino para la comunicación I2C.

Pines I2C en el Arduino Uno:

Pines Arduino Nano I2C:

Para utilizar la biblioteca, debe incluir el Alambre.h archivo de encabezado al comienzo de su boceto de Arduino.

#incluir

La biblioteca Wire proporciona funciones para iniciar la comunicación con un dispositivo I2C, enviar y recibir datos. Algunas funciones importantes que debe conocer incluyen:

  • Wire.begin(): se utiliza para unirse al bus I2C e iniciar la comunicación.
  • Wire.beginTransmission(): se utiliza para especificar la dirección del esclavo y comenzar una transmisión.
  • Alambre.escribir(): se utiliza para enviar datos al dispositivo I2C.
  • Cable.endTransmission(): se utiliza para finalizar la transmisión y comprobar si hay errores.
  • Cable.solicitudDesde(): se utiliza para solicitar datos del dispositivo I2C.
  • Cable.disponible(): se utiliza para verificar si los datos están disponibles para leer desde el dispositivo I2C.
  • Alambre.read(): se utiliza para leer datos del dispositivo I2C.

Utilizar el Wire.beginTransmission() para establecer la dirección del sensor, que se inserta como argumento. Por ejemplo, si la dirección del sensor es 0x68, usarías:

Cable.comenzarTransmisión(0x68);

Configuración de hardware Arduino I2C

Para conectar dos placas Arduino usando I2C, necesitará los siguientes componentes de hardware:

  • Dos placas Arduino (maestra y esclava)
  • Tablero de circuitos
  • Cables puente
  • Dos resistencias pull-up de 4,7 kΩ

Conecta el ASD y SCL pines de ambas placas Arduino a una placa de pruebas. Conecte las resistencias pull-up entre los ASD y SCL alfileres y el 5V riel de alimentación en el protoboard. Finalmente, conecte las dos placas de prueba juntas usando cables de puente.

circuito arduino uno

Arduino Nano Circuito

Credito de imagen: Documentación Arduino I2C

Configuración de las placas Arduino como dispositivos maestros y esclavos I2C

Utilizar el Cable.solicitudDesde() función para especificar la dirección del dispositivo esclavo con el que queremos comunicarnos. Luego usa el Alambre.read() Función para obtener datos del dispositivo esclavo.

Código de dispositivo maestro:

#incluir
vacíoconfiguración(){
Cable.comenzar(); // unirse al autobús i2c
De serie.comenzar(9600); // inicia la serie para la salida
}
vacíorecibir datos(){
En t dirección = 8;
En t bytesParaLeer = 6;
Cable.solicitud de(dirección, bytesToRead);
mientras (Cable.disponible()) {
carbonizarse datos = Cable.leer();
De serie.imprimir(datos);
}
demora(500);
}
vacíobucle(){
recibir datos();
}

El Conectar.onReceive() La función se utiliza para especificar qué hacer cuando el esclavo recibe datos del dispositivo maestro. En el código anterior, el Cable.disponible() La función comprueba si los datos están disponibles y el Alambre.read() La función lee los datos enviados por el dispositivo maestro.

Código del dispositivo esclavo:

#incluir
vacíoconfiguración(){
Cable.comenzar(8); // unirse al bus I2C con dirección 8
Cable.en Recibir(recibirEvento); // llama a receiveEvent cuando se reciben los datos
}
vacíobucle(){
demora(100);
}
vacíorecibir evento(En t bytes){
Cable.escribir("Hola "); // responde con un mensaje de 6 bytes como esperaba el maestro
}

Envío y recepción de datos mediante I2C

En este ejemplo, leamos la temperatura de un sensor de temperatura DHT11 interconectado con el Arduino esclavo e imprimámoslo en el monitor serial del Arduino maestro.

Modifiquemos el código que escribimos anteriormente para incluir la medición de temperatura que luego enviaremos a la placa maestra a través del bus I2C. La placa maestra puede leer el valor que enviamos y luego mostrarlo en el monitor serial.

Código de dispositivo maestro:

#incluir
vacíoconfiguración(){
Cable.comenzar();
De serie.comenzar(9600);
De serie.imprimir("¡Maestro inicializado!");
}
vacíobucle(){
Cable.solicitud de(8, 1); // Solicitar datos de temperatura del esclavo
si (Cable.disponible()) {
byte temperatura = Cable.leer(); // Leer datos de temperatura del esclavo
De serie.imprimir("Temperatura: ");
De serie.imprimir(temperatura);
De serie.imprimir("°C");
}
demora(2000); // Espere 2 segundos antes de volver a solicitar la temperatura
}

Código del dispositivo esclavo:

#incluir
#incluir

#definir DHTPIN 4 // Pin conectado al sensor DHT
#definir TIPO DHT DHT11 // tipo de sensor DHT
DHT dht(PINDHTP, TIPODHTP);
byte temperatura;

vacíoconfiguración(){
Cable.comenzar(8); // La dirección del esclavo es 8
Cable.bajo pedido(solicitud de evento);
dht.comenzar();
}

vacíobucle(){
demora(2000); // Espere 2 segundos para que DHT se estabilice
temperatura = dht.leerTemperatura(); // Leer la temperatura del sensor DHT
}

vacíosolicitudEvento(){
Cable.escribir(temperatura); // Enviar datos de temperatura al maestro
}

Puede personalizar este código para adaptarse a los sensores que pueda tener en su proyecto, o incluso mostrar los valores de los sensores en un módulo de visualización para Haz tu propio termómetro de habitación y medidor de humedad..

Direccionamiento de esclavos con I2C en Arduino

Para leer los valores de los componentes agregados a un bus I2C en un proyecto de este tipo, es importante que incluya la dirección de esclavo correcta al codificar. Afortunadamente, Arduino ofrece una biblioteca de escáner que simplifica el proceso de identificación de esclavos. direcciones, eliminando la necesidad de revisar largas hojas de datos de sensores y confundiendo en línea documentación.

Utilice el siguiente código para identificar la dirección de cualquier dispositivo esclavo presente en el bus I2C.

#incluir // Incluir la biblioteca Wire para comunicación I2C

vacíoconfiguración(){
Cable.comenzar(); // Inicializar la comunicación I2C
De serie.comenzar(9600); // Inicializar la comunicación serial con una tasa de baudios de 9600
mientras (!De serie); // Espere a que se establezca la conexión serial
De serie.imprimir("\nEscáner I2C"); // Imprime un mensaje que indica el inicio del escaneo I2C
}

vacíobucle(){
byte error, dirección; // Declarar variables para almacenar errores y direcciones de dispositivos
En t nDispositivos; // Declarar una variable para almacenar el número de dispositivos encontrados

De serie.imprimir("Exploración..."); // Imprime un mensaje que indica el inicio del escaneo I2C

nDispositivos = 0; // Establecer el número de dispositivos encontrados en 0
para (dirección = 1; dirección < 127; dirección++) { // Iterar sobre todas las direcciones I2C posibles
Cable.comenzarTransmisión(DIRECCIÓN); // Iniciar una transmisión a la dirección actual
error = Cable.transmisión final(); // Terminar la transmisión y almacenar cualquier error

si (error == 0) { // Si no se encontraron errores
De serie.imprimir("Dispositivo I2C encontrado en la dirección 0x"); // Imprime un mensaje indicando que se encontró un dispositivo
si (dirección < 16) De serie.imprimir("0"); // Si la dirección es menor que 16, agregue un 0 inicial para fines de formato
De serie.imprimir(dirección, HEX); // Imprime la dirección en formato hexadecimal
De serie.imprimir(" !"); // Imprime un mensaje indicando que se encontró un dispositivo

nDispositivos++; // Incrementar el número de dispositivos encontrados
}
demássi (error == 4) { // Si se encuentra un error
De serie.imprimir("Error desconocido en la dirección 0x"); // Imprime un mensaje indicando que se encontró un error
si (dirección < 16) De serie.imprimir("0"); // Si la dirección es menor que 16, agregue un 0 inicial para fines de formato
De serie.imprimir(dirección, HEX); // Imprime la dirección en formato hexadecimal
}
}
si (nDispositivos == 0) { // Si no se encontraron dispositivos
De serie.imprimir("No se encontraron dispositivos I2C\n"); // Imprime un mensaje que indica que no se encontraron dispositivos
}
demás { // Si se encontraron dispositivos
De serie.imprimir("hecho\n"); // Imprime un mensaje que indica el final del escaneo I2C
}
demora(5000); // Retraso de 5 segundos antes de iniciar el siguiente escaneo
}

Amplíe su proyecto hoy

La interfaz de dos placas Arduino utilizando el protocolo de comunicación I2C ofrece una forma flexible y eficiente de lograr tareas complejas que no pueden ser manejadas por una sola placa. Con la ayuda de la biblioteca Wire, la comunicación entre las dos placas mediante I2C se simplifica, lo que le permite agregar más componentes a su proyecto.