Comunicación I2C con Arduino Uno

¡Conéctate conmigo en las redes sociales para actualizaciones y contenido!

Hay muchos dispositivos que funcionan con protocolos de circuito interintegrado (I2C) para compartir datos entre sí. La comunicación de la placa es independiente de la tasa de baudios de la USART.

En este tutorial, mostraré cómo realizar la comunicación I2C con dos placas Arduino. El potenciómetro y la pantalla LCD se utilizan para mostrar el intercambio de datos de un Arduino maestro al esclavo. El tutorial muestra los resultados de la simulación para los valores del potenciómetro leídos del maestro y aplicados al esclavo y viceversa, realizados controlando la pantalla LCD adjunta.

Introducción

El circuito interintegrado (I2C), también deletreado IIC, es un bus de comunicación en serie sincrónico, maestro/esclavo, conmutado por paquetes y de extremo único que admite múltiples controladores y objetivos. Para transmitir y recibir datos utilizando el protocolo I2C, utiliza dos líneas: un pin de reloj en serie (SCL), que emite pulsos periódicamente por la placa Uno Controller (maestra), y un pin de datos en serie (SDA), a través del cual pasan los datos. entre el transmisor y el receptor.

Entonces, la línea SDA transfiere datos y la línea SCL sincroniza los dispositivos con la señal del reloj.

Fenómenos de trabajo

El bus I2C se conecta a dos tipos diferentes de dispositivos: esclavo y maestro. Los maestros de bus manejan la transmisión y recepción de datos hacia y desde los dispositivos esclavos. El maestro también proporciona la señal del reloj. El protocolo I2C también admite múltiples maestros y múltiples esclavos, pero en este tutorial simplificaremos con un solo maestro y esclavo.

Cada dispositivo esclavo conectado al bus I2C obtiene una dirección exclusiva de 7 bits. El maestro elige un esclavo específico utilizando esta dirección para enviar o recibir datos, y el esclavo elegido reacciona de acuerdo con la solicitud.

Bits de datos de comunicación I2C

Lo que necesitamos

Como de costumbre, sugiero agregar desde ahora a su carrito de compras de comercio electrónico favorito todo el hardware necesario, para que al final pueda evaluar los costos generales y decidir si continúa con el proyecto o los elimina del carrito de compras. Entonces, el hardware será solo:

Consulta precios de hardware en los siguientes enlaces:

Procedimiento paso a paso

Diagrama de cableado de la placa Arduino maestro y esclavo

El siguiente diagrama de cableado proporciona la comunicación I2C entre dos placas Arduino (se puede encontrar más información sobre los puertos en Arduino pinout).

Cada Arduino leerá el valor de su potenciómetro más cercano y lo enviará al otro Arduino. Los 2 potenciómetros en las pantallas LCD son solo para controlar el contraste y no afectan la variable del valor de lectura.

Diagrama de cableado de la tarjeta SD con Arduino Uno

A continuación encontrará más información sobre el cableado:

  • GND: GND de ambas placas necesitan conectarse juntos
  • Maestro A4: Esclavo A4
  • Maestro A5: Esclavo A5
  • Los cables de la pantalla LCD son VCC=5V, GND= GND, rs=2, enable = 7, D4=8, D5=9, D6=10, D7=11 para maestro y esclavo Contraste = Conectado con un potenciómetro para cambiar el valor de un ajuste de contraste
  • El potenciómetro de ambas placas está conectado en A0 de su placa.

Obtenga el código y la biblioteca para la comunicación I2C entre Arduino

Conecte su PC a Arduino y abra Arduino IDE. Para los primeros pasos, puede consultar el tutorial Conexión de PC con Windows con Arduino. Puede obtener el código .ino y las bibliotecas desde mi área de descarga con el siguiente enlace:

master_code.ino

código_esclavo.ino

Nuestra prueba I2C utilizará la biblioteca Wire.h, que ya está incluida en nuestro IDE de Arduino.

También debe instalar la biblioteca LiquidCrystal, de acuerdo con mi tutorial Instalar bibliotecas de Arduino: métodos para agregar bibliotecas con el IDE de Arduino, disponible en el Administrador de bibliotecas en el IDE de Arduino:

Código Explicación

Sección 1: Código Maestro

Comenzamos agregando la biblioteca I2C, seguida de la biblioteca LCD y su definición de pines.

#include<Wire.h> #include<LiquidCrystal.h> LiquidCrystal lcd(2, 7, 8, 9, 10, 11);

En la configuración, abrimos un monitor serial a una velocidad de 9600 baudios para visualizar los datos que vienen después de recibirlos. El comando wire.begin() permite una comunicación de datos de 8 bits.

void setup()  {    Serial.begin(9600);   Wire.begin(8);

También inicializamos nuestro LCD con un mensaje de bienvenida que durará 5 segundos (5.000 milisegundos). Luego, borraremos la pantalla LDC para que pueda recibir datos:

  lcd.begin(16,2);                    //Initilize LCD display   lcd.setCursor(0,0);                 //Sets Cursor at first line of Display    lcd.print("Peppe8o");               //Prints Peppe8o in LCD    lcd.setCursor(0,1);                 //Sets Cursor at second line of Display   lcd.print("I2C 1 ARDUINO");         //Prints I2C ARDUINO in LCD   delay(5000);                        //Delay 5 seconds   lcd.clear();                        //Clear LCD display }

En la sección de bucle, el maestro requiere al dispositivo I2C con dirección «8» (nuestro esclavo Arduino) 1 byte de datos. También comenzamos a escuchar la comunicación para almacenarla en nuestra variable MasterReceive. Este será el valor que mostraremos en nuestro LCD Maestro, recibido del Esclavo:

void loop() {     Wire.requestFrom(8,1);     byte MasterReceive = Wire.read();

Por otro lado, el maestro debe enviar su valor de potenciómetro al esclavo. Entonces, procedemos a leer el valor del potenciómetro maestro, mapeándolo desde el rango sin procesar de 0-1023 a un rango más corto de 0-127, y luego lo transmitiremos en el puerto I2C:

    int potvalue = analogRead(A0);     byte MasterSend = map(potvalue,0,1023,0,127);       Wire.beginTransmission(8);     Wire.write(MasterSend);     Wire.endTransmission();  

Todos los datos ahora se han compartido entre Maestro y Esclavo. El bucle finaliza gestionando su presentación en LCD (y en nuestro monitor serie), añadiendo finalmente un retraso de 500 milisegundos antes de ejecutar un nuevo bucle:

    lcd.setCursor(0,0);     lcd.print(">>  Master  <<");     lcd.setCursor(0,1);     lcd.print("SlaveVal:");     lcd.print(MasterReceive);     Serial.println("Master Received From Slave");     Serial.println(MasterReceive);     delay(500);     lcd.clear(); }

Sección 2: Código Esclavo

A diferencia del Maestro, que tiene el control para inicializar acciones en el bus I2C, el Esclavo solo reaccionará a las acciones ejecutando 2 funciones principales:

  • cuando el Maestro requiere datos, el Esclavo ejecutará la función requestEvent()
  • cuando el Maestro envía datos, el Esclavo ejecutará la función receiveEvent()

Dicho esto, el código Esclavo comienza a inicializar las bibliotecas requeridas de manera similar al caso maestro:

#include<Wire.h> #include<LiquidCrystal.h> LiquidCrystal lcd(2, 7, 8, 9, 10, 11);

También necesitamos una variable para almacenar qué valores ha transmitido Master, para obtenerlos de la función receiveEvent() y mostrarlos en nuestro bucle principal:

byte SlaveReceived;

En la sección de configuración del Esclavo, nuevamente inicializamos el monitor serie y luego registramos la placa esclava Arduino con la dirección «8»:

void setup() {   Serial.begin(9600);   Wire.begin(8);

Como se anticipó, inicializamos las acciones onReceive y onRequest, refiriéndolas a las funciones definidas más adelante en el código:

  Wire.onReceive(receiveEvent);   Wire.onRequest(requestEvent);

Nuevamente, se imprimirá un mensaje de bienvenida durante 5 segundos, antes de borrar la pantalla LCD para realizar el trabajo de comunicación I2C:

  lcd.begin(16,2);   lcd.setCursor(0,0);   lcd.print("Peppe8o");   lcd.setCursor(0,1);   lcd.print("I2C 2 ARDUINO");   delay(5000);   lcd.clear(); } 

La función de evento de solicitud comienza a obtener el potenciómetro Esclavo y el mapeo de 0 a 127. El resultado se envía a I2C para el maestro:

void requestEvent() {   int potvalue = analogRead(A0);   byte SlaveSend = map(potvalue,0,1023,0,127);   Wire.write(SlaveSend); }

De manera similar, el evento de recepción obtiene los datos del I2C y los almacena en la variable «SlaveReceived»:

void receiveEvent (int howMany) {    SlaveReceived = Wire.read(); }

En el ciclo principal, el esclavo solo mostrará en la pantalla LCD (y en el monitor serial) lo que está almacenado en nuestra variable SlaveReceived:

void loop(void) {   lcd.setCursor(0,0);                              //Sets Currsor at line one of LCD   lcd.print(">>  Slave  <<");                      //Prints >> Slave << at LCD   lcd.setCursor(0,1);                              //Sets Cursor at line two of LCD   lcd.print("MasterVal:");                         //Prints MasterVal: in LCD   lcd.print(SlaveReceived);                        //Prints SlaveReceived value in LCD received from Master   Serial.println("Slave Received From Master:");   //Prints in Serial Monitor   Serial.println(SlaveReceived);   delay(500);   lcd.clear(); }

Probando la comunicación I2C con Arduino Uno

Cuando los datos del potenciómetro del maestro cambian girándolos, los datos modificados se envían al esclavo para que se muestren en la pantalla LCD del esclavo. De manera similar, cuando gira el potenciómetro en el esclavo, los valores se mostrarán en la pantalla LCD maestra. El medio de comunicación entre ambas placas I2C se establece mediante los pines A4 y A5.

La pantalla LCD comenzó a mostrar los valores del potenciómetro de referencia. El potenciómetro en el maestro se gira y cambia el valor en el LCD esclavo. El potenciómetro en el esclavo se gira y cambia el valor en el LCD maestro.