Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Manufacturing Technology >> Proceso de manufactura

¿Cómo funciona la comunicación I2C? Tutorial de Arduino e I2C

En este tutorial aprenderemos cómo funciona el protocolo de comunicación I2C y también haremos un ejemplo práctico del mismo con la placa Arduino y un sensor que utiliza este protocolo. Puede ver el siguiente video o leer el tutorial escrito a continuación.

Resumen

El bus de comunicación I2C es muy popular y ampliamente utilizado por muchos dispositivos electrónicos porque se puede implementar fácilmente en muchos diseños electrónicos que requieren comunicación entre un maestro y varios dispositivos esclavos o incluso varios dispositivos maestros. Las implementaciones sencillas vienen con el hecho de que solo se requieren dos cables para la comunicación entre hasta casi 128 (112) dispositivos cuando se usa el direccionamiento de 7 bits y hasta casi 1024 (1008) dispositivos cuando se usa el direccionamiento de 10 bits.

Cómo funciona I2C

¿Cómo es posible, una comunicación entre tantos dispositivos con sólo cables? Bueno, cada dispositivo tiene una ID preestablecida o una dirección de dispositivo única para que el maestro pueda elegir con qué dispositivos se comunicará.

Los dos cables o líneas se denominan reloj serial (o SCL) y datos seriales (o SDA). La línea SCL es la señal de reloj que sincroniza la transferencia de datos entre los dispositivos en el bus I2C y es generada por el dispositivo maestro. La otra línea es la línea SDA que transporta los datos.

Las dos líneas son de "drenaje abierto", lo que significa que se deben conectar resistencias de extracción para que las líneas estén altas porque los dispositivos en el bus I2C están activos bajos. Los valores comúnmente utilizados para las resistencias van desde 2K para velocidades más altas de aproximadamente 400 kbps hasta 10K para velocidades más bajas de aproximadamente 100 kbps.

Protocolo I2C

La señal de datos se transfiere en secuencias de 8 bits. Entonces, después de que ocurre una condición de inicio especial, viene la primera secuencia de 8 bits que indica la dirección del esclavo al que se envían los datos. Después de cada secuencia de 8 bits sigue un bit llamado Reconocimiento. Después del primer bit de reconocimiento, en la mayoría de los casos, viene otra secuencia de direccionamiento, pero esta vez para los registros internos del dispositivo esclavo. Inmediatamente después de las secuencias de direccionamiento, siguen las secuencias de datos hasta que los datos se envían por completo y finaliza con una condición de parada especial.

Echemos un vistazo aún más de cerca a estos eventos. La condición de inicio se produce cuando la línea de datos desciende mientras que la línea de reloj sigue siendo alta. Después de esto, el reloj se inicia y cada bit de datos se transfiere durante cada pulso de reloj.

La secuencia de direccionamiento del dispositivo comienza primero con el bit más significativo (MSB) y termina con el bit menos significativo (LSB) y en realidad está compuesta por 7 bits porque el 8 th bit se utiliza para indicar si el maestro escribirá en el esclavo (lógica baja) o leerá de él (lógica alta).

El dispositivo esclavo utiliza el siguiente bit AKC/NACK para indicar si ha recibido correctamente la secuencia de bits anterior. Entonces, en este momento, el dispositivo maestro transfiere el control de la línea SDA al dispositivo esclavo y, si el dispositivo esclavo ha recibido con éxito la secuencia anterior, bajará la línea SDA a la condición llamada Reconocimiento. Si el esclavo no baja la línea SDA, la condición se llama Not Acknowledge y significa que no recibió correctamente la secuencia anterior, lo que puede deberse a varias razones. Por ejemplo, el esclavo puede estar ocupado, puede que no comprenda los datos o comandos recibidos, no puede recibir más datos, etc. En tal caso, el dispositivo maestro decide cómo proceder.

El siguiente es el direccionamiento de registros internos. Los registros internos son ubicaciones en la memoria del esclavo que contienen información o datos diversos. Por ejemplo, el acelerómetro ADX345 tiene una dirección de dispositivo única y direcciones de registros internos adicionales para los ejes X, Y y Z. Entonces, si queremos leer los datos del eje X, primero debemos enviar la dirección del dispositivo y luego la dirección de registro interno particular para el eje X. Estas direcciones se pueden encontrar en la hoja de datos del sensor.

Después del direccionamiento, las secuencias de transferencia de datos comienzan desde el maestro o el esclavo, según el modo seleccionado en el bit R/W. Una vez que los datos se hayan enviado por completo, la transferencia terminará con una condición de parada que ocurre cuando la línea SDA pasa de baja a alta mientras que la línea SCL está alta.

Ejemplo

Como ejemplo, usaré la placa de conexión GY-80 que consta de 5 sensores diferentes y la placa de conexión GY-521 que consta de 3 sensores diferentes. Entonces podemos obtener datos de 8 sensores diferentes con solo dos cables con el bus I2C.

Puede obtener estos componentes en cualquiera de los siguientes sitios:

  • Acelerador de 3 ejes ADXL345 …………………………………………………………
  • 2 en 1:MPU6050 giroscopio y acelerómetro de 6 ejes …………………
  • 3 en 1:giroscopio de aceleración de campo magnético de 9 ejes GY-80………… Amazon 
  • 3 en 1: GY-86 10DOF MS5611 HMC5883L MPU6050 Módulo………… Banggood  /AliExpress

Así es como conectaremos las tablas. El pin del reloj en serie de la placa Arduino se conectará a los pines del reloj en serie de las dos placas de derivación, lo mismo ocurre con los pines de datos en serie y alimentaremos las placas con Gnd y el pin de 5V de la placa Arduino. Tenga en cuenta que aquí no estamos usando resistencias pull-up porque las placas de conexión ya las tienen.

Ahora, para comunicarnos con estos chips o sensores, necesitamos conocer sus direcciones únicas. Los podemos encontrar en las fichas técnicas de los sensores. Para la placa de conexiones GY-80 tenemos las siguientes 4 direcciones:un 0x53 hexadecimal para el sensor del acelerómetro de 3 ejes, un 0x69 hexadecimal para el giroscopio de 3 ejes, un 0x1E hexadecimal para el magnetómetro de 3 ejes y un 0x77 hexadecimal para el barómetro y el termómetro sensor.

Para la placa de conexión GY-521 solo tenemos una dirección y es un 0x68 hexadecimal. También podemos obtener o verificar las direcciones utilizando el boceto Arduino I2C Scanner que se puede encontrar en el sitio web oficial de Arduino. Así que aquí, si cargamos y ejecutamos ese boceto, obtendremos las direcciones de los dispositivos conectados en el bus I2C.


Sensor                                             Número de pieza                                     Dirección I2C

Acelerómetro de 3 ejes                   Analog Devices ADXL345                   0x53                  Hoja de datos

GyroST de 3 ejes                                Microelectrónica L3G4200D              0x69                  Hoja de datos

Magnetómetro de 3 ejes                  Honeywell MC5883L                           0x1E                  Hoja de datos

Barómetro + Termómetro        Bosch BMP085                                     0x77                  Hoja de datos


Después de haber encontrado las direcciones de los dispositivos, también necesitamos encontrar las direcciones de sus registros internos para poder leer los datos de ellos. Por ejemplo, si queremos leer los datos del eje X del sensor del acelerómetro de 3 ejes de la placa de conexión GY-80, necesitamos encontrar la dirección de registro interna donde se almacenan los datos del eje X. En la hoja de datos del sensor, podemos ver que los datos para el eje X en realidad se almacenan en dos registros, DATAX0 con una dirección hexadecimal 0x32 y DATAX1 con una dirección hexadecimal 0x33.

Código Arduino I2C

Ahora hagamos el código que obtendrá los datos para el eje X. Así que usaremos la biblioteca de cables Arduino que debe incluirse en el boceto. Aquí primero tenemos que definir la dirección del sensor y las dos direcciones de registros internos que encontramos anteriormente. El Cable.begin() La función iniciará la biblioteca de cables y también necesitamos iniciar la comunicación en serie porque usaremos el monitor en serie para mostrar los datos del sensor.

En el bucle() comenzaremos con Wire.beginTransmission() función que comenzará la transmisión al sensor en particular, el acelerómetro de 3 ejes en nuestro caso. Luego con Wire.write() función pediremos los datos particulares de los dos registros del eje X. El Cable.endTransmission() finalizará la transmisión y transmitirá los datos de los registros. Ahora con Wire.requestFrom() función solicitaremos los datos transmitidos o los dos bytes de los dos registros.

El Cable.disponible() la función devolverá el número de bytes disponibles para la recuperación y si ese número coincide con nuestros bytes solicitados, en nuestro caso 2 bytes, usando Wire.read() función vamos a leer los bytes de los dos registros del eje X. Al final imprimiremos los datos en el monitor serie. Aquí están esos datos, pero tenga en cuenta que se trata de datos sin procesar y se necesita hacer algo de matemática para obtener los valores correctos del eje X. Puede encontrar más detalles al respecto en mi próximo tutorial sobre el uso de acelerómetros con la placa Arduino porque no quiero sobrecargar este tutorial porque su objetivo principal era explicar cómo funciona la comunicación Arduino I2C.

/*  
 *  How I2C Communication Protocol Works - Arduino I2C Tutorial
 *  
 *   by Dejan, www.HowToMechatronics.com 
 *   
 */

#include <Wire.h>

int ADXLAddress = 0x53; // Device address in which is also included the 8th bit for selecting the mode, read in this case.

#define X_Axis_Register_DATAX0 0x32 // Hexadecima address for the DATAX0 internal register.
#define X_Axis_Register_DATAX1 0x33 // Hexadecima address for the DATAX1 internal register.
#define Power_Register 0x2D // Power Control Register

int X0,X1,X_out;

void setup() {
  Wire.begin(); // Initiate the Wire library
  Serial.begin(9600);
  delay(100);
  // Enable measurement
  Wire.beginTransmission(ADXLAddress);
  Wire.write(Power_Register);
  // Bit D3 High for measuring enable (0000 1000)
  Wire.write(8);  
  Wire.endTransmission();
}

void loop() {
  Wire.beginTransmission(ADXLAddress); // Begin transmission to the Sensor 
  //Ask the particular registers for data
  Wire.write(X_Axis_Register_DATAX0);
  Wire.write(X_Axis_Register_DATAX1);
  
  Wire.endTransmission(); // Ends the transmission and transmits the data from the two registers
  
  Wire.requestFrom(ADXLAddress,2); // Request the transmitted two bytes from the two registers
  
  if(Wire.available()<=2) {  // 
    X0 = Wire.read(); // Reads the data from the register
    X1 = Wire.read();   
  }
  
  Serial.print("X0= ");
  Serial.print(X0);
  Serial.print("   X1= ");
  Serial.println(X1);
}Code language: Arduino (arduino)

Proceso de manufactura

  1. Comunicación de Arduino I2C con Raspi 2 WIOT
  2. Cómo construir un monitor de energía Arduino y un registrador de datos
  3. Registrador de datos de temperatura y humedad
  4. Python3 y comunicación Arduino
  5. Cómo utilizar NMEA-0183 con Arduino
  6. Tutorial de Arduino:JARVIS v1 | Cómo hacer una automatización del hogar
  7. Cómo realizar múltiples subprocesos en un Arduino (Tutorial de protothreading)
  8. nRF24L01 - Cómo funciona, interfaz Arduino, circuitos, códigos
  9. Tutorial de acelerómetro y giroscopio Arduino y MPU6050
  10. Cómo rastrear la orientación con Arduino y el acelerómetro ADXL345
  11. Módulo de comunicación inalámbrica de largo alcance Arduino y HC-12