¿Alguna vez has querido saber cómo realizar un seguimiento preciso de la alineación utilizando el acelerómetro Arduino y el ADXL345? En este artículo, te enseñaremos paso a paso cómo lograrlo. ¡No te lo pierdas!
En este tutorial aprenderemos cómo medir ángulos y rastrear orientación usando Arduino y el acelerómetro ADXL345. Para obtener más detalles, puede ver el siguiente vídeo o leer el tutorial escrito a continuación.
descripción general
Primero explicaré cómo funciona el sensor y cómo leer los datos del mismo, y luego crearemos una visualización 3D de la orientación del acelerómetro utilizando el entorno de desarrollo Processing.
Así funciona el acelerómetro ADXL345
Primero, echemos un vistazo a cómo funciona el sensor ADXL345. Este es un acelerómetro de 3 ejes que puede medir fuerzas de aceleración tanto estáticas como dinámicas. La fuerza gravitacional de la Tierra es un ejemplo típico de fuerza estática, mientras que las fuerzas dinámicas pueden ser causadas por vibraciones, movimientos, etc.
La>
Entonces, si colocamos un acelerómetro en posición horizontal con el eje Z apuntando hacia arriba, contra la gravedad, la salida del eje Z del sensor será 1 g. Las salidas X e Y, por otro lado, son cero porque la gravedad es perpendicular a estos ejes y no los afecta en absoluto.
Si>
Usando>
Cómo leer datos del acelerómetro ADXL345 con Arduino
Bien, ahora veamos cómo podemos leer los datos del acelerómetro ADXL345 usando Arduino. Este sensor utiliza el protocolo I2C para comunicarse con el Arduino, por lo que sólo necesitamos dos cables para la conexión y los dos cables para la alimentación.
Puede>
- Acelerómetro ADXL345………………. Amazonas / Banggood / AliExpress
- Placa Arduino……………………………….. Amazon / Banggood / AliExpress
- Cables de puente y placa de pruebas………… Amazonas / Banggood / AliExpress
Divulgación: estos son enlaces de afiliados. Como asociado de Amazon, gano con compras que califican.
Ver también
Cómo funcionan los acelerómetros, giroscopios y magnetómetros MEMS
Acelerómetro ADXL345 Código Arduino
Aquí está el código Arduino para leer los datos del acelerómetro ADXL345.
/*
Arduino and ADXL345 Accelerometer Tutorial
by Dejan, https://howtomechatronics.com
*/
#include <Wire.h> // Wire library - used for I2C communication
int ADXL345 = 0x53; // The ADXL345 sensor I2C address
float X_out, Y_out, Z_out; // Outputs
void setup() {
Serial.begin(9600); // Initiate serial communication for printing the results on the Serial monitor
Wire.begin(); // Initiate the Wire library
// Set ADXL345 in measuring mode
Wire.beginTransmission(ADXL345); // Start communicating with the device
Wire.write(0x2D); // Access/ talk to POWER_CTL Register - 0x2D
// Enable measurement
Wire.write(8); // (8dec -> 0000 1000 binary) Bit D3 High for measuring enable
Wire.endTransmission();
delay(10);
}
void loop() {
// === Read acceleromter data === //
Wire.beginTransmission(ADXL345);
Wire.write(0x32); // Start with register 0x32 (ACCEL_XOUT_H)
Wire.endTransmission(false);
Wire.requestFrom(ADXL345, 6, true); // Read 6 registers total, each axis value is stored in 2 registers
X_out = ( Wire.read()| Wire.read() << 8); // X-axis value
X_out = X_out/256; //For a range of +-2g, we need to divide the raw values by 256, according to the datasheet
Y_out = ( Wire.read()| Wire.read() << 8); // Y-axis value
Y_out = Y_out/256;
Z_out = ( Wire.read()| Wire.read() << 8); // Z-axis value
Z_out = Z_out/256;
Serial.print("Xa= ");
Serial.print(X_out);
Serial.print(" Ya= ");
Serial.print(Y_out);
Serial.print(" Za= ");
Serial.println(Z_out);
}
Code language: Arduino (arduino)
Descripción: Por lo tanto, primero debemos incluir la biblioteca Wire.h, que se utiliza para la comunicación I2C. Si desea obtener más información sobre cómo funciona la comunicación I2C y cómo usarla con Arduino, puede consultar mi otro tutorial detallado al respecto.
Cada dispositivo que utiliza comunicación I2C tiene una dirección I2C única. Puede encontrar esta dirección en la hoja de datos del sensor (Hoja de datos ADXL345). Entonces, después de definir la dirección y las variables para las tres salidas en la sección de configuración, primero debemos inicializar la biblioteca de cables y luego poner el acelerómetro en modo de medición. Para lograr esto, mirando la hoja de datos nuevamente podemos ver que necesitamos configurar el bit D3 del registro POWER_CTL en ALTO.
Entonces>
// Set ADXL345 in measuring mode
Wire.beginTransmission(ADXL345); // Start communicating with the device
Wire.write(0x2D); // Access/ talk to POWER_CTL Register - 0x2D
// Enable measurement
Wire.write(8); // (8dec -> 0000 1000 binary) Bit D3 High for measuring enable
Wire.endTransmission();
Code language: Arduino (arduino)
En la sección del bucle ahora leemos los datos del sensor. Los datos de cada eje se almacenan en dos bytes o registros. Podemos encontrar las direcciones de estos registros en la hoja de datos.
Para>
// === Read acceleromter data === //
Wire.beginTransmission(ADXL345);
Wire.write(0x32); // Start with register 0x32 (ACCEL_XOUT_H)
Wire.endTransmission(false);
Wire.requestFrom(ADXL345, 6, true); // Read 6 registers total, each axis value is stored in 2 registers
X_out = ( Wire.read()| Wire.read() << 8); // X-axis value
X_out = X_out/256; //For a range of +-2g, we need to divide the raw values by 256, according to the datasheet
Y_out = ( Wire.read()| Wire.read() << 8); // Y-axis value
Y_out = Y_out/256;
Z_out = ( Wire.read()| Wire.read() << 8); // Z-axis value
Z_out = Z_out/256;
Code language: Arduino (arduino)
Los valores de salida del sensor dependen en realidad de la sensibilidad seleccionada, que puede variar entre +-2g y +-16g. La sensibilidad predeterminada es +-2g, por lo que debemos dividir la salida por 256 para obtener valores de -1 a +1g. Los 256 LSB/g significan que tenemos 256 cuentas por g.
Dependiendo>
Calibración del acelerómetro ADXL345
Sin embargo, una vez leídos los datos, simplemente podemos imprimirlos en el monitor serie para verificar que los valores son los esperados. En mi caso los valores que recibí no fueron exactamente como deberían ser, especialmente el eje Z que tenía un error notorio de 0.1g.
Para>
Desde>
// This code goes in the SETUP section
// Off-set Calibration
//X-axis
Wire.beginTransmission(ADXL345);
Wire.write(0x1E); // X-axis offset register
Wire.write(1);
Wire.endTransmission();
delay(10);
//Y-axis
Wire.beginTransmission(ADXL345);
Wire.write(0x1F); // Y-axis offset register
Wire.write(-2);
Wire.endTransmission();
delay(10);
//Z-axis
Wire.beginTransmission(ADXL345);
Wire.write(0x20); // Z-axis offset register
Wire.write(-7);
Wire.endTransmission();
delay(10);
Code language: Arduino (arduino)
Si es necesario, debemos calibrar el otro eje usando el mismo método. Y solo una nota rápida: esta calibración no se escribe permanentemente en los registros. Necesitamos escribir estos valores en los registros cada vez que se enciende el sensor.
Una vez que hayamos terminado con la calibración, finalmente podemos calcular el balanceo y el cabeceo, o la rotación alrededor del eje X y la rotación alrededor del eje Y en grados, usando estas dos fórmulas.
// Calculate Roll and Pitch (rotation around X-axis, rotation around Y-axis)
roll = atan(Y_out / sqrt(pow(X_out, 2) + pow(Z_out, 2))) * 180 / PI;
pitch = atan(-1 * X_out / sqrt(pow(Y_out, 2) + pow(Z_out, 2))) * 180 / PI;
Code language: Arduino (arduino)
Puedes encontrar más información sobre cómo funcionan estas fórmulas aquí Nota de aplicación de Freescale Semiconductor.
Seguimiento de orientación del acelerómetro Arduino y ADXL345: visualización 3D
Bien, ahora creemos el ejemplo de visualización 3D del acelerómetro.
Entonces>
/*
Arduino and ADXL345 Accelerometer - 3D Visualization Example
by Dejan, https://howtomechatronics.com
*/
#include <Wire.h> // Wire library - used for I2C communication
int ADXL345 = 0x53; // The ADXL345 sensor I2C address
float X_out, Y_out, Z_out; // Outputs
float roll,pitch,rollF,pitchF=0;
void setup() {
Serial.begin(9600); // Initiate serial communication for printing the results on the Serial monitor
Wire.begin(); // Initiate the Wire library
// Set ADXL345 in measuring mode
Wire.beginTransmission(ADXL345); // Start communicating with the device
Wire.write(0x2D); // Access/ talk to POWER_CTL Register - 0x2D
// Enable measurement
Wire.write(8); // Bit D3 High for measuring enable (8dec -> 0000 1000 binary)
Wire.endTransmission();
delay(10);
//Off-set Calibration
//X-axis
Wire.beginTransmission(ADXL345);
Wire.write(0x1E);
Wire.write(1);
Wire.endTransmission();
delay(10);
//Y-axis
Wire.beginTransmission(ADXL345);
Wire.write(0x1F);
Wire.write(-2);
Wire.endTransmission();
delay(10);
//Z-axis
Wire.beginTransmission(ADXL345);
Wire.write(0x20);
Wire.write(-9);
Wire.endTransmission();
delay(10);
}
void loop() {
// === Read acceleromter data === //
Wire.beginTransmission(ADXL345);
Wire.write(0x32); // Start with register 0x32 (ACCEL_XOUT_H)
Wire.endTransmission(false);
Wire.requestFrom(ADXL345, 6, true); // Read 6 registers total, each axis value is stored in 2 registers
X_out = ( Wire.read() | Wire.read() << 8); // X-axis value
X_out = X_out / 256; //For a range of +-2g, we need to divide the raw values by 256, according to the datasheet
Y_out = ( Wire.read() | Wire.read() << 8); // Y-axis value
Y_out = Y_out / 256;
Z_out = ( Wire.read() | Wire.read() << 8); // Z-axis value
Z_out = Z_out / 256;
// Calculate Roll and Pitch (rotation around X-axis, rotation around Y-axis)
roll = atan(Y_out / sqrt(pow(X_out, 2) + pow(Z_out, 2))) * 180 / PI;
pitch = atan(-1 * X_out / sqrt(pow(Y_out, 2) + pow(Z_out, 2))) * 180 / PI;
// Low-pass filter
rollF = 0.94 * rollF + 0.06 * roll;
pitchF = 0.94 * pitchF + 0.06 * pitch;
Serial.print(rollF);
Serial.print("/");
Serial.println(pitchF);
}
Code language: Arduino (arduino)
Ahora en Entorno de desarrollo de procesamiento Necesitamos recibir estos valores y usarlos para rotar el objeto 3D que vamos a crear. Aquí está el código de procesamiento completo:
/*
Arduino and ADXL345 Accelerometer - 3D Visualization Example
by Dejan, https://howtomechatronics.com
*/
import processing.serial.*;
import java.awt.event.KeyEvent;
import java.io.IOException;
Serial myPort;
String data="";
float roll, pitch;
void setup() {
size (960, 640, P3D);
myPort = new Serial(this, "COM8", 9600); // starts the serial communication
myPort.bufferUntil('n');
}
void draw() {
translate(width/2, height/2, 0);
background(33);
textSize(22);
text("Roll: " + int(roll) + " Pitch: " + int(pitch), -100, 265);
// Rotate the object
rotateX(radians(roll));
rotateZ(radians(-pitch));
// 3D 0bject
textSize(30);
fill(0, 76, 153);
box (386, 40, 200); // Draw box
textSize(25);
fill(255, 255, 255);
text("www.HowToMechatronics.com", -183, 10, 101);
//delay(10);
//println("ypr:t" + angleX + "t" + angleY); // Print the values to check whether we are getting proper values
}
// Read data from the Serial Port
void serialEvent (Serial myPort) {
// reads the data from the Serial Port up to the character '.' and puts it into the String variable "data".
data = myPort.readStringUntil('n');
// if you got any bytes other than the linefeed:
if (data != null) {
data = trim(data);
// split the string at "/"
String items[] = split(data, '/');
if (items.length > 1) {
//--- Roll,Pitch in degrees
roll = float(items[0]);
pitch = float(items[1]);
}
}
}
Code language: Arduino (arduino)
Descripción: Entonces aquí necesitamos incluir la biblioteca serial, definir el puerto serial y la velocidad en baudios, que debe coincidir con la velocidad en baudios del boceto Arduino cargado. Luego leemos los datos entrantes y los insertamos en las variables de balanceo y cabeceo apropiadas. En el bucle de dibujo principal, usamos estos valores para rotar el objeto 3D. En este caso se trata de un campo simple con un color y un texto específicos.
Cuando ejecutamos el boceto, aparece el objeto 3D y sigue la orientación del acelerómetro. Aquí podemos notar que el objeto en realidad tiembla un poco, y esto se debe a que el acelerómetro detecta no solo la fuerza gravitacional, sino también pequeñas fuerzas creadas por los movimientos de nuestra mano. Para obtener un resultado más suave podemos utilizar un filtro de paso bajo simple. Aquí he implementado un filtro de este tipo en el código Arduino que toma el 94% del estado anterior y agrega el 6% del estado o ángulo actual.
// Low-pass filter
rollF = 0.94 * rollF + 0.06 * roll;
pitchF = 0.94 * pitchF + 0.06 * pitch;
Code language: Arduino (arduino)
Con este filtro podemos ver que el objeto ahora se mueve mucho más suavemente, pero también hay un efecto secundario y es una capacidad de respuesta más lenta. También podemos notar que nos falta guiñada o rotación alrededor del eje Z. Si solo utilizamos los datos del acelerómetro de 3 ejes, no podemos calcular la guiñada.
Para lograr esto y mejorar el rendimiento general de nuestro sensor de seguimiento de orientación, necesitamos incluir un sensor adicional, un giroscopio, y fusionar sus datos con el acelerómetro.
Entonces>
Ver también
Tutorial de acelerómetro y giroscopio Arduino y MPU6050
Espero que hayas disfrutado este tutorial y hayas aprendido algo nuevo. No dudes en hacer tus preguntas en la sección de comentarios a continuación y no olvides echar un vistazo a mi colección de proyectos Arduino.
Cómo realizar un seguimiento de la alineación con el acelerómetro Arduino y ADXL345
En este tutorial aprenderemos cómo medir ángulos y hacer un seguimiento de la orientación utilizando el Arduino y el sensor acelerómetro ADXL345. Puede ver el video a continuación o leer el tutorial escrito para obtener más detalles.
Visión General
En primer lugar, explicaré cómo funciona el sensor y cómo leer los datos de él. Luego, utilizando el entorno de desarrollo Processing, crearemos una visualización 3D de la orientación del acelerómetro.
¿Cómo funciona el acelerómetro ADXL345?
El ADXL345 es un acelerómetro de 3 ejes que puede medir tanto fuerzas estáticas como dinámicas de aceleración. La fuerza gravitacional terrestre es un ejemplo típico de fuerza estática, mientras que las fuerzas dinámicas pueden ser causadas por vibraciones, movimientos, etc.
La unidad de medida para la aceleración es el metro por segundo al cuadrado (m/s^2). Sin embargo, los sensores de acelerómetro suelen expresar las mediciones en «g» o gravedad. 1 «g» equivale a 9.8 metros por segundo al cuadrado, que es el valor de la fuerza gravitatoria terrestre.
Si tenemos un acelerómetro posicionado planamente, con su eje Z apuntando hacia arriba y opuesto a la fuerza gravitatoria, la salida del eje Z del sensor será de 1g. Por otro lado, las salidas X e Y serán cero, ya que la fuerza gravitatoria es perpendicular a estos ejes y no los afecta en absoluto.
Si damos la vuelta al sensor, entonces la salida del eje Z será de -1g. Esto significa que las salidas del sensor debido a su orientación a la gravedad pueden variar de -1g a +1g. Con estos datos y utilizando matemáticas trigonométricas, podemos calcular el ángulo en el que se encuentra el sensor.
¿Cómo leer los datos del acelerómetro ADXL345 con Arduino?
Para leer los datos del acelerómetro ADXL345 usando Arduino, necesitamos usar el protocolo I2C para la comunicación. Conectamos el sensor con solo dos cables más los dos cables de alimentación.
Puedes obtener los componentes necesarios para este tutorial de Arduino en los siguientes enlaces:
- ADXL345 Acelerómetro – Amazon / Banggood / AliExpress
- Placa Arduino – Amazon / Banggood / AliExpress
- Protoboard y Cables Puente – Amazon / Banggood / AliExpress
Estos son enlaces de afiliados. Como Asociado de Amazon, gano dinero con las compras calificadas.
En el código de Arduino, primero inicializamos la comunicación I2C y configuramos el sensor en modo de medición. Luego leemos los datos del sensor para cada eje, realizando los cálculos necesarios para obtener los valores de aceleración.
Si es necesario, también debemos calibrar el acelerómetro para garantizar lecturas precisas. Usamos los valores de desplazamiento para corregir posibles errores en los datos leídos.
Finalmente, calculamos el Roll y Pitch, o la rotación alrededor del eje X y la rotación alrededor del eje Y en grados, utilizando fórmulas trigonométricas.
Espero que este tutorial te haya sido útil. Si tienes alguna pregunta, no dudes en dejarla en la sección de comentarios. ¡No te olvides de revisar mi colección de Proyectos de Arduino!
¡Interesante artículo! Parece una forma creativa de utilizar el acelerómetro en Arduino. ¡Definitivamente voy a intentarlo!
¡Suena genial! Nunca hubiera pensado en usar un acelerómetro de esa manera con Arduino. ¡Definitivamente voy a probarlo en mi próximo proyecto!
¡Guau, qué chévere! Nunca pensé que se pudiera hacer algo así con un acelerómetro en Arduino. Definitivamente tengo que probar este proyecto, suena emocionante. ¡Gracias por compartir la información!
¡Qué divertido! Nunca imaginé que se pudiera hacer seguimiento de la alineación con un acelerómetro en Arduino. ¡Ahora quiero probarlo yo también!