> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kode.diy/llms.txt
> Use this file to discover all available pages before exploring further.

# IMU

> Aprende para qué sirve una IMU y cómo usarla en tu Kode Dot

# Características

En el interior de tu Kode Dot tienes integrado un **giroscópio de 3 ejes, un acelerómetro de 3 ejes y un magnetómetro de 3 ejes.** Así, puedes conocer la posición relativa a si mismo y su posición absoluta respecto a la Tierra.

El giroscópio y el acelerómetro están en un **mismo integrado** y tienen las siguientes características:

| Característica                        | Descripción                                                                                                              |
| ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| Acelerómetro + giroscopio “always-on” | Consumo total de **0,55 mA** en modo de alto rendimiento para operación continua.                                        |
| Rangos de medida                      | Acelerómetro **±2/4/8/16 g**  •  Giroscopio **±125/250/500/1000/2000 dps**.                                              |
| FIFO inteligente                      | Búfer de datos de hasta **9 KB** con compresión y batching dinámico.                                                     |
| Motor de IA embebido                  | **16 máquinas de estados (FSM)** programables + **núcleo MLC** (hasta 8 flujos / 256 nodos).                             |
| Reconocimiento de eventos             | Podómetro, contador de pasos, significant motion, inclinación, free-fall, wake-up, orientación 6D/4D, clic y doble clic. |
| Sensor de temperatura                 | Termómetro interno para monitorizar la temperatura del chip.                                                             |

El magnetómetro tiene las siguientes características:

| Característica       | Detalle                                                   |
| -------------------- | --------------------------------------------------------- |
| Rango dinámico       | **±50 gauss** (tres ejes)                                 |
| Resolución de salida | **16 bits**                                               |
| Consumo típico       | 200 µA @ 20 Hz (modo alta resolución) / 50 µA (low-power) |

## Esquema de conexión

### IMU de 6 ejes

La IMU está conectado al ESP32-S3 a través del bus I2C usando estas conexiones:

| IMU  | ESP32-S3 |
| ---- | -------- |
| SDA  | GPIO48   |
| SCL  | GPIO47   |
| INT1 | EXP13    |
| INT2 | EXP12    |

<Tip>La IMU tiene la dirección 0x6A en el bus I2C.</Tip>
<Note>Los pines de interrupción están conectados al [expansor de pines](/es/kode-dot/io-expander).</Note>

### Magnetómetro de 3 ejes

El magnetómetro está conectado de la misma manera al bus I2C usando estas conexiones:

| Magnetómetro | ESP32-S3 |
| ------------ | -------- |
| SDA          | GPIO48   |
| SCL          | GPIO47   |
| INT1         | EXP0     |

<Tip>El magnetómetro tiene la dirección 0x1E en el bus I2C.</Tip>
<Note>El pin de interrupción está conectado al [expansor de pines](/es/kode-dot/io-expander).</Note>

## Librerías recomendadas

### Arduino

* [Adafruit LSM6DS](https://github.com/adafruit/Adafruit_LSM6DS)
* [Adafruit LIS2MDL](https://github.com/adafruit/Adafruit_LIS2MDL)

### ESP-IDF

* [kode\_lsm6dsox](https://components.espressif.com/components/kodediy/kode_lsm6dsox)
* [kode\_lis2mdl](TBD)

## Ejemplo de código

### IMU de 6 ejes

Este código muestra el rango de medida de los sensores y la frecuencia de muestreo. También muestra la temperatura, la aceleración y la velocidad angular.

```cpp imu_test.ino lines icon="microchip" theme={null}
/**
 * Inicializa y lee una IMU LSM6DSOX por I2C en ESP32-S3, mostrando aceleración, giro y temperatura.
 * Imprime rangos y data rates configurados y luego publica lecturas cada 1 segundo por el puerto serie.
 * Usa pines I2C personalizados (GPIO48/47) y la librería Adafruit_LSM6DSOX.
*/
/* ───────── KODE | docs.kode.diy ───────── */

#include <Adafruit_LSM6DSOX.h>  /* Librería para el sensor LSM6DSOX */
#include <Wire.h>               /* Librería de comunicación I2C */

/* Pines I2C configurables */
#define I2C_SDA 48            /* Pin SDA */
#define I2C_SCL 47            /* Pin SCL */

/* Instancia del sensor IMU y del bus I2C */
Adafruit_LSM6DSOX imu;

void setup(void) {
  /* Inicializa el puerto serie para depuración */
  Serial.begin(115200);
  while (!Serial);

  /* Inicializa el bus I2C con los pines especificados */
  Wire.begin(I2C_SDA, I2C_SCL);

  Serial.println("LSM6DSOX test");

  /* Intenta inicializar el sensor en la dirección I2C por defecto (0x6A).
     Nota: algunas placas usan 0x6B según el estado del pin SA0. */
  if (!imu.begin_I2C()) {
    Serial.println("Failed to find LSM6DSOX chip");
    while (1) {
      delay(10);  /* Bucle infinito si falla la inicialización */
    }
  }
  Serial.println("LSM6DSOX Found!");

  /* Muestra el rango configurado del acelerómetro */
  Serial.print("Accelerometer range set to: ");
  switch (imu.getAccelRange()) {
    case LSM6DS_ACCEL_RANGE_2_G:
      Serial.println("+-2G"); break;
    case LSM6DS_ACCEL_RANGE_4_G:
      Serial.println("+-4G"); break;
    case LSM6DS_ACCEL_RANGE_8_G:
      Serial.println("+-8G"); break;
    case LSM6DS_ACCEL_RANGE_16_G:
      Serial.println("+-16G"); break;
  }

  /* Muestra el rango configurado del giroscopio */
  Serial.print("Gyro range set to: ");
  switch (imu.getGyroRange()) {
    case LSM6DS_GYRO_RANGE_125_DPS:
      Serial.println("125 degrees/s"); break;
    case LSM6DS_GYRO_RANGE_250_DPS:
      Serial.println("250 degrees/s"); break;
    case LSM6DS_GYRO_RANGE_500_DPS:
      Serial.println("500 degrees/s"); break;
    case LSM6DS_GYRO_RANGE_1000_DPS:
      Serial.println("1000 degrees/s"); break;
    case LSM6DS_GYRO_RANGE_2000_DPS:
      Serial.println("2000 degrees/s"); break;
    case ISM330DHCX_GYRO_RANGE_4000_DPS:
      /* Rango no soportado por el DSOX */
      break;
  }

  /* Muestra el data rate configurado del acelerómetro */
  Serial.print("Accelerometer data rate set to: ");
  switch (imu.getAccelDataRate()) {
    case LSM6DS_RATE_SHUTDOWN:    Serial.println("0 Hz"); break;
    case LSM6DS_RATE_12_5_HZ:     Serial.println("12.5 Hz"); break;
    case LSM6DS_RATE_26_HZ:       Serial.println("26 Hz"); break;
    case LSM6DS_RATE_52_HZ:       Serial.println("52 Hz"); break;
    case LSM6DS_RATE_104_HZ:      Serial.println("104 Hz"); break;
    case LSM6DS_RATE_208_HZ:      Serial.println("208 Hz"); break;
    case LSM6DS_RATE_416_HZ:      Serial.println("416 Hz"); break;
    case LSM6DS_RATE_833_HZ:      Serial.println("833 Hz"); break;
    case LSM6DS_RATE_1_66K_HZ:    Serial.println("1.66 KHz"); break;
    case LSM6DS_RATE_3_33K_HZ:    Serial.println("3.33 KHz"); break;
    case LSM6DS_RATE_6_66K_HZ:    Serial.println("6.66 KHz"); break;
  }

  /* Muestra el data rate configurado del giroscopio */
  Serial.print("Gyro data rate set to: ");
  switch (imu.getGyroDataRate()) {
    case LSM6DS_RATE_SHUTDOWN:    Serial.println("0 Hz"); break;
    case LSM6DS_RATE_12_5_HZ:     Serial.println("12.5 Hz"); break;
    case LSM6DS_RATE_26_HZ:       Serial.println("26 Hz"); break;
    case LSM6DS_RATE_52_HZ:       Serial.println("52 Hz"); break;
    case LSM6DS_RATE_104_HZ:      Serial.println("104 Hz"); break;
    case LSM6DS_RATE_208_HZ:      Serial.println("208 Hz"); break;
    case LSM6DS_RATE_416_HZ:      Serial.println("416 Hz"); break;
    case LSM6DS_RATE_833_HZ:      Serial.println("833 Hz"); break;
    case LSM6DS_RATE_1_66K_HZ:    Serial.println("1.66 KHz"); break;
    case LSM6DS_RATE_3_33K_HZ:    Serial.println("3.33 KHz"); break;
    case LSM6DS_RATE_6_66K_HZ:    Serial.println("6.66 KHz"); break;
  }
}

void loop() {
  /* Variables para los eventos del sensor */
  sensors_event_t accel;
  sensors_event_t gyro;
  sensors_event_t temp;

  /* Obtiene eventos de acelerómetro, giroscopio y temperatura */
  imu.getEvent(&accel, &gyro, &temp);

  /* Imprime temperatura en grados Celsius */
  Serial.print("\t\tTemperature: ");
  Serial.print(temp.temperature);
  Serial.println(" deg C");

  /* Imprime aceleración en m/s^2 por eje */
  Serial.print("\t\tAccel X: ");
  Serial.print(accel.acceleration.x);
  Serial.print(" \tY: ");
  Serial.print(accel.acceleration.y);
  Serial.print(" \tZ: ");
  Serial.print(accel.acceleration.z);
  Serial.println(" m/s^2");

  /* Imprime rotación del giroscopio en rad/s por eje */
  Serial.print("\t\tGyro X: ");
  Serial.print(gyro.gyro.x);
  Serial.print(" \tY: ");
  Serial.print(gyro.gyro.y);
  Serial.print(" \tZ: ");
  Serial.print(gyro.gyro.z);
  Serial.println(" radians/s");

  Serial.println();
  delay(1000);  /* Espera entre lecturas */
}
```

### Magnetómetro de 3 ejes

Este código muestra el vector magnético en micro-Teslas (uT).

```cpp mag_test.ino lines icon="microchip" theme={null}
/**
 * Inicializa y lee el magnetómetro LIS2MDL por I2C en un ESP32-S3.
 * Imprime detalles del sensor al inicio y luego muestra el vector magnético (uT) cada segundo.
 * Usa pines I2C personalizados (GPIO48/47) y la librería Adafruit_LIS2MDL.
*/
/* ───────── KODE | docs.kode.diy ───────── */

#include <Wire.h>
#include <Adafruit_LIS2MDL.h>

/* Pines I2C configurables */
#define I2C_SDA 48            /* Pin SDA */
#define I2C_SCL 47            /* Pin SCL */

/* Instancia del magnetómetro con ID único */
Adafruit_LIS2MDL mag = Adafruit_LIS2MDL(12345);

void setup(void) {
  /* Inicializa el puerto serie para depuración */
  Serial.begin(115200);
  while (!Serial) {
    /* espera al puerto serie */
  }

  /* Inicializa el bus I2C con los pines seleccionados */
  Wire.begin(I2C_SDA, I2C_SCL);

  Serial.println("Magnetometer Test");
  Serial.println();

  /* Intenta inicializar el sensor LIS2MDL en la dirección I2C 0x1E */
  if (!mag.begin()) {
    /* Sensor no detectado: muestra error y se detiene */
    Serial.println("Ooops, no LIS2MDL detected ... Check your wiring!");
    while (1) {
      delay(10);  /* Bucle infinito si falla */
    }
  }

  /* Muestra información básica del sensor */
  mag.printSensorDetails();
}

void loop(void) {
  /* Obtiene un nuevo evento del sensor */
  sensors_event_t event;
  mag.getEvent(&event);

  /* Muestra los resultados (valores magnéticos en micro-Teslas, uT) */
  Serial.print("X: ");
  Serial.print(event.magnetic.x);
  Serial.print("  ");
  Serial.print("Y: ");
  Serial.print(event.magnetic.y);
  Serial.print("  ");
  Serial.print("Z: ");
  Serial.print(event.magnetic.z);
  Serial.print("  ");
  Serial.println("uT");

  /* Espera entre lecturas */
  delay(1000);
}
```

## Descarga de ejemplos

Puedes probar los códigos de ejemplo mediante el IDE de Arduino o el IDE de ESP-IDF o descargar los códigos en nuestro drive:

[Ejemplos de la IMU y el magnetómetro](https://drive.google.com/drive/folders/1eAutUqjqenHA7lNoFHxKpBUXdwUa-6ZS)
