arduino-acelerometro-adxl345

Usar un acelerómetro ADXL345 con Arduino

¿Qué es un acelerómetro ADXL345?

El ADXL345 es un acelerómetro micromecanizado capacitivo de 3 ejes independientes (3 DOF), que puede ser fácilmente conectado a un autómata o procesador como Arduino.

Es un sensor micromecanizado (MEMS) capacitivo que detecta la aceleración en los ejes X, Y y Z. También es posible determinar la orientación del sensor, gracias a la acción de la fuerza de la gravedad.

El ADXL345 es un dispositivo de ultra bajo consumo, con 45 µA en modo de medición y 0.1 µA en standby. Además dispone de un bloque de memoria FIFO que almacena hasta 32 conjuntos X, Y, Z.

La comunicación puede realizarse tanto por bus SPI como por bus I2C, por lo que es sencillo obtener los datos medidos. La tensión de alimentación es de bajo voltaje entre 2.0 a 3.6V.

Frecuentemente se encuentran integrados en módulos que incorporan la electrónica necesaria para conectarla de forma sencilla a un Arduino. En la mayoría de los módulos, esto incluye un regulador de voltaje que permite alimentar directamente a 5V.

El ADXL345 tiene un rango de medición ajustable entre ±2g, ±4g, ±8g, ±16g, y una alta resolución de hasta 13 bits, con una sensibilidad de 40mg/LSB en todos los rangos, lo que equivale a una precisión superior a un 1º.

El ADXL345 dispone de dos pines de interrupciones que podemos configurar para responder a ciertos eventos. Estos eventos incluyen detección de movimientos rápidos golpes y vibraciones, en uno o dos pulsos, y detección de condiciones de caída libre 0-g.

Los acelerómetros son dispositivos ampliamente utilizados en todo tipo de dispositivos, desde determinar la orientación en móviles o tablets, detectar la caída libre, medir pasos en podómetros, estabilización de cámaras, alarmas y sensores de vibración, entre muchos otros.

Si quieres saber más sobre acelerómetros, giroscopios e IMU’s en Arduino consulta las serie de entradas Cómo usar un acelerómetro con Arduino, Cómo usar un giroscopio con Arduino y Medir la inclinación con IMU.

Precio

El ADXL345 es un acelerómetro barato. Podemos encontrarlo en placas de montaje como la GY-291, que incorpora la electrónica necesaria para conectarlo de forma sencilla a Arduino, por 1.10€ en vendedores internacionales de eBay o AliExpress.

arduino-acelerometro-adxl345-componente

Pese a ser barato, por precios similares tenemos IMUs como el MPU6050, que incorporan acelerómetro y giroscopio, y por tanto tienen características superiores y son más versátiles.

Esquema montaje

La conexión es sencilla, simplemente alimentamos el módulo desde Arduino mediante GND y 5V y conectamos el pin SDA y SCL de Arduino con los pines correspondientes del sensor.

arduino-acelerometro-adxl345-esquema

Mientras que la conexión vista desde el lado de Arduino quedaría así.

arduino-acelerometro-ADXL345-conexion

En Arduino Uno, Nano y Mini Pro, SDA es el pin A4 y el SCK el pin A5. Para otros modelos de Arduino consultar el esquema patillaje correspondiente.

Verificar que vuestra placa es compatible con 5V antes de conectarla a Arduino. Si no, tendréis que usar un adaptador de nivel lógico.

Ejemplos de código

El siguiente código realiza la lectura del AXDL345 en bruto (RAW) y muestra los valores por puerto serie.

// Gnd      -  GND
// 3.3v     -  VCC
// 3.3v     -  CS
// Analog 4 -  SDA
// Analog 5 -  SLC

#include <Wire.h>

//Direccion del dispositivo
const int DEVICE_ADDRESS = (0x53);  

byte _buff[6];

//Direcciones de los registros del ADXL345
char POWER_CTL = 0x2D;
char DATA_FORMAT = 0x31;
char DATAX0 = 0x32;  //X-Axis Data 0
char DATAX1 = 0x33;  //X-Axis Data 1
char DATAY0 = 0x34;  //Y-Axis Data 0
char DATAY1 = 0x35;  //Y-Axis Data 1
char DATAZ0 = 0x36;  //Z-Axis Data 0
char DATAZ1 = 0x37;  //Z-Axis Data 1

void setup()
{
  Serial.begin(57000);
  Serial.print("Iniciado");
  
  Wire.begin();
  writeTo(DEVICE_ADDRESS, DATA_FORMAT, 0x01); //Poner ADXL345 en +- 4G
  writeTo(DEVICE_ADDRESS, POWER_CTL, 0x08);  //Poner el ADXL345 
}

void loop()
{
  readAccel(); //Leer aceleracion x, y, z
  delay(500);
}

void readAccel() {
  //Leer los datos
  uint8_t numBytesToRead = 6;
  readFrom(DEVICE_ADDRESS, DATAX0, numBytesToRead, _buff);

  //Leer los valores del registro y convertir a int (Cada eje tiene 10 bits, en 2 Bytes LSB)
  int x = (((int)_buff[1]) << 8) | _buff[0];   
  int y = (((int)_buff[3]) << 8) | _buff[2];
  int z = (((int)_buff[5]) << 8) | _buff[4];
  Serial.print("x: ");
  Serial.print( x );
  Serial.print(" y: ");
  Serial.print( y );
  Serial.print(" z: ");
  Serial.println( z );
}

//Funcion auxiliar de escritura
void writeTo(int device, byte address, byte val) {
  Wire.beginTransmission(device);
  Wire.write(address);
  Wire.write(val);
  Wire.endTransmission(); 
}

//Funcion auxiliar de lectura
void readFrom(int device, byte address, int num, byte _buff[]) {
  Wire.beginTransmission(device);
  Wire.write(address);
  Wire.endTransmission();

  Wire.beginTransmission(device);
  Wire.requestFrom(device, num);

  int i = 0;
  while(Wire.available())
  { 
    _buff[i] = Wire.read();
    i++;
  }
  Wire.endTransmission();
}

También podemos usar una de las múltiples librerías disponibles. Por ejemplo, la librería proporcionada Sparkfun para el ADXL345. Esta librería proporciona métodos para comunicar tanto por I2C como por SPI, para configurar el ADXL345, y definir interrupciones para detección de actividad, inactividad, pulsaciones normales y dobles.

La librería proporciona ejemplos de código, que resulta aconsejable revisar. El siguiente ejemplo es una versión reducida a partir de los disponibles en la librería, que hace las mismas funciones que el ejemplo anterior con un código mucho más conciso.

#include <SPI.h>
#include <Wire.h>
#include <SparkFun_ADXL345.h> 

ADXL345 adxl = ADXL345();

void setup() 
{
  Serial.begin(9600);             
  Serial.println("Iniciar");
  Serial.println();

  adxl.powerOn();            
  adxl.setRangeSetting(16);       //Definir el rango, valores 2, 4, 8 o 16
}

void loop() 
{
  //leer los valores e imprimirlos
  int x, y, z;
  adxl.readAccel(&x, &y, &z);  
  Serial.print(x);
  Serial.print(", ");
  Serial.print(y);
  Serial.print(", ");
  Serial.println(z); 
}

Descarga el código

Todo el código de esta entrada está disponible para su descarga en Github. github-full