I2C

Práctica I2C

En esta entrada se recoge la información necesaria para realizar la práctica relacionada con este bus. Para ello, se dará una breve introducción de lo que es este bus y su protocolo de comunicación.

Bus I2C

Este tipo de bus tiene una comunicación bidireccional basado en dos conductores. El SLC (señal de reloj), y el SDA (transmisión de datos). Los datos que se transmiten por el SDA son de 8 bits.

El uso de este tipo de bus viene representado en la siguiente imagen, en la cuál se puede observar que uno de los elementos actúa como maestro, mientras que el resto actúa como esclavos, recibiendo información del maestro o viceversa.

Este bus ha sido extendido para soportar velocidades de hasta 3.4 Mbits/s. La velocidad de transmisión es determinada por el reloj.

Modos de transferencia:
  • Modo estándar (S-mode) - 100 kbits/s
  • Modo rápido (F-mode) - 400 kbits/s
  • Modo alta velocidad (HS-mode) - más de 3,4 Mbits/s

Protocolo I2C

El formato del mensaje del protocolo I2C es el siguiente:


  • Los datos transitan en la bajada del reloj.
  • El dato es recibido en el borde de bajada del reloj.
  • El bit más significativo se envía primero.
  • El nodo que recibe debe manejar un acknowledge (bajo en SDA) después de completado el byte.
  • El nodo maestro siempre genera el reloj.



Práctica

Se desea desarrollar una práctica con Arduino en la que se vea la comunicación entre dos dispositivos mediante el protocolo I2C. El esclavo será el dispositivo que está en la derecha, el cual obtiene información sobre el sensor LDR para detectar si hay luz o no.

El esclavo será el encargado de enviar la información al maestro, y éste actuará de una forma u otra en función de los datos recibidos.

A continuación se muestra el esquema de conexiones entre los dos dispositivos Arduino. 



Código Esclavo

#include <Wire.h>
  const int LDR_pin = A0;
  bool plaza = false;//false es vacia, true, ocupada
  int valorLDR;
  int contDetec=0;
  int contNoDetect=0;
  int estado=1;
  void setup()
  {
    pinMode(LDR_pin, INPUT);
    Wire.begin(2);                // join i2c bus with address #2
    Wire.onRequest(requestEvent); // register event
    Serial.begin(9600);
  }
  void loop()
  {
    valorLDR=analogRead(LDR_pin);
    Serial.println(valorLDR);
    if(valorLDR>800 && estado==1){
      contDetec++;
      if(contDetec>3){
        contNoDetect=0;
        plaza=true;//La plaza esta ocupada
        estado=2;
      }
    }else{
      contDetec=0;
    }
    if(valorLDR<800 && estado==2){
      contNoDetect++;
      if(contNoDetect>3){
        contDetec=0;
        plaza=false;//La plaza esta ocupada
        estado=1;
      }
    }else{
      contNoDetect=0;
    }
    delay(100);
  }
  // function that executes whenever data is requested by master
  // this function is registered as an event, see setup()
  void requestEvent()
  {
    if (plaza == true) {   
      Wire.write("si");
    }
    else {
      Wire.write("no");
    }
 
  }

Código Maestro

#include <Wire.h>
void setup() {
 Wire.begin();
 Serial.begin(9600);
}

void loop() {
  Wire.requestFrom(2,2);
  while(Wire.available()){
    char c = Wire.read();
    Serial.print(c);
  }
  delay(500);
}

El código de los diferentes dispositivos se encuentran en Comunicación I2C

Funcionamiento

A continuación se puede observar el funcionamiento de los dispositivos que actúan como maestro y esclavo. El maestro recibe mediante el protocolo I2C un "si" o un "no" que es enviado por el esclavo.
El esclavo es el encargado de obtener datos del LDR.

I2C - Esclavo

I2C - Maestro

Comentarios

Entradas populares de este blog

Clasificador Difuso del sistema

Cliente MQTT del ESP8266