Ejemplos de Acelerómetro ADXL345 Controlado mediante Bus SPI

ejemplos de acelerometro adxl345 controlado mediante bus spi

ejemplos de acelerometro adxl345 controlado mediante bus spi

Introducción al ADXL345 y SPI

El acelerómetro ADXL345 controlado mediante bus SPI es una opción fantástica para proyectos de electrónica que requieren mediciones de aceleración precisas y fiables. Después de probar varios acelerómetros en el taller de DunaTech, como el MPU-6050 y el LIS3DH, el ADXL345 de Analog Devices destacó por su versatilidad, su bajo consumo de energía y la facilidad de configuración a través de la interfaz SPI. Este sensor es capaz de medir la aceleración estática de la gravedad en aplicaciones de detección de inclinación, así como la aceleración dinámica resultante del movimiento o el impacto en tres ejes. Su robustez y la claridad de su hoja de datos lo convierten en un favorito para ingenieros y aficionados por igual, siendo ideal para aplicaciones que van desde la estabilización de cámaras y sistemas de monitoreo de vibraciones hasta interfaces de usuario basadas en gestos o controles de movimiento en robótica. Aquí te explicaremos cómo configurarlo de manera eficiente y sacarle el máximo partido.

¿Por Qué Elegir el ADXL345 para tus Proyectos?

El ADXL345 es una excelente elección para tus proyectos por varias razones clave: ofrece una alta resolución (hasta 13 bits), un amplio rango de medición (±2g, ±4g, ±8g, ±16g) y un bajo consumo de energía, lo que lo hace ideal para dispositivos alimentados por batería. En DunaTech, hemos comprobado que su interfaz SPI es particularmente ventajosa para proyectos que demandan alta velocidad de datos o donde se necesita conectar múltiples sensores al mismo bus, ya que SPI permite una comunicación full-duplex y es menos susceptible a ruido que I2C en ciertos entornos. Además, su tamaño compacto y la disponibilidad de módulos pre-ensamblados facilitan enormemente su integración en prototipos y productos finales. Es un sensor muy bien documentado, lo que simplifica la fase de desarrollo y depuración.

Los precios y la disponibilidad pueden variar. Como asociados de AliExpress, podemos recibir una comisión por las compras que cumplan los requisitos.

Cómo Conectar el Acelerómetro ADXL345 mediante Bus SPI

Para conectar el acelerómetro ADXL345 mediante bus SPI a una placa de desarrollo como Arduino, es crucial seguir un esquema de cableado preciso para asegurar una comunicación estable y correcta. En nuestras pruebas, conectamos el ADXL345 a una placa Arduino Uno, que es un microcontrolador muy común y accesible para empezar. La interfaz SPI requiere cuatro líneas principales: MOSI, MISO, SCK y CS, además de la alimentación. Aquí están los pasos detallados para realizar la conexión, prestando especial atención a los voltajes para evitar daños al sensor:

1. Cableado del ADXL345 a Arduino Uno

  • VCC (Voltaje de Alimentación): Conéctalo al pin de 3.3V del Arduino. Es fundamental usar 3.3V, ya que el ADXL345 es un dispositivo de 3.3V. Aunque algunos módulos tienen reguladores de voltaje integrados que permiten 5V, la especificación de Analog Devices recomienda 3.3V para un rendimiento óptimo y para evitar estrés en el chip.
  • GND (Tierra): Conéctalo a cualquier pin GND del Arduino.
  • CS (Chip Select / Slave Select): Este pin es crucial para SPI, ya que permite seleccionar qué dispositivo esclavo está activo en el bus. Conéctalo a un pin digital configurable del Arduino, por ejemplo, el pin 10. Siempre debe estar en HIGH cuando el dispositivo no está seleccionado y en LOW cuando se desea comunicar con él.
  • SCL (Serial Clock): Conéctalo al pin SCK del Arduino. En un Arduino Uno, este es el pin digital 13. Esta línea sincroniza la comunicación entre el maestro (Arduino) y el esclavo (ADXL345).
  • SDA (Serial Data In / MOSI – Master Out, Slave In): Conéctalo al pin MOSI del Arduino. En un Arduino Uno, este es el pin digital 11. Por esta línea, el Arduino envía datos al ADXL345.
  • SDO (Serial Data Out / MISO – Master In, Slave Out): Conéctalo al pin MISO del Arduino. En un Arduino Uno, este es el pin digital 12. Por esta línea, el ADXL345 envía datos de vuelta al Arduino.

2. Configuración del Bus SPI

La comunicación SPI requiere que el microcontrolador (Arduino) actúe como maestro y el ADXL345 como esclavo. Debes inicializar la biblioteca SPI en tu código y configurar los parámetros adecuados. Esto incluye definir el pin CS, establecer el modo SPI (generalmente MODE0 o MODE3 para el ADXL345, aunque MODE0 es el más común) y la velocidad del reloj. En nuestras pruebas, una frecuencia de reloj de 5 MHz (o un divisor como SPI_CLOCK_DIV4 o SPI_CLOCK_DIV8 en Arduino) ha demostrado ser ideal para una comunicación estable y lecturas precisas, aunque el ADXL345 puede soportar hasta 10 MHz. Ojo con esto: una velocidad demasiado alta puede generar errores de lectura, especialmente con cables largos o de baja calidad.

Código Ejemplo Detallado para Controlar el ADXL345 con Arduino

Para que el ADXL345 funcione correctamente, es necesario un código que inicialice el sensor, configure sus registros internos y luego lea los datos de aceleración. Aquí tienes un ejemplo funcional que hemos probado extensamente en el laboratorio de DunaTech, utilizando la biblioteca estándar `SPI.h` de Arduino. Este código no solo te muestra cómo leer los datos, sino también cómo inicializar el sensor para empezar a medir.

«`cpp
#include <SPI.h> // Incluye la biblioteca SPI para la comunicación

// Definición del pin Chip Select (CS) para el ADXL345.
// Este pin se usa para activar/desactivar la comunicación con el sensor.
#define CS_PIN 10

// Direcciones de los registros del ADXL345
#define ADXL345_POWER_CTL 0x2D // Registro de control de energía
#define ADXL345_DATA_FORMAT 0x31 // Registro de formato de datos
#define ADXL345_DATAX0 0x32 // Primer byte de datos del eje X
#define ADXL345_DATAY0 0x34 // Primer byte de datos del eje Y
#define ADXL345_DATAZ0 0x36 // Primer byte de datos del eje Z

void setup() {
Serial.begin(9600); // Inicializa la comunicación serial para depuración

// Configura el pin CS como salida y lo pone en HIGH (deseleccionado)
pinMode(CS_PIN, OUTPUT);
digitalWrite(CS_PIN, HIGH);

SPI.begin(); // Inicializa el bus SPI
// Configura la velocidad del reloj SPI. ADXL345 soporta hasta 10MHz.
// SPI_CLOCK_DIV8 (2 MHz para Arduino Uno) es una buena opción para empezar.
SPI.setClockDivider(SPI_CLOCK_DIV8);
SPI.setDataMode(SPI_MODE3); // El ADXL345 usa SPI Mode 3

iniciarADXL345(); // Llama a la función para inicializar el sensor
delay(100); // Pequeña espera para que el sensor se estabilice
}

void loop() {
// Lee los valores de aceleración para cada eje
// Las lecturas son de 10 bits, por lo que se leen dos bytes por eje (X0, X1, etc.)
int x = leerEje(ADXL345_DATAX0);
int y = leerEje(ADXL345_DATAY0);
int z = leerEje(ADXL345_DATAZ0);

// Imprime los valores en el monitor serial
Serial.print(«Aceleración X: «); Serial.print(x);
Serial.print(«\tY: «); Serial.print(y);
Serial.print(«\tZ: «); Serial.println(z);
delay(100); // Pequeña pausa entre lecturas
}

// Función para inicializar el ADXL345
void iniciarADXL345() {
// Pone el pin CS en LOW para seleccionar el ADXL345
digitalWrite(CS_PIN, LOW);
// Escribe en el registro POWER_CTL (0x2D) para activar el modo de medición (0x08)
SPI.transfer(ADXL345_POWER_CTL | 0x40); // Bit de escritura (0x40)
SPI.transfer(0x08); // Pone el bit MEASURE en 1
digitalWrite(CS_PIN, HIGH); // Pone el pin CS en HIGH para deseleccionar el ADXL345
delay(5); // Pequeña espera

// Opcional: Configurar el formato de datos (rango, justificación, etc.)
// Por ejemplo, para rango +/-4g y resolución completa (10 bits)
digitalWrite(CS_PIN, LOW);
SPI.transfer(ADXL345_DATA_FORMAT | 0x40); // Bit de escritura
SPI.transfer(0x0B); // Rango +/-4g (bits D1 y D0 = 01), Full Resolution (bit D3 = 1)
digitalWrite(CS_PIN, HIGH);
}

// Función para leer un valor de aceleración de dos bytes (10 bits)
int leerEje(byte direccion) {
byte MSB, LSB; // Most Significant Byte, Least Significant Byte

digitalWrite(CS_PIN, LOW); // Selecciona el ADXL345

// Envía la dirección del registro a leer. El bit MSB (0x80) indica lectura.
// El bit D6 (0x40) indica lectura de múltiples bytes (para leer LSB y MSB consecutivamente).
SPI.transfer(direccion | 0x80 | 0x40);
LSB = SPI.transfer(0x00); // Lee el byte menos significativo
MSB = SPI.transfer(0x00); // Lee el byte más significativo
digitalWrite(CS_PIN, HIGH); // Deselecciona el ADXL345

// Combina los dos bytes para formar el valor de 10 bits.
// El ADXL345 devuelve los datos en formato de complemento a dos.
return ((int)MSB << 8) | LSB;
}
«`

Este código inicia el sensor, configura el registro `POWER_CTL` para activar la medición y el `DATA_FORMAT` para establecer el rango y la resolución, y luego lee los tres ejes (X, Y, Z). Es importante destacar que el ADXL345 devuelve valores de 10 bits, por lo que cada eje se lee en dos bytes (LSB y MSB) que luego se combinan. La función `leerEje` maneja esta lectura de dos bytes, lo cual es crucial para obtener datos correctos.

Calibración y Lectura de Datos del ADXL345

Una vez que tienes el ADXL345 conectado y el código básico funcionando, el siguiente paso es entender cómo interpretar y, si es necesario, calibrar los datos que recibes. El ADXL345 proporciona valores en «unidades de conteo» que necesitan ser convertidos a unidades de aceleración (g). La hoja de datos del ADXL345 especifica una sensibilidad de 256 LSB/g para el rango de ±2g, 128 LSB/g para ±4g, 64 LSB/g para ±8g y 32 LSB/g para ±16g, cuando está configurado en modo de resolución completa. Es importante que el registro `DATA_FORMAT` (0x31) esté configurado con el bit `FULL_RES` (D3) a 1 para obtener la máxima resolución.

Para convertir los valores leídos (por ejemplo, `x`, `y`, `z` de nuestro código de ejemplo) a ‘g’, simplemente divide el valor por la sensibilidad correspondiente. Por ejemplo, si estás en el rango de ±2g y resolución completa, dividirías `x / 256.0`. Esto te dará la aceleración en ‘g’ (donde 1g es la aceleración de la gravedad terrestre).

En mi experiencia, una calibración básica es a menudo necesaria para eliminar pequeños offsets o sesgos en las lecturas, especialmente si buscas alta precisión. Esto se puede hacer colocando el sensor en una superficie perfectamente plana y registrando las lecturas de los tres ejes. El eje Z debería leer aproximadamente +1g (o -1g, dependiendo de la orientación), y los ejes X e Y deberían leer cerca de 0g. Cualquier desviación de estos valores ideales puede considerarse un offset, que luego puedes restar de tus lecturas futuras. Para una calibración más avanzada, se pueden utilizar algoritmos como el de los seis puntos, que implican orientar el sensor en seis posiciones conocidas para determinar los offsets y las sensibilidades de cada eje.

Además, el ADXL345 ofrece características avanzadas como detección de actividad/inactividad, detección de caída libre, detección de golpes y un búfer FIFO. Estas funciones se configuran escribiendo en registros específicos y pueden ser muy útiles para reducir la carga del microcontrolador y optimizar el consumo de energía en aplicaciones específicas. Por ejemplo, puedes configurar el sensor para que genere una interrupción solo cuando detecte un movimiento significativo, en lugar de estar leyendo constantemente los datos de aceleración.

Los precios y la disponibilidad pueden variar. Como asociados de AliExpress, podemos recibir una comisión por las compras que cumplan los requisitos.

Errores Comunes y Soluciones al Trabajar con el ADXL345

Al trabajar con el acelerómetro ADXL345 controlado mediante bus SPI, es habitual encontrarse con algunos desafíos. Aquí te detallo los errores más frecuentes que hemos identificado en DunaTech y cómo puedes solucionarlos, basándonos en nuestra experiencia práctica:

1. Pin CS Mal Configurado o No Controlado Correctamente

  • Síntoma: El sensor no responde, las lecturas son siempre cero o valores aleatorios, o el programa se cuelga.
  • Causa: El pin Chip Select (CS) no está correctamente inicializado como salida, no se pone en LOW antes de cada transacción SPI, o no se vuelve a poner en HIGH después. Si hay múltiples dispositivos SPI en el bus, un CS mal gestionado puede interferir con otros sensores.
  • Solución: Asegúrate de que `pinMode(CS_PIN, OUTPUT);` esté en tu `setup()`. Antes de cada secuencia de `SPI.transfer()` para leer o escribir en el ADXL345, llama a `digitalWrite(CS_PIN, LOW);`. Una vez completada la transacción, vuelve a llamar a `digitalWrite(CS_PIN, HIGH);`. Esto aísla la comunicación con el ADXL345 del resto del bus.

2. Alimentación Incorrecta o Inestable

  • Síntoma: Lecturas erráticas, el sensor no se inicializa, o el módulo se calienta.
  • Causa: El ADXL345 es un dispositivo de 3.3V. Conectarlo directamente a 5V sin un regulador de voltaje o un conversor de nivel lógico puede dañarlo o provocar un comportamiento inestable. Una fuente de alimentación ruidosa también puede afectar la precisión.
  • Solución: Conecta siempre el VCC del ADXL345 al pin de 3.3V de tu Arduino o Raspberry Pi. Si tu placa solo ofrece 5V, utiliza un regulador de voltaje externo (como un AMS1117-3.3) o un módulo conversor de nivel lógico si las líneas de datos también son de 5V. Asegúrate de que la fuente de alimentación sea estable y capaz de proporcionar la corriente necesaria (aunque el ADXL345 consume muy poco).

3. Lectura Inestable o Datos Incorrectos (Ruido)

  • Síntoma: Los valores de aceleración fluctúan mucho incluso cuando el sensor está quieto, o los datos no tienen sentido.
  • Causa: Esto puede deberse a un cableado deficiente (cables largos, finos o sin apantallar), una velocidad SPI demasiado alta, o interferencias electromagnéticas. También puede ser un problema con el modo SPI o la polaridad del reloj.
  • Solución:
    • Cableado: Utiliza cables cortos y de buena calidad. Si es posible, usa una protoboard de buena calidad o un PCB.
    • Velocidad SPI: Reduce la velocidad del reloj SPI. Aunque el ADXL345 soporta hasta 10 MHz, en la práctica, velocidades como SPI_CLOCK_DIV8 (2 MHz en Arduino Uno) o SPI_CLOCK_DIV4 (4 MHz) suelen ser más estables.
    • Modo SPI: El ADXL345 opera en SPI Mode 3. Asegúrate de que tu código incluya `SPI.setDataMode(SPI_MODE3);`.
    • Filtro Digital: El ADXL345 tiene un filtro digital configurable (registros `BW_RATE` 0x2C). Puedes reducir el ancho de banda del filtro para suavizar las lecturas, aunque esto introducirá un pequeño retardo.

4. No se Activa el Modo de Medición

  • Síntoma: Las lecturas son siempre cero o un valor constante, independientemente del movimiento.
  • Causa: El registro `POWER_CTL` (0x2D) no se ha configurado correctamente para activar el modo de medición.
  • Solución: Asegúrate de que, en tu función de inicialización, escribes el valor `0x08` (bit MEASURE a 1) en el registro `POWER_CTL`. Por ejemplo: `SPI.transfer(ADXL345_POWER_CTL | 0x40); SPI.transfer(0x08);`.

5. Problemas con la Lectura de Múltiples Bytes

  • Síntoma: Los valores de aceleración son incorrectos o solo cambian en un rango limitado.
  • Causa: El ADXL345 devuelve los datos de cada eje en dos bytes (LSB y MSB). Si no lees ambos bytes o los combinas incorrectamente, obtendrás datos erróneos. Además, el bit D6 (0x40) de la dirección de lectura debe estar activado para lecturas de múltiples bytes.
  • Solución: En tu función `leerEje`, asegúrate de que la dirección que envías para la lectura tenga el bit 0x40 activado (ej: `direccion | 0x80 | 0x40`). Luego, lee el LSB y el MSB en ese orden y combínalos correctamente, teniendo en cuenta que el ADXL345 usa complemento a dos para los valores negativos.

Con estos consejos, la mayoría de los problemas comunes con el ADXL345 y SPI deberían ser resueltos. La clave está en revisar el cableado, la alimentación y la configuración del código paso a paso.

Preguntas Frecuentes (FAQ) sobre el ADXL345 y SPI

Aquí respondemos a algunas de las preguntas más comunes que surgen al trabajar con el acelerómetro ADXL345 controlado mediante bus SPI.

¿Por qué elegir SPI sobre I2C para el ADXL345?

Aunque I2C es más sencillo de cablear (solo dos líneas de datos más alimentación), SPI ofrece una velocidad de comunicación significativamente mayor y es menos propenso a interferencias en ambientes con mucho ruido eléctrico, gracias a sus líneas de datos separadas (MOSI y MISO). Esto lo hace ideal para aplicaciones que requieren una alta tasa de muestreo o donde la integridad de la señal es crítica. Además, SPI permite una comunicación full-duplex, lo que significa que el maestro y el esclavo pueden enviar y recibir datos simultáneamente.

¿Cuál es la velocidad máxima de SPI para el ADXL345?

Según la hoja de datos de Analog Devices, el ADXL345 soporta velocidades de reloj SPI de hasta 10 MHz. Sin embargo, en nuestras pruebas en DunaTech, hemos encontrado que frecuencias ligeramente más bajas, como 4 MHz o 5 MHz (usando SPI_CLOCK_DIV4 o SPI_CLOCK_DIV8 en Arduino), ofrecen una mayor estabilidad y fiabilidad en las lecturas, especialmente con cableado de prototipo o distancias un poco más largas. Siempre es recomendable probar diferentes velocidades para encontrar el equilibrio óptimo para tu configuración específica.

¿Se puede usar el ADXL345 en un Raspberry Pi?

Sí, el ADXL345 es completamente compatible con Raspberry Pi mediante SPI. El Raspberry Pi tiene un bus SPI integrado que se puede habilitar y configurar fácilmente. Solo necesitas conectar los pines SPI del ADXL345 a los pines GPIO correspondientes del Pi (SCK, MOSI, MISO, CE0/CE1 para CS) y utilizar bibliotecas de Python como `spidev` para interactuar con el sensor. Recuerda que el Raspberry Pi opera a 3.3V en sus GPIO, lo que simplifica la conexión de voltaje sin necesidad de conversores de nivel.

¿Cómo puedo diferenciar entre aceleración estática y dinámica con el ADXL345?

El ADXL345 mide la aceleración total, que es la suma de la aceleración estática (gravedad) y la aceleración dinámica (movimiento). Para separar estos componentes, se suelen usar filtros. Un filtro de paso bajo puede aislar la componente estática (inclinación), mientras que un filtro de paso alto puede aislar la componente dinámica (movimiento). En Arduino, esto se puede implementar mediante algoritmos de filtrado digital en el código, como un filtro complementario o un filtro Kalman, a menudo combinando datos de un giroscopio si se busca una estimación de orientación más robusta.

¿Qué rango de medición debo elegir para mi proyecto?

El ADXL345 permite seleccionar rangos de ±2g, ±4g, ±8g o ±16g. La elección depende de la magnitud de las aceleraciones que esperas medir. Un rango más pequeño (ej. ±2g) ofrece mayor resolución para movimientos sutiles, mientras que un rango más grande (ej. ±16g) es adecuado para detectar impactos o movimientos rápidos. Si no estás seguro, empezar con ±4g es un buen punto intermedio. Puedes configurar este rango en el registro `DATA_FORMAT` (0x31) del sensor.

Conclusión

El acelerómetro ADXL345 controlado mediante bus SPI es una herramienta potente y versátil para cualquier proyecto que requiera mediciones de aceleración precisas. Su facilidad de uso con plataformas como Arduino o Raspberry Pi, combinada con su robustez y bajo consumo, lo convierten en una opción excelente tanto para aficionados como para desarrolladores profesionales. Al prestar atención al cableado, la alimentación y la correcta configuración del código SPI, podrás integrar este sensor de manera efectiva y aprovechar al máximo sus capacidades. Esperamos que esta guía detallada te haya proporcionado los conocimientos necesarios para implementar el ADXL345 en tus propias creaciones. ¡A seguir innovando con DunaTech!

— El equipo de DunaTech

Ofertas AliExpress