usar-arduino-y-el-imu-9-ejes-l3gd20-lsm303d

Cómo usar Arduino y el IMU 9 ejes L3GD20 + LSM303D

¿Qué es un IMU 9 ejes L3GD20 + LSM303D?

El módulo L3GD20 + LSM303D es un IMU de 9 ejes que incorpora funciones de acelerómetro, giroscopio y brújula magnética, podemos usar con un procesador como Arduino para determinar la orientación del sensor.

Este módulo, como su nombre indica, está formado por un integrado L3GD20 como giroscopio, LSM303DLHC como acelerómetro y brújula magnética. Ambos sensores son fabricados por STMicroelectronics.

La combinación de estos sensores en un mismo módulo un IMU de 9 ejes de buena calidad y bajo precio, que es un buen reemplazo a otras alternativas como los populares MPU6050 y MPU9250 de InvenSense.

La rango y sensibilidad de los tres sensores es ajustable. Para el giroscopio L3GD20 es ±250, ±500, o ±2000 grados por segundo. Para el LSM303 es de ±2g, ±4g, ±6g, ±8g, ±16g para el acelerómetro, y ±2, ±4, ±8, ±12 gauss.

La comunicación con el módulo se realiza a través de bus I2C, por lo que es muy sencillo realizar su lectura desde un procesador como Arduino.

Los integrados operan a 3.3V, pero el módulo incorpora un regulador por lo que la tensión de alimentación es de 2.5-5.5V. Los pines de I2C tienen adaptadores de nivel, por lo que es seguro conectarlo con un procesador de 3.3V o 5V.

Precio

Podemos encontrar un IMU de 9 ejes L3GD20 + LSM303D por unos 3.70€, lo cual lo convierte en uno de los mejores IMUs en cuanto a relación calidad / precio.

arduino-l3gd20-lsm303d-componente

No confundir con otros sensores que sólo incorporan el L3GD20, y por tanto sólo tienen 3 ejes de giroscopio. Cuestan unos 2.40€ y no son interesantes porque

También existen versiones de 10 DOF, que añaden un BMP180 como barómetro para estimar la altitud, con un coste de unos 4.80€. Tampoco los recomiendo especialmente porque el BMP180 está algo obsoleto, y por la diferencia de precio podríamos comprarlo suelto.

Esquema de 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-l3gd20-lsm303d-esquema

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

arduino-l3gd20-lsm303d-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

Para realizar la lectura del L3GD20 + LSM303D usaremos las librerías de Adafruit https://github.com/adafruit/Adafruit_L3GD20_U, https://github.com/adafruit/Adafruit_LSM303DLH_Mag y https://github.com/adafruit/Adafruit_9DOF.

La librería Adafruit_9DOF incorpora varios ejemplos de uso que conviene revisar, que incluyen un algoritmo de fusión de la medición de los tres sensores para conseguir la orientación del módulo. Los siguientes ejemplos son modificaciones a partir de los disponibles en la librería.

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_LSM303_U.h>
#include <Adafruit_9DOF.h>
#include <Adafruit_L3GD20_U.h>

Adafruit_9DOF                 dof   = Adafruit_9DOF();
Adafruit_LSM303_Accel_Unified accel = Adafruit_LSM303_Accel_Unified(30301);
Adafruit_LSM303_Mag_Unified   mag   = Adafruit_LSM303_Mag_Unified(30302);

void initSensors()
{
  if(!accel.begin())
  {
    Serial.println(F("Ooops, no LSM303 detected ... Check your wiring!"));
    while(1);
  }
  if(!mag.begin())
  {
    Serial.println("Ooops, no LSM303 detected ... Check your wiring!");
    while(1);
  }
}

void setup(void)
{
  Serial.begin(115200);
  Serial.println(F("Adafruit 9 DOF Pitch/Roll/Heading Example")); 
  Serial.println("");
  
  initSensors();  // iniciar sensor
}

void loop(void)
{
  sensors_event_t accel_event;
  sensors_event_t mag_event;
  sensors_vec_t   orientation;

  // leer el estado de los sensores
  accel.getEvent(&accel_event);
  mag.getEvent(&mag_event);

  // usar el algoritmo de fusion de la libreria para combinar las mediciones
  if (dof.fusionGetOrientation(&accel_event, &mag_event, &orientation))
  {
    /* 'orientation' should have valid .roll and .pitch fields */
    Serial.print(F("Orientation: "));
    Serial.print(orientation.roll);
    Serial.print(F(" "));
    Serial.print(orientation.pitch);
    Serial.print(F(" "));
    Serial.print(orientation.heading);
    Serial.println(F(""));
  }
  
  delay(100);
}

Ejemplo con RTIMULIB-Arduino

Otra opción para la lectura del sensor es emplear la librería RTIMULIB-Arduino, que permite crear un sistema AHRS ((Attitude Heading Reference Systems) y funciona con una gran variedad de sensores. Vimos como emplear esta librería en esta entrada.

Descarga el código

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