Cómo conectar dos placas Arduino usando I2C

Cómo conectar dos placas Arduino usando I2C
Lectores como tú ayudan a apoyar a MUO. Cuando realiza una compra utilizando enlaces en nuestro sitio, podemos ganar una comisión de afiliado. Leer más.

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.





MAKEUSEOF VÍDEO DEL DÍA DESPLAZAR PARA CONTINUAR CON EL CONTENIDO

¿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).





¿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.

  Demostración de comunicación I2C

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:

cómo hacer música en tu computadora gratis
  Arduino I2C Uno pins

Pines Arduino Nano I2C:





  Asignación de pines Arduino nano I2C

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

 #include <Wire.h>

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.
  • Wire.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:

 Wire.beginTransmission(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

  Conexión Arduino_I2C en una protoboard

Arduino Nano Circuito

  nano33BS_06_ilustración para el protocolo de comunicación I2C
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 Wire.read() Función para obtener datos del dispositivo esclavo.

Código de dispositivo maestro:

 #include <Wire.h> 
void setup() {
Wire.begin(); // join i2c bus
Serial.begin(9600); // start serial for output
}
void receiveData() {
int address = 8;
int bytesToRead = 6;
Wire.requestFrom(address, bytesToRead);
while (Wire.available()) {
char data = Wire.read();
Serial.print(data);
}
delay(500);
}
void loop() {
receiveData();
}

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 Wire.read() La función lee los datos enviados por el dispositivo maestro.

Código del dispositivo esclavo:

 #include <Wire.h> 
void setup() {
Wire.begin(8); // join the I2C bus with address 8
Wire.onReceive(receiveEvent); // call receiveEvent when data is received
}
void loop() {
delay(100);
}
void receiveEvent(int bytes) {
Wire.write("hello "); // respond with message of 6 bytes as expected by master
}

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.

  Ejemplo de DHT11 I2C con 2 placas Arduino

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:

 #include <Wire.h> 
void setup() {
Wire.begin();
Serial.begin(9600);
Serial.println("Master Initialized!");
}
void loop() {
Wire.requestFrom(8, 1); // Request temperature data from slave
if (Wire.available()) {
byte temperature = Wire.read(); // Read temperature data from slave
Serial.print("Temperature: ");
Serial.print(temperature);
Serial.println(" &deg;C");
}
delay(2000); // Wait for 2 seconds before requesting temperature again
}

Código del dispositivo esclavo:

 #include <Wire.h> 
#include <DHT.h>

#define DHTPIN 4 // Pin connected to DHT sensor
#define DHTTYPE DHT11 // DHT sensor type
DHT dht(DHTPIN, DHTTYPE);
byte temperature;

void setup() {
Wire.begin(8); // Slave address is 8
Wire.onRequest(requestEvent);
dht.begin();
}

void loop() {
delay(2000); // Wait for 2 seconds for DHT to stabilize
temperature = dht.readTemperature(); // Read temperature from DHT sensor
}

void requestEvent() {
Wire.write(temperature); // Send temperature data to master
}

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áneres que simplifica el proceso de identificación de direcciones esclavas, lo que elimina la necesidad de revisar largas hojas de datos de sensores y la confusa documentación en línea.

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

 #include <Wire.h> // Include the Wire library for I2C communication 

void setup() {
Wire.begin(); // Initialize the I2C communication
Serial.begin(9600); // Initialize the serial communication with a baud rate of 9600
while (!Serial); // Wait for the serial connection to establish
Serial.println("\nI2C Scanner"); // Print a message indicating the start of I2C scanning
}

void loop() {
byte error, address; // Declare variables to store errors and device addresses
int nDevices; // Declare a variable to store the number of devices found

Serial.println("Scanning..."); // Print a message indicating the start of I2C scanning

nDevices = 0; // Set the number of devices found to 0
for (address = 1; address < 127; address++) { // Iterate over all possible I2C addresses
Wire.beginTransmission(address); // Start a transmission to the current address
error = Wire.endTransmission(); // End the transmission and store any errors

if (error == 0) { // If no errors were found
Serial.print("I2C device found at address 0x"); // Print a message indicating a device was found
if (address < 16) Serial.print("0"); // If the address is less than 16, add a leading 0 for formatting purposes
Serial.print(address, HEX); // Print the address in hexadecimal format
Serial.println(" !"); // Print a message indicating a device was found

nDevices++; // Increment the number of devices found
}
else if (error == 4) { // If an error was found
Serial.print("Unknown error at address 0x"); // Print a message indicating an error was found
if (address < 16) Serial.print("0"); // If the address is less than 16, add a leading 0 for formatting purposes
Serial.println(address, HEX); // Print the address in hexadecimal format
}
}
if (nDevices == 0) { // If no devices were found
Serial.println("No I2C devices found\n"); // Print a message indicating no devices were found
}
else { // If devices were found
Serial.println("done\n"); // Print a message indicating the end of I2C scanning
}
delay(5000); // Delay for 5 seconds before starting the next scan
}

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.