¿Qué es el ADXL345 y por qué coño usar SPI?
Vale. Hablemos del ADXL345. Es uno de esos acelerómetros de 3 ejes que llevan una década siendo el caballo de batalla de la electrónica DIY. Lo encuentras en todo: desde drones de AliExpress hasta proyectos de nivelación de impresoras 3D caseras. Es pequeño, barato (unos 2-3 USD en módulo) y consume una miseria.
Pero aquí viene el lío. Este chip tiene dos interfaces de comunicación: I2C y SPI. Y sí, el 90% de los tutoriales te enseñan I2C porque es más fácil de cablear. Dos cables, biblioteca simple, listo. ¿El problema? I2C es lento. Muy lento. Si quieres leer datos a más de 200 Hz o tienes varios sensores en el mismo bus, I2C se convierte en un cuello de botella.
SPI es la solución. Es full-duplex, mucho más rápido (puedes pasar de 5 MHz sin problemas) y te da control total sobre el chip. Eso sí, necesitas un cable más (el CS, Chip Select) y entender cómo funciona el bus. Pero si estás aquí, asumo que no te da miedo soldar ni leer datasheets.
En DunaTech siempre estamos hurgando en el desierto de AliExpress buscando chollos, y este sensor es uno de los mejores ejemplos de algo que no necesitas caro para que funcione de puta madre. Un módulo chino de 1.5 USD bien configurado te da los mismos resultados que uno «original» de 20 USD. Ojo, siempre que sepas cablearlo bien.
Conexión Física: El Mapa de Pines
Primero, localiza tu módulo ADXL345. Normalmente viene en una plaquita azul o verde con 7 pines. Los que nos interesan para SPI son:
- VCC (3.3V) — No le metas 5V o lo fríes. El chip es de 3.3V. Si tu Arduino es de 5V, necesitas un divisor de tensión o un level shifter en las líneas de datos. Lo barato sale caro.
- GND — A tierra, obvio.
- CS (Chip Select) — Este pin selecciona el dispositivo en el bus SPI. Lo conectas a cualquier pin digital de tu Arduino (ej. pin 10).
- SDI/SDA (MOSI) — Master Out Slave In. Datos que envía el Arduino al sensor.
- SDO/ALT (MISO) — Master In Slave Out. Datos que envía el sensor al Arduino.
- SCLK (SCK) — El reloj. Lo genera el Arduino.
La conexión estándar para Arduino Uno/Nano:
| ADXL345 | Arduino |
|---|---|
| VCC | 3.3V |
| GND | GND |
| CS | Pin 10 (o cualquier digital) |
| SDI (MOSI) | Pin 11 |
| SDO (MISO) | Pin 12 |
| SCLK | Pin 13 |
Ojo con esto: Si usas un ESP32 o un ESP8266, los pines SPI suelen ser diferentes. Por ejemplo, en un ESP32 el VSPI usa pines MOSI=23, MISO=19, SCK=18, y puedes elegir cualquier GPIO para CS. No copies y pegues el código sin verificar el pinout de tu placa.
¿Y el pin INT1 o INT2?
El ADXL345 tiene dos pines de interrupción. No son necesarios para la lectura básica, pero si quieres detectar golpes, caídas libres o movimientos sin estar preguntando constantemente al sensor (polling), los necesitas. Conecta INT1 a un pin digital (ej. pin 2) y configúralo en el código. Esto te ahorra CPU y es la forma correcta de hacer las cosas en proyectos de batería.
Código Base: Leyendo Datos por SPI
Aquí no vamos a usar la biblioteca Adafruit_ADXL345 que usa I2C por defecto. Vamos a usar la librería SPI de Arduino y a escribir nosotros mismos las funciones de lectura. ¿Por qué? Porque así entiendes lo que pasa. Y porque a veces las librerías pre-hechas fallan en módulos chinos baratos.
Primero, instala la biblioteca «ADXL345» de Adafruit desde el Gestor de Librerías. Sí, la misma que usa I2C, pero tiene soporte SPI. O puedes usar la librería «SparkFun ADXL345». Ambas sirven.
Aquí te dejo el código base que uso en mi laboratorio. Lo he probado con 5 módulos diferentes de AliExpress y funciona:
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include <ADXL345.h>
/* Pines SPI para Arduino Uno */
#define ADXL345_CS 10
ADXL345 adxl = ADXL345(ADXL345_CS);
void setup(void) {
Serial.begin(115200);
Serial.println("Inicializando ADXL345 por SPI...");
if (!adxl.begin()) {
Serial.println("¡ERROR! No se encuentra el ADXL345.");
Serial.println("Revisa las conexiones o el pin CS.");
while (1);
}
/* Rango de medición: ±16g (máxima sensibilidad para golpes) */
adxl.setRange(ADXL345_RANGE_16_G);
Serial.println("Sensor listo.");
}
void loop(void) {
sensors_event_t event;
adxl.getEvent(&event);
Serial.print("X: "); Serial.print(event.acceleration.x);
Serial.print(" Y: "); Serial.print(event.acceleration.y);
Serial.print(" Z: "); Serial.print(event.acceleration.z);
Serial.println(" m/s²");
delay(100);
}
¿Qué hace esto? Inicializa el sensor, configura el rango a ±16g (ideal para detectar impactos, no para medir inclinación suave) y luego imprime los valores de aceleración en los tres ejes cada 100 ms.
Si no ves datos: Revisa el pin CS. El error más tonto y más común es tener el CS mal conectado o usar un pin que no declaraste en el código. A mí me pasó. Una hora perdida por un cable suelto.
Leyendo datos en bruto (raw)
Si quieres los valores crudos de 10 bits (antes de convertirlos a m/s²), usa adxl.getRawXYZ(&x, &y, &z);. Esto te da números entre -512 y 511 (dependiendo del rango). Útil si quieres hacer tu propia calibración o si el sensor está montado en una impresora 3D y necesitas detectar vibraciones finas.
Calibración: El Secreto de los Datos Precisos
Los módulos de AliExpress vienen sin calibrar de fábrica. El offset en el eje Z puede variar hasta 0.5g. Eso es una mierda si quieres medir inclinaciones con precisión.
La calibración casera que hago yo:
- Coloca el sensor en una superficie perfectamente plana. Usa un nivel de burbuja. No lo hagas sobre la mesa coja de tu taller.
- Toma 100 lecturas en reposo. Calcula el promedio para cada eje. En teoría, X e Y deberían ser 0, y Z debería ser +1g (9.8 m/s²).
- Guarda esos offsets. En el setup, después de iniciar el sensor, aplica los offsets con
adxl.setOffset(x_offset, y_offset, z_offset);. - Gira el sensor 180 grados en cada eje y repite. Si el valor absoluto no es simétrico, tienes un problema de linealidad. En ese caso, el sensor está defectuoso o la PCB está mal diseñada.
He visto módulos donde el offset en Z era de -0.8g. Una burrada. Si no calibras, cualquier proyecto de medición de ángulos será un despropósito.
Troubleshooting & Errores Comunes
Aquí va lo que realmente importa. He visto a decenas de personas en foros (y a mí mismo) perder horas con estos errores. Vamos a por ellos.
Error 1: «No se encuentra el sensor» (Device not found)
Causa más probable: El pin CS no está configurado correctamente o hay un conflicto con otros dispositivos SPI. Si tienes una SD card o un display conectado al mismo bus, asegúrate de que solo un CS esté en LOW a la vez. O usa pines CS diferentes.
Solución: Desconecta todo lo demás del bus SPI. Deja solo el ADXL345. Si funciona, el problema es de colisión de buses. Si no, revisa las soldaduras del módulo. Los módulos baratos a veces vienen con cold joints.
Error 2: Lecturas saltarinas o ruidosas
Causa: Cables largos sin blindaje, o usar una protoboard con mala conexión. El SPI a 5 MHz es sensible a la capacitancia parásita.
Solución: Usa cables de menos de 20 cm. Si necesitas más longitud, usa cable apantallado y reduce la velocidad del SPI en el código: SPI.setClockDivider(SPI_CLOCK_DIV8); (baja a 2 MHz). También prueba a soldar directamente los cables al módulo en lugar de usar pines hembra.
Error 3: El valor de Z nunca es 1g en reposo
Causa: El sensor está montado en un ángulo, o el chip está defectuoso. También puede ser que hayas seleccionado el rango equivocado (si pones ±2g, la resolución es mayor pero el valor máximo es menor).
Solución: Asegúrate de que el módulo esté físico y eléctricamente plano. Si el PCB del módulo está torcido, el sensor lo está también. He tenido módulos donde el chip venía soldado torcido. Ahí no hay calibración que valga.
Error 4: El código compila pero no imprime nada
Causa: El Serial Monitor está configurado a 9600 baudios pero el código usa 115200. O viceversa.
Solución: Ajusta el baud rate del monitor al mismo que pusiste en Serial.begin(). Esto es de primero de Arduino, pero te juro que lo veo cada semana en los grupos de WhatsApp.
Error 5: El sensor se calienta
Causa: Le estás metiendo 5V en VCC. El ADXL345 es de 3.3V y se calienta si le metes más. No explota, pero se descalibra y acorta su vida útil.
Solución: Usa un regulador de 3.3V o el pin de 3.3V de tu Arduino. Si tu placa no tiene salida de 3.3V (como algunos clones chinos), necesitas un módulo regulador externo.
FAQ
¿Puedo usar I2C y SPI a la vez en el mismo ADXL345?
No. El pin SDO/ALT determina el modo. Si lo dejas flotando o lo conectas a GND, el sensor usa I2C. Si lo conectas a VCC (o lo configuras como MISO), usa SPI. No puedes tener ambos activos simultáneamente. Si necesitas ambos buses, compra dos sensores o usa un multiplexor.
¿Cuál es la frecuencia máxima de lectura por SPI?
El datasheet oficial dice que soporta hasta 5 MHz en SPI. En la práctica, he llegado a 10 MHz con un ESP32 sin problemas, pero a esa velocidad los cables empiezan a importar mucho. Para la mayoría de proyectos, 2 MHz es más que suficiente y te ahorras dolores de cabeza.
¿Vale la pena comprar el módulo «original» de Analog Devices vs el clon chino?
Sinceramente, no. El chip en sí es el mismo (o una copia funcional). Lo que cambia es la calidad del PCB y los condensadores de desacoplo. En los módulos de 1 USD, a veces el condensador de 0.1 µF que va al lado del pin VCC es de peor calidad, lo que introduce ruido. Pero con una calibración decente y cables cortos, la diferencia es inapreciable para el 99% de los proyectos. Si eres un manitas, incluso puedes cambiar ese condensador por uno de calidad y tienes un sensor de 20 USD por 2 USD. Eso es un chollo.
Conclusión
El ADXL345 por SPI no es más complicado que por I2C, solo requiere entender un cable más y cómo funciona el bus. La recompensa es una velocidad de lectura muy superior, menos latencia y la posibilidad de conectar múltiples sensores sin conflictos de direcciones.
Si estás construyendo un datalogger de vibraciones para tu impresora 3D, un control de gestos para un robot o simplemente quieres aprender a comunicarte con sensores como un ingeniero de verdad, el camino SPI es el correcto. No te dejes engañar por la facilidad de I2C.
Y recuerda: en el desierto de AliExpress, no todo lo que brilla es oro. Pero un ADXL345 bien cableado y calibrado te da datos de nivel profesional por menos de lo que cuesta un café con leche en Madrid. Así que deja de leer y ponte a soldar.
Ver precio actual y cupones en AliExpress