Encuentra informaci贸n referente a la programaci贸n, electr贸nica y mucho m谩s, la p谩gina est谩 pensada para compartir contenido educativo relevante coadyuvando a su aprendizaje diario.
Bus de comunicaci贸n I2C en Arduino

Este bus de comunicaci贸n I2C (Inter Integrated circuits) que usan en Arduino fue dise帽ado por los ingenieros de Philips en los a帽os 80 para simplificar 茅l envi贸 de datos entre dispositivos que soportan este protocolo de comunicaci贸n, adem谩s de poder tener varios maestros y esclavos conectados entre s铆 al mismo tiempo.

Para iniciar la comunicaci贸n entre dispositivos siempre la debe iniciar el maestro y no el esclavo, adem谩s este tipo de comunicaci贸n es s铆ncrona y half d煤plex.

Para realizar una comunicaci贸n con el bus I2C requerimos dos se帽ales, una se帽al es usada por los pulsos de reloj para sincronizar los cambios de flancos de bajada y subida, y la otra se帽al es usada para el intercambio de datos.

Se帽ales usadas por el bus de comunicaci贸n I2C / TWI en Arduino

Como ya mencionamos este tipo de comunicaci贸n solo requiere dos se帽ales, el SCL y SDA, esto lo hace muy f谩cil de implementar para nuestros proyectos.

SCL (Serial Clock Line).- Usada para determinar la frecuencia de reloj.

SDA (Serial Data Line).-  Con esta l铆nea de se帽al podemos intercambiar datos entre nuestros dispositivos.

Velocidades posibles con el bus de comunicaci贸n I2C / TWI en Arduino

Las velocidades de transferencia de datos son relativamente bajas, pero podemos trabajar hasta los 3.4 Mbit/s con un bus bidireccional y 5 Mbit/s con un bus unidireccional.

Velocidades del Bus de comunicaci贸n I2C con Arduino

Pines para hacer una conexi贸n en el bus I2C / TWI en Arduino

Lo m谩s recomendable para saber que pin usar para este tipo de conexi贸n es ir directamente a la hoja de datos del microcontrolador que utiliza nuestra placa de Arduino, pero la documentaci贸n de Arduino nos indica que pines usar y se lo detalla a continuaci贸n:

Pines para usar en las placas de Arduino para realizar la comunicaci贸n I2C

Conexi贸n de maestro esclavo para la comunicaci贸n con el bus I2C / TWI en Arduino

En este tipo de conexi贸n podemos tener hasta 128 dispositivos interconectados asign谩ndole una direcci贸n 煤nica a cada dispositivo, esto porque las direcciones trabajan con 7 bit lo que nos da un rango de 0 a 127 direcciones posible, el bit restante se usa para determinar si el dispositivo est谩 leyendo o escribiendo, para tener una buena interconectividad se recomienda usar una resistencia pull-up, adem谩s como dijimos podemos trabajar con uno o varios maestros a continuaci贸n se muestra un diagrama de conexi贸n para realizar la comunicaci贸n con el bus I2C en Arduino.

Conexion para tener varios esclavos con un bus I2C

Conexi贸n entre varios esclavos y un maestro con la comunicaci贸n
 i2c en Arduino

Conexion para tener varios maestros con un bus I2C

Conexi贸n entre varios maestros y varios esclavos para la comunicaci贸n i2c con arduino

Librer铆a Wire para manejar dispositivos I2C / TWI con Arduino

La librer铆a Wire que viene preinstalado en el IDE de Arduino nos permite trabajar de manera f谩cil y ordenada con el bus de comunicaci贸n I2C, para usarla solo debemos incluirla en la cabecera de nuestro c贸digo con la siguiente instrucci贸n: #include <Wire.h>, con esto ya estaremos listos para utilizar sus m茅todos de esta librer铆a que se detallan a continuaci贸n:

Wire.begin()

Esta funci贸n nos permite inicializar la conexi贸n como maestro o esclavo, si ponemos la direcci贸n del dispositivo como par谩metro estaremos configurando como esclavo y en caso contrario ser谩 maestro el dispositivo.

Wire.requestFrom()

Esta funci贸n es usada para recuperar informaci贸n desde el esclavo, tiene tres argumentos, en el primer argumento debemos colocar la direcci贸n del dispositivo esclavo, en el segundo argumento debemos colocar la cantidad de bits que solicitaremos, y en el tercer argumento colocamos una booleano 鈥淭RUE鈥 que nos permitir谩 terminar la conexi贸n despu茅s de la solicitud o 鈥淔ALSE鈥 para mantener la conexi贸n.

Wire.beginTransmission(direcci贸n)

Nos permite iniciar la transmisi贸n de datos al esclavo colocando la direcci贸n de 7 bits del dispositivo como argumento.

Wire.endTransmission()

Termina la transmisi贸n de datos al esclavo y env铆a los bytes en cola en la funci贸n write(), tambi茅n podemos definir un argumento booleano 鈥淭rue鈥 para liberar el bus y 鈥渇alse鈥 para seguir usando el bus.

Wire.write()

Env铆a datos desde el maestro al esclavo, puede tener un argumento donde puede ser un byte o una cadena, tambi茅n podemos enviar datos con respectiva longitud y para esto usaremos dos argumentos.

Wire.available()

Esta funci贸n nos permite determinar si existen bytes para ser le铆dos.

Wire.read()

Es usada para leer los bytes enviados ya sea del maestro al esclavo o del esclavo al maestro.

Wire.setClock(frecuencia del reloj)

Es usada para colocar la frecuencia de reloj y poder trabajar con la velocidad que necesitemos seg煤n los modos ya mencionados anteriormente, esto depender谩 si soporta o no el dispositivo que vayamos a usar, para esto debemos hacer uso de sus hojas de datos para saber si es posible trabajar con estas velocidades.

Wire.onReceive(funci贸n)

Con esta funci贸n podemos hacer referencia a otra funci贸n para realizar alguna acci贸n cuando recibamos alguna transmisi贸n de datos dese el maestro.

Wire.onRequest(funcion)

Es usada para responder con alg煤n mensaje al maestro cuando lo requiera, el mensaje lo podemos programar en una funci贸n propia y colocarla como argumento.

Ejemplo del bus de comunicaci贸n I2C / TWI conexi贸n entre dos Arduinos

El ejemplo consiste en la comunicaci贸n entre dos Arduinos donde se enviara un mensaje 鈥渙n鈥 desde el monitor Serie el Arduino maestro para encender un led  y 鈥渙ff鈥 para apagarlo, el led estar谩 conectado en el Arduino esclavo, este ejemplo ser谩 similar al que hicimos con el <<bus de comunicaci贸n SPI>>.

Materiales para el ejemplo de conexi贸n entre dos Arduino

  • 2 Arduino Uno
  • 1 led
  • 1 resistencia de 330 o 220 ohmios
  • Cables (lo necesario)  

Diagrama de conexi贸n entre los dos Arduinos con el bus de comunicaci贸n I2C

Conexi贸n entre Arduino para hacer la comunicaci贸n I2C

C贸digo fuente para la comunicaci贸n entre dos arduinos con el bus I2C / TWI

Arduino Maestro

/* AUTOR: CREATIVIDAD CODIFICADA
 *  www.creatividadcodificada.com
 *  NOMBRE DEL PROYECTO: Comunicaci贸n entre dos Arduinos Uno 
 *  con el bus I2C 
 *  
 *  ******* [ARDUINO MAESTRO] *******
*/  
#include <Wire.h>

boolean control = false;
String datosLeidos = "";
char datos;

void setup() {
  
  Serial.begin(9600);
  // Iniciamos el bus I2C 
  Wire.begin();
}

void loop() {
  if(control) {
    // Preparamos 16 bits para ser leidos desde el esclavo
    Wire.requestFrom(1, 16);    
    while(Wire.available())    
    { 
      char c = Wire.read();   
      Serial.print(c);        
    }

    //Controlamos los datos para encender o apagar el led
    //Enviamos los bit al esclavo 
    if(datosLeidos == "on\n"){
      Wire.beginTransmission(1);
      Wire.write("on");
      Serial.println(" - Led encendido");
      Wire.endTransmission();
    }
    else if(datosLeidos == "off\n"){
      Wire.beginTransmission(1);
      Wire.write("off");
      Serial.println(" - Led apagado");
      Wire.endTransmission();
    }
    else { 
      Serial.println(" - Mensaje no valido!!!");
    }
  datosLeidos = "";
  control = false;
  }
}

// funcion para controlar si existe algo para leer en el 
// monitor Serie del Arduino Maestro 
void serialEvent() { 
  while (Serial.available()) {
    char c = (char)Serial.read();
    datosLeidos += c;
    if (c == '\n') {
      control = true;
    }
  }
}

Arduino Esclavo

/* AUTOR: CREATIVIDAD CODIFICADA
 *  www.creatividadcodificada.com
 *  NOMBRE DEL PROYECTO: Comunicaci贸n entre dos Arduinos Uno 
 *  con el bus I2C 
 *  
 *  ******* [ARDUINO ESCLAVO] *******
*/  
#include <Wire.h>

uint8_t control = 0;
String mens="";
int led = 2;
char buffer[20];

void setup() {
  
  pinMode(led,OUTPUT);
  Wire.begin(1);
  Wire.onRequest(requestEvent);
  Wire.onReceive(receiveEvent);
}

void loop() {
  // Controlamos el mensaje recibido desde el maestro
  // para encender o apagar el led
   if (control == 1){
      mens = buffer;
      if(mens == "on")
        digitalWrite(2,HIGH);
      else if(mens == "off")
        digitalWrite(2,LOW);  
      control = 0;  
      memset(buffer,'\0',20); // limpiamos el buffer   
  }
}
void receiveEvent (int howMany)
{
  // Llenamos el mensaje completo a buffer 
  byte* x = buffer;
  while (Wire.available()) { 
    control = 1;
    *x++ = Wire.read(); 
  }
   
}
void requestEvent()
{
  // Enviamos un mensaje en caso 
  // de que la conexion este correcta
  Wire.write("Conexion exitosa"); // Env铆a 10 bytes                    
}

驴Que te parecio el art铆culo?

Su direcci贸n de email no sera publicado. Los campos obligatorios est谩n marcados con *.

驴Qu茅 hacemos con tus datos?

Creatividad Codificada como responsable tratar谩 tus datos con la finalidad de gestionar tu participaci贸n en nuestro blog informativo. Puedes acceder, rectificar y suprimir tus datos, as铆 como ejercer otros derechos consultando la informaci贸n adicional y detallada sobre protecci贸n de datos en nuestra Pol铆tica de Privacidad