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

Rastreo de orientación con Arduino y acelerómetro ADXL345: Guía paso a paso

En este tutorial aprenderemos a medir ángulo y rastrear orientación usando Arduino y el sensor acelerómetro ADXL345. Puedes ver el vídeo o leer el tutorial escrito para más detalles.

Resumen

Primero explico cómo funciona el sensor y cómo leer sus datos, y luego con el entorno Processing haremos visualización 3D de la orientación del acelerómetro.

Rastreo de orientación con Arduino y acelerómetro ADXL345: Guía paso a paso

Cómo funciona el acelerómetro ADXL345

El ADXL345 es un acelerómetro 3 ejes que mide fuerzas de aceleración estáticas y dinámicas. La fuerza gravitatoria terrestre es ejemplo típico de fuerza estática; fuerzas dinámicas pueden ser vibraciones, movimientos, etc.

Rastreo de orientación con Arduino y acelerómetro ADXL345: Guía paso a paso

Unidad de medida: m/s². Pero sensores suelen expresar en "g" (gravedad). 1 g = fuerza gravitatoria terrestre = 9.8 m/s².

Si acelerómetro está plano, eje Z hacia arriba (opuesto a gravedad), salida Z = 1g. Ejes X e Y = 0 (gravedad perpendicular, no les afecta).

Rastreo de orientación con Arduino y acelerómetro ADXL345: Guía paso a paso

Si volteamos sensor, Z = -1g. Salidas por orientación a gravedad varían de -1g a +1g.

Rastreo de orientación con Arduino y acelerómetro ADXL345: Guía paso a paso

Con estos datos y trigonometría, calculamos ángulo de inclinación del sensor.

Cómo leer datos ADXL345 con Arduino

El sensor usa protocolo I2C: 2 hilos comunicación + 2 alimentación.

Rastreo de orientación con Arduino y acelerómetro ADXL345: Guía paso a paso

Componentes necesarios:

  • Acelerómetro ADXL345 ………………. Amazon / Banggood / AliExpress
  • Placa Arduino ……………………………..
  • Protoboard y cables jumpers …………

Código Arduino ADXL345

/* Arduino y ADXL345 Acelerómetro por Dejan, https://howtomechatronics.com */
#include <Wire.h> // Wire library - I2C communication
int ADXL345 = 0x53; // Dirección I2C ADXL345
float X_out, Y_out, Z_out; // Salidas

void setup() {
  Serial.begin(9600);
  Wire.begin(); // Inicia librería Wire
  // Poner ADXL345 en modo medición
  Wire.beginTransmission(ADXL345);
  Wire.write(0x2D); // Acceder registro POWER_CTL - 0x2D
  Wire.write(8);    // (8dec -> 0000 1000 bin) Bit D3 HIGH para habilitar medición
  Wire.endTransmission();
  delay(10);
}

void loop() {
  // === Leer datos acelerómetro ===
  Wire.beginTransmission(ADXL345);
  Wire.write(0x32); // Registro inicial 0x32 (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(ADXL345, 6, true); // Leer 6 registros (2 por eje)
  X_out = (Wire.read() | Wire.read() << 8); // Valor eje X
  X_out = X_out / 256; // Rango ±2g: dividir raw por 256 (datasheet)
  Y_out = (Wire.read() | Wire.read() << 8); // Valor eje Y
  Y_out = Y_out / 256;
  Z_out = (Wire.read() | Wire.read() << 8); // Valor eje Z
  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);
}

Descripción: Incluimos Wire.h para I2C. Cada dispositivo I2C tiene dirección única (en datasheet ADXL345). Definimos dirección y variables salidas. En setup(): iniciamos Wire y ponemos acelerómetro en modo medición. En datasheet vemos que hay que poner bit D3 del registro POWER_CTL HIGH.

Rastreo de orientación con Arduino y acelerómetro ADXL345: Guía paso a paso

Con beginTransmission() iniciamos comunicación, write() indica registro a acceder, otro write() pone bit D3 HIGH escribiendo 8 decimal (bit D3 HIGH).

// Set ADXL345 in measuring mode
Wire.beginTransmission(ADXL345);
Wire.write(0x2D); // Access/ talk to POWER_CTL Register - 0x2D
Wire.write(8);    // (8dec -> 0000 1000 binary) Bit D3 High for measuring enable
Wire.endTransmission();

En loop() leemos datos. Cada eje en 2 bytes/registros; direcciones en datasheet.

Rastreo de orientación con Arduino y acelerómetro ADXL345: Guía paso a paso

Empezamos en primer registro, requestFrom() pide leer 6 registros. Con read() leemos cada registro, combinamos apropiadamente (complemento a dos) para valores correctos.

// === 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
X_out = (Wire.read() | Wire.read() << 8); // X-axis value
X_out = X_out / 256; // For a range of +-2g, divide raw by 256
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;

Valores de salida dependen de sensibilidad seleccionada (±2g a ±16g). Default ±2g → dividir por 256 para obtener -1 a +1g. 256 LSB/g = 256 cuentas por g.

Rastreo de orientación con Arduino y acelerómetro ADXL345: Guía paso a paso

Según aplicación elegimos sensibilidad. Para rastreo orientación ±2g basta; para detectar aceleraciones altas (movimientos bruscos, golpes) usamos otros rangos via registro DATA_FORMAT bits D1, D0.

Rastreo de orientación con Arduino y acelerómetro ADXL345: Guía paso a paso

Calibración acelerómetro ADXL345

Al leer datos, los imprimimos en monitor serial para verificar. En mi caso, valores no eran exactos, especialmente Z con error notable de 0.1g.

Rastreo de orientación con Arduino y acelerómetro ADXL345: Guía paso a paso

Para solucionar: calibrar usando 3 registros offset. Posicionamos sensor plano, imprimimos valores RAW (sin dividir por 256).

Rastreo de orientación con Arduino y acelerómetro ADXL345: Guía paso a paso

Vemos cuánto se desvían salidas. En mi caso Z ~283 (diferencia +27). Dividimos entre 4 → valor para registro offset Z. Subimos código y Z sale exactamente 256 (1g correcto).

// Este código va en la sección SETUP
// Calibración Offset
// Eje X
Wire.beginTransmission(ADXL345);
Wire.write(0x1E); // Registro offset X
Wire.write(1);
Wire.endTransmission();
delay(10);
// Eje Y
Wire.beginTransmission(ADXL345);
Wire.write(0x1F); // Registro offset Y
Wire.write(-2);
Wire.endTransmission();
delay(10);
// Eje Z
Wire.beginTransmission(ADXL345);
Wire.write(0x20); // Registro offset Z
Wire.write(-7);
Wire.endTransmission();
delay(10);

Calibramos otros ejes mismo método. Nota: calibración no se guarda permanentemente en registros; hay que escribir estos valores en cada encendido del sensor.

Tras calibración, calculamos Roll y Pitch (rotación eje X, rotación eje Y) en grados con estas fórmulas:

// Calcular Roll y Pitch (rotación eje X, rotación eje Y)
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;

Detalles fórmulas: Application Note Freescale Semiconductor.

Arduino y ADXL345 – Rastreo orientación 3D

Hagamos ejemplo visualización 3D.

Rastreo de orientación con Arduino y acelerómetro ADXL345: Guía paso a paso

Mismo código enviando Roll y Pitch por puerto serial. Código Arduino completo:

/* Arduino y ADXL345 Acelerómetro - Visualización 3D por Dejan, https://howtomechatronics.com */
#include <Wire.h>
int ADXL345 = 0x53;
float X_out, Y_out, Z_out;
float roll, pitch, rollF, pitchF = 0;

void setup() {
  Serial.begin(9600);
  Wire.begin();
  // Modo medición
  Wire.beginTransmission(ADXL345);
  Wire.write(0x2D); // POWER_CTL Register
  Wire.write(8);    // Bit D3 HIGH
  Wire.endTransmission();
  delay(10);
  // Calibración Offset
  // 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() {
  // Leer acelerómetro
  Wire.beginTransmission(ADXL345);
  Wire.write(0x32); // ACCEL_XOUT_H
  Wire.endTransmission(false);
  Wire.requestFrom(ADXL345, 6, true);
  X_out = (Wire.read() | Wire.read() << 8); X_out = X_out / 256;
  Y_out = (Wire.read() | Wire.read() << 8); Y_out = Y_out / 256;
  Z_out = (Wire.read() | Wire.read() << 8); Z_out = Z_out / 256;
  // Calcular Roll y Pitch
  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;
  // Filtro paso bajo
  rollF = 0.94 * rollF + 0.06 * roll;
  pitchF = 0.94 * pitchF + 0.06 * pitch;
  Serial.print(rollF); Serial.print("/"); Serial.println(pitchF);
}

En Processing recibimos valores y rotamos objeto 3D. Código Processing completo:

/* Arduino y ADXL345 Acelerómetro - Visualización 3D por 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); // Puerto serial y baud rate = Arduino sketch
  myPort.bufferUntil('\n');
}

void draw() {
  translate(width/2, height/2, 0);
  background(33);
  textSize(22);
  text("Roll: " + int(roll) + " Pitch: " + int(pitch), -100, 265);
  // Rotar objeto
  rotateX(radians(roll));
  rotateZ(radians(-pitch));
  // Objeto 3D
  textSize(30);
  fill(0, 76, 153);
  box(386, 40, 200); // Dibujar caja
  textSize(25);
  fill(255, 255, 255);
  text("www.HowToMechatronics.com", -183, 10, 101);
}

// Leer datos Puerto Serial
void serialEvent(Serial myPort) {
  data = myPort.readStringUntil('\n');
  if (data != null) {
    data = trim(data);
    // Separar en "/"
    String items[] = split(data, '/');
    if (items.length > 1) {
      roll = float(items[0]);
      pitch = float(items[1]);
    }
  }
}

Descripción: Incluimos librería serial, definimos puerto y baud rate (debe coincidir con sketch Arduino). Leemos datos entrantes y ponemos en variables roll, pitch. En draw() usamos para rotar objeto 3D (caja con color y texto).

Al ejecutar, objeto 3D aparece y sigue orientación del acelerómetro. Notamos que objeto tiembla un poco: acelerómetro capta no solo gravedad, sino pequeñas fuerzas de movimiento de mano. Para suavizar: filtro paso bajo (Low-pass filter). Implementé en código Arduino: toma 94% estado anterior + 6% estado actual.

// Low-pass filter
rollF = 0.94 * rollF + 0.06 * roll;
pitchF = 0.94 * pitchF + 0.06 * pitch;

Con filtro, movimiento más suave, pero respuesta más lenta. También notamos que falta Yaw (rotación eje Z). Con solo acelerómetro 3 ejes no podemos calcular Yaw.

Para mejorar rastreo orientación, necesitamos sensor adicional: giroscopio, y fusionar sus datos con acelerómetro.

Rastreo de orientación con Arduino y acelerómetro ADXL345: Guía paso a paso

O usamos ADXL345 + giroscopio aparte, o MPU6050 IMU que integra ambos en un chip. Tutorial detallado MPU6050 en mi próximo vídeo.

¡Espero que hayas disfrutado y aprendido! Preguntas en comentarios y revisa mi Colección Proyectos Arduino.

Proceso de manufactura

  1. Control Preciso de Servo con Arduino y MPU6050 (SG90 / MG996R)
  2. Módulo GPS u-blox LEA‑6H 02: Guía de integración con Arduino y Python
  3. Leer Temperatura y Humedad con DHT11 en Blynk – Tutorial Paso a Paso con Arduino
  4. Dominando reconocimiento y síntesis de voz en Arduino Due
  5. Genera Tonos Musicales con Arduino: Guía Paso a Paso
  6. Conexión de Arduino a NMEA‑0183: Guía Paso a Paso
  7. Domina Modbus en Arduino: Guía Paso a Paso
  8. Cafetera inteligente con Arduino, control por Bluetooth y monitorización de temperatura
  9. Crea una Tira LED Inteligente Animada Controlada por Alexa con Arduino
  10. Proyecto LED Controlado por Voz: Arduino Micro + BitVoicer Server para Reconocimiento Voz
  11. Construye tu Propio Robot Asistente IA con Arduino y Python