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)