Pages Menu
TwitterFacebook



BANNER2_ALT

Posted by on Abr 25, 2014 in Sensores digitales | 14 comments

Acelerómetro y Giroscopio MPU6050

Acelerómetro y Giroscopio MPU6050

 

 

 

 

 

      Acelerómetro y Giroscopio MPU6050 

 

Acelerómetro y Giroscopio

Acelerómetro y Giroscopio

Acelerómetro y Giroscopio

DESCRIPCIÓN

 El propósito de este tutorial consiste de dos partes, la primera será mostrar lo que es un acelerómetro y giroscopio y la lectura de valores del MPU-6050 utilizando un Arduino Uno se mostraran en el monitor serial del Arduino IDE. La segunda parte será de la implementación de IMU.

 

MATERIALES

–       Acelerómetro Giroscopio MPU-6050 6DOF

–       1  Arduino Uno

–       1 Cables USB serial

 

DIAGRAMA y CONEXIÓN

Acelerómetro y Giroscopio

Acelerómetro y Giroscopio

 

PINES UTILIZADOS

Acelerómetro y Giroscopio

Acelerómetro y Giroscopio

 

 

INTRODUCCIÓN

 

Acelerómetro Giroscopio MPU-6050 6DOF

 

DESCRIPCIÓN

 

Sensor Giroscópico

 

Un giroscopio es un dispositivo que funciona para miden velocidades angulares basándose en el mantenimiento del impulso de rotación. Si intentamos hacer girar un objeto que está girando sobre un eje que no es el eje sobre el que está rotando, el objeto ejercerá un momento contrario al movimiento con el fin de preservar el impulso de rotación total.

El giroscopio muestra el cambio de rango en rotación en sus ejes X, Y y Z.

 

Acelerómetro

 

Mide la aceleración, inclinación o vibración y transforma la magnitud física de aceleración en otra magnitud eléctrica que será la que emplearemos en los equipos de adquisición estándar. Los rangos de medida van desde las décimas de g, hasta los miles de g.

 

MPU-6050

 

El circuito integrado MPU-6050 contiene un acelerómetro y giroscopio MEMS en un solo empaque. Cuenta con una resolución de 16-bits, lo cual significa que divide el rango dinámico en 65536 fracciones,  estos aplican para cada eje X, Y y Z al igual que en la velocidad angular. El sensor es ideal para diseñar control de robótica, medición de vibración, sistemas de medición inercial (IMU), detector de caídas, sensor de distancia y velocidad, y muchas cosas más. El MPU-6050 contiene un giroscópico, un acelerómetro, además de un sensor de temperatura, mediante I2C  regresa unos valores conocidos como raw o “crudos” según el registro seleccionado.

A continuación se mostraron los rangos de escala y el valor máximo raw.

Rango De Escala Completa Giroscopio Sensibilidad del Giroscopio Rango De Escala Completa Acelerómetro Sensibilidad del Acelerómetro
±250 131 ±2 16384
±500 65.5 ±4 8192
±1000 32.8 ±8 4096
±2000 16.4 ±16 2048

 

ESPECIFICACIONES

  • Salida digital de 6 ejes.
  • Giroscopio con sensibilidad de ±250, ±500, ±1000, y ±2000dps
  • Acelerómetro con sensibilidad de ±2g, ±4g, ±8g y ±16g
  • Algoritmos embebidos para calibración
  • Sensor de temperatura digital
  • Entrada digital de video FSYNC
  • Interrupciones programables
  • Voltaje de alimentación: 2.37 a 3.46V
  • Voltaje lógico: 1.8V±5% o VDD
  • 10000g tolerancia de aceleración máxima

 

CODIGO

 

Descarga los codigos:

https://github.com/HeTpro/MPU6050_arduino_processing/tree/master

 

#include <Wire.h> // I2C library, gyroscope

#define MPU6050_AUX_VDDIO          0x01   // R/W
#define MPU6050_SMPLRT_DIV         0x19   // R/W
#define MPU6050_CONFIG             0x1A   // R/W
#define MPU6050_GYRO_CONFIG        0x1B   // R/W
#define MPU6050_ACCEL_CONFIG       0x1C   // R/W
#define MPU6050_FF_THR             0x1D   // R/W
#define MPU6050_FF_DUR             0x1E   // R/W
#define MPU6050_MOT_THR            0x1F   // R/W
#define MPU6050_MOT_DUR            0x20   // R/W
#define MPU6050_ZRMOT_THR          0x21   // R/W
#define MPU6050_ZRMOT_DUR          0x22   // R/W
#define MPU6050_FIFO_EN            0x23   // R/W
#define MPU6050_I2C_MST_CTRL       0x24   // R/W
#define MPU6050_I2C_SLV0_ADDR      0x25   // R/W
#define MPU6050_I2C_SLV0_REG       0x26   // R/W
#define MPU6050_I2C_SLV0_CTRL      0x27   // R/W
#define MPU6050_I2C_SLV1_ADDR      0x28   // R/W
#define MPU6050_I2C_SLV1_REG       0x29   // R/W
#define MPU6050_I2C_SLV1_CTRL      0x2A   // R/W
#define MPU6050_I2C_SLV2_ADDR      0x2B   // R/W
#define MPU6050_I2C_SLV2_REG       0x2C   // R/W
#define MPU6050_I2C_SLV2_CTRL      0x2D   // R/W
#define MPU6050_I2C_SLV3_ADDR      0x2E   // R/W
#define MPU6050_I2C_SLV3_REG       0x2F   // R/W
#define MPU6050_I2C_SLV3_CTRL      0x30   // R/W
#define MPU6050_I2C_SLV4_ADDR      0x31   // R/W
#define MPU6050_I2C_SLV4_REG       0x32   // R/W
#define MPU6050_I2C_SLV4_DO        0x33   // R/W
#define MPU6050_I2C_SLV4_CTRL      0x34   // R/W
#define MPU6050_I2C_SLV4_DI        0x35   // R
#define MPU6050_I2C_MST_STATUS     0x36   // R
#define MPU6050_INT_PIN_CFG        0x37   // R/W
#define MPU6050_INT_ENABLE         0x38   // R/W
#define MPU6050_INT_STATUS         0x3A   // R
#define MPU6050_ACCEL_XOUT_H       0x3B   // R
#define MPU6050_ACCEL_XOUT_L       0x3C   // R
#define MPU6050_ACCEL_YOUT_H       0x3D   // R
#define MPU6050_ACCEL_YOUT_L       0x3E   // R
#define MPU6050_ACCEL_ZOUT_H       0x3F   // R
#define MPU6050_ACCEL_ZOUT_L       0x40   // R
#define MPU6050_TEMP_OUT_H         0x41   // R
#define MPU6050_TEMP_OUT_L         0x42   // R
#define MPU6050_GYRO_XOUT_H        0x43   // R
#define MPU6050_GYRO_XOUT_L        0x44   // R
#define MPU6050_GYRO_YOUT_H        0x45   // R
#define MPU6050_GYRO_YOUT_L        0x46   // R
#define MPU6050_GYRO_ZOUT_H        0x47   // R
#define MPU6050_GYRO_ZOUT_L        0x48   // R
#define MPU6050_EXT_SENS_DATA_00   0x49   // R
#define MPU6050_EXT_SENS_DATA_01   0x4A   // R
#define MPU6050_EXT_SENS_DATA_02   0x4B   // R
#define MPU6050_EXT_SENS_DATA_03   0x4C   // R
#define MPU6050_EXT_SENS_DATA_04   0x4D   // R
#define MPU6050_EXT_SENS_DATA_05   0x4E   // R
#define MPU6050_EXT_SENS_DATA_06   0x4F   // R
#define MPU6050_EXT_SENS_DATA_07   0x50   // R
#define MPU6050_EXT_SENS_DATA_08   0x51   // R
#define MPU6050_EXT_SENS_DATA_09   0x52   // R
#define MPU6050_EXT_SENS_DATA_10   0x53   // R
#define MPU6050_EXT_SENS_DATA_11   0x54   // R
#define MPU6050_EXT_SENS_DATA_12   0x55   // R
#define MPU6050_EXT_SENS_DATA_13   0x56   // R
#define MPU6050_EXT_SENS_DATA_14   0x57   // R
#define MPU6050_EXT_SENS_DATA_15   0x58   // R
#define MPU6050_EXT_SENS_DATA_16   0x59   // R
#define MPU6050_EXT_SENS_DATA_17   0x5A   // R
#define MPU6050_EXT_SENS_DATA_18   0x5B   // R
#define MPU6050_EXT_SENS_DATA_19   0x5C   // R
#define MPU6050_EXT_SENS_DATA_20   0x5D   // R
#define MPU6050_EXT_SENS_DATA_21   0x5E   // R
#define MPU6050_EXT_SENS_DATA_22   0x5F   // R
#define MPU6050_EXT_SENS_DATA_23   0x60   // R
#define MPU6050_MOT_DETECT_STATUS  0x61   // R
#define MPU6050_I2C_SLV0_DO        0x63   // R/W
#define MPU6050_I2C_SLV1_DO        0x64   // R/W
#define MPU6050_I2C_SLV2_DO        0x65   // R/W
#define MPU6050_I2C_SLV3_DO        0x66   // R/W
#define MPU6050_I2C_MST_DELAY_CTRL 0x67   // R/W
#define MPU6050_SIGNAL_PATH_RESET  0x68   // R/W
#define MPU6050_MOT_DETECT_CTRL    0x69   // R/W
#define MPU6050_USER_CTRL          0x6A   // R/W
#define MPU6050_PWR_MGMT_1         0x6B   // R/W
#define MPU6050_PWR_MGMT_2         0x6C   // R/W
#define MPU6050_FIFO_COUNTH        0x72   // R/W
#define MPU6050_FIFO_COUNTL        0x73   // R/W
#define MPU6050_FIFO_R_W           0x74   // R/W
#define MPU6050_WHO_AM_I           0x75   // R

//definiciones para los bits, para cambiar entre numero de bit y definiciones binarias
#define MPU6050_D0 0
#define MPU6050_D1 1
#define MPU6050_D2 2
#define MPU6050_D3 3
#define MPU6050_D4 4
#define MPU6050_D5 5
#define MPU6050_D6 6
#define MPU6050_D7 7

// AUX_VDDIO Register
#define MPU6050_AUX_VDDIO MPU6050_D7  // I2C high: 1=VDD, 0=VLOGIC

// CONFIG Register
//DLPF es un Filtro digital Low Pass para el giro y acelerometro
#define MPU6050_DLPF_CFG0     MPU6050_D0
#define MPU6050_DLPF_CFG1     MPU6050_D1
#define MPU6050_DLPF_CFG2     MPU6050_D2
#define MPU6050_EXT_SYNC_SET0 MPU6050_D3
#define MPU6050_EXT_SYNC_SET1 MPU6050_D4
#define MPU6050_EXT_SYNC_SET2 MPU6050_D5

// Combined definitions for the EXT_SYNC_SET values
#define MPU6050_EXT_SYNC_SET_0 (0)
#define MPU6050_EXT_SYNC_SET_1 (bit(MPU6050_EXT_SYNC_SET0))
#define MPU6050_EXT_SYNC_SET_2 (bit(MPU6050_EXT_SYNC_SET1))
#define MPU6050_EXT_SYNC_SET_3 (bit(MPU6050_EXT_SYNC_SET1)|bit(MPU6050_EXT_SYNC_SET0))
#define MPU6050_EXT_SYNC_SET_4 (bit(MPU6050_EXT_SYNC_SET2))
#define MPU6050_EXT_SYNC_SET_5 (bit(MPU6050_EXT_SYNC_SET2)|bit(MPU6050_EXT_SYNC_SET0))
#define MPU6050_EXT_SYNC_SET_6 (bit(MPU6050_EXT_SYNC_SET2)|bit(MPU6050_EXT_SYNC_SET1))
#define MPU6050_EXT_SYNC_SET_7 (bit(MPU6050_EXT_SYNC_SET2)|bit(MPU6050_EXT_SYNC_SET1)|bit(MPU6050_EXT_SYNC_SET0))

// Alternative names for the combined definitions.
#define MPU6050_EXT_SYNC_DISABLED     MPU6050_EXT_SYNC_SET_0
#define MPU6050_EXT_SYNC_TEMP_OUT_L   MPU6050_EXT_SYNC_SET_1
#define MPU6050_EXT_SYNC_GYRO_XOUT_L  MPU6050_EXT_SYNC_SET_2
#define MPU6050_EXT_SYNC_GYRO_YOUT_L  MPU6050_EXT_SYNC_SET_3
#define MPU6050_EXT_SYNC_GYRO_ZOUT_L  MPU6050_EXT_SYNC_SET_4
#define MPU6050_EXT_SYNC_ACCEL_XOUT_L MPU6050_EXT_SYNC_SET_5
#define MPU6050_EXT_SYNC_ACCEL_YOUT_L MPU6050_EXT_SYNC_SET_6
#define MPU6050_EXT_SYNC_ACCEL_ZOUT_L MPU6050_EXT_SYNC_SET_7

// Combined definitions for the DLPF_CFG values
#define MPU6050_DLPF_CFG_0 (0)
#define MPU6050_DLPF_CFG_1 (bit(MPU6050_DLPF_CFG0))
#define MPU6050_DLPF_CFG_2 (bit(MPU6050_DLPF_CFG1))
#define MPU6050_DLPF_CFG_3 (bit(MPU6050_DLPF_CFG1)|bit(MPU6050_DLPF_CFG0))
#define MPU6050_DLPF_CFG_4 (bit(MPU6050_DLPF_CFG2))
#define MPU6050_DLPF_CFG_5 (bit(MPU6050_DLPF_CFG2)|bit(MPU6050_DLPF_CFG0))
#define MPU6050_DLPF_CFG_6 (bit(MPU6050_DLPF_CFG2)|bit(MPU6050_DLPF_CFG1))
#define MPU6050_DLPF_CFG_7 (bit(MPU6050_DLPF_CFG2)|bit(MPU6050_DLPF_CFG1)|bit(MPU6050_DLPF_CFG0))

// Alternative names for the combined definitions
// This name uses the bandwidth (Hz) for the accelometer,
// for the gyro the bandwidth is almost the same.
#define MPU6050_DLPF_260HZ    MPU6050_DLPF_CFG_0
#define MPU6050_DLPF_184HZ    MPU6050_DLPF_CFG_1
#define MPU6050_DLPF_94HZ     MPU6050_DLPF_CFG_2
#define MPU6050_DLPF_44HZ     MPU6050_DLPF_CFG_3
#define MPU6050_DLPF_21HZ     MPU6050_DLPF_CFG_4
#define MPU6050_DLPF_10HZ     MPU6050_DLPF_CFG_5
#define MPU6050_DLPF_5HZ      MPU6050_DLPF_CFG_6
#define MPU6050_DLPF_RESERVED MPU6050_DLPF_CFG_7

// GYRO_CONFIG Register
// The XG_ST, YG_ST, ZG_ST are bits for selftest.
// The FS_SEL sets the range for the gyro.
// These are the names for the bits.
// Use these only with the bit() macro.
#define MPU6050_FS_SEL0 MPU6050_D3
#define MPU6050_FS_SEL1 MPU6050_D4
#define MPU6050_ZG_ST   MPU6050_D5
#define MPU6050_YG_ST   MPU6050_D6
#define MPU6050_XG_ST   MPU6050_D7

// Combined definitions for the FS_SEL values
#define MPU6050_FS_SEL_0 (0)
#define MPU6050_FS_SEL_1 (bit(MPU6050_FS_SEL0))
#define MPU6050_FS_SEL_2 (bit(MPU6050_FS_SEL1))
#define MPU6050_FS_SEL_3 (bit(MPU6050_FS_SEL1)|bit(MPU6050_FS_SEL0))

// Alternative names for the combined definitions
// The name uses the range in degrees per second.
#define MPU6050_FS_SEL_250  MPU6050_FS_SEL_0
#define MPU6050_FS_SEL_500  MPU6050_FS_SEL_1
#define MPU6050_FS_SEL_1000 MPU6050_FS_SEL_2
#define MPU6050_FS_SEL_2000 MPU6050_FS_SEL_3

// ACCEL_CONFIG Register
// The XA_ST, YA_ST, ZA_ST are bits for selftest.
// The AFS_SEL sets the range for the accelerometer.
// These are the names for the bits.
// Use these only with the bit() macro.
#define MPU6050_ACCEL_HPF0 MPU6050_D0
#define MPU6050_ACCEL_HPF1 MPU6050_D1
#define MPU6050_ACCEL_HPF2 MPU6050_D2
#define MPU6050_AFS_SEL0   MPU6050_D3
#define MPU6050_AFS_SEL1   MPU6050_D4
#define MPU6050_ZA_ST      MPU6050_D5
#define MPU6050_YA_ST      MPU6050_D6
#define MPU6050_XA_ST      MPU6050_D7

// Combined definitions for the ACCEL_HPF values
#define MPU6050_ACCEL_HPF_0 (0)
#define MPU6050_ACCEL_HPF_1 (bit(MPU6050_ACCEL_HPF0))
#define MPU6050_ACCEL_HPF_2 (bit(MPU6050_ACCEL_HPF1))
#define MPU6050_ACCEL_HPF_3 (bit(MPU6050_ACCEL_HPF1)|bit(MPU6050_ACCEL_HPF0))
#define MPU6050_ACCEL_HPF_4 (bit(MPU6050_ACCEL_HPF2))
#define MPU6050_ACCEL_HPF_7 (bit(MPU6050_ACCEL_HPF2)|bit(MPU6050_ACCEL_HPF1)|bit(MPU6050_ACCEL_HPF0))

// Alternative names for the combined definitions
// The name uses the Cut-off frequency.
#define MPU6050_ACCEL_HPF_RESET  MPU6050_ACCEL_HPF_0
#define MPU6050_ACCEL_HPF_5HZ    MPU6050_ACCEL_HPF_1
#define MPU6050_ACCEL_HPF_2_5HZ  MPU6050_ACCEL_HPF_2
#define MPU6050_ACCEL_HPF_1_25HZ MPU6050_ACCEL_HPF_3
#define MPU6050_ACCEL_HPF_0_63HZ MPU6050_ACCEL_HPF_4
#define MPU6050_ACCEL_HPF_HOLD   MPU6050_ACCEL_HPF_7

// Combined definitions for the AFS_SEL values
#define MPU6050_AFS_SEL_0 (0)
#define MPU6050_AFS_SEL_1 (bit(MPU6050_AFS_SEL0))
#define MPU6050_AFS_SEL_2 (bit(MPU6050_AFS_SEL1))
#define MPU6050_AFS_SEL_3 (bit(MPU6050_AFS_SEL1)|bit(MPU6050_AFS_SEL0))

// Alternative names for the combined definitions
// The name uses the full scale range for the accelerometer.
#define MPU6050_AFS_SEL_2G  MPU6050_AFS_SEL_0
#define MPU6050_AFS_SEL_4G  MPU6050_AFS_SEL_1
#define MPU6050_AFS_SEL_8G  MPU6050_AFS_SEL_2
#define MPU6050_AFS_SEL_16G MPU6050_AFS_SEL_3

// FIFO_EN Register
// These are the names for the bits.
// Use these only with the bit() macro.
#define MPU6050_SLV0_FIFO_EN  MPU6050_D0
#define MPU6050_SLV1_FIFO_EN  MPU6050_D1
#define MPU6050_SLV2_FIFO_EN  MPU6050_D2
#define MPU6050_ACCEL_FIFO_EN MPU6050_D3
#define MPU6050_ZG_FIFO_EN    MPU6050_D4
#define MPU6050_YG_FIFO_EN    MPU6050_D5
#define MPU6050_XG_FIFO_EN    MPU6050_D6
#define MPU6050_TEMP_FIFO_EN  MPU6050_D7

// I2C_MST_CTRL Register
// These are the names for the bits.
// Use these only with the bit() macro.
#define MPU6050_I2C_MST_CLK0  MPU6050_D0
#define MPU6050_I2C_MST_CLK1  MPU6050_D1
#define MPU6050_I2C_MST_CLK2  MPU6050_D2
#define MPU6050_I2C_MST_CLK3  MPU6050_D3
#define MPU6050_I2C_MST_P_NSR MPU6050_D4
#define MPU6050_SLV_3_FIFO_EN MPU6050_D5
#define MPU6050_WAIT_FOR_ES   MPU6050_D6
#define MPU6050_MULT_MST_EN   MPU6050_D7

// Combined definitions for the I2C_MST_CLK
#define MPU6050_I2C_MST_CLK_0 (0)
#define MPU6050_I2C_MST_CLK_1  (bit(MPU6050_I2C_MST_CLK0))
#define MPU6050_I2C_MST_CLK_2  (bit(MPU6050_I2C_MST_CLK1))
#define MPU6050_I2C_MST_CLK_3  (bit(MPU6050_I2C_MST_CLK1)|bit(MPU6050_I2C_MST_CLK0))
#define MPU6050_I2C_MST_CLK_4  (bit(MPU6050_I2C_MST_CLK2))
#define MPU6050_I2C_MST_CLK_5  (bit(MPU6050_I2C_MST_CLK2)|bit(MPU6050_I2C_MST_CLK0))
#define MPU6050_I2C_MST_CLK_6  (bit(MPU6050_I2C_MST_CLK2)|bit(MPU6050_I2C_MST_CLK1))
#define MPU6050_I2C_MST_CLK_7  (bit(MPU6050_I2C_MST_CLK2)|bit(MPU6050_I2C_MST_CLK1)|bit(MPU6050_I2C_MST_CLK0))
#define MPU6050_I2C_MST_CLK_8  (bit(MPU6050_I2C_MST_CLK3))
#define MPU6050_I2C_MST_CLK_9  (bit(MPU6050_I2C_MST_CLK3)|bit(MPU6050_I2C_MST_CLK0))
#define MPU6050_I2C_MST_CLK_10 (bit(MPU6050_I2C_MST_CLK3)|bit(MPU6050_I2C_MST_CLK1))
#define MPU6050_I2C_MST_CLK_11 (bit(MPU6050_I2C_MST_CLK3)|bit(MPU6050_I2C_MST_CLK1)|bit(MPU6050_I2C_MST_CLK0))
#define MPU6050_I2C_MST_CLK_12 (bit(MPU6050_I2C_MST_CLK3)|bit(MPU6050_I2C_MST_CLK2))
#define MPU6050_I2C_MST_CLK_13 (bit(MPU6050_I2C_MST_CLK3)|bit(MPU6050_I2C_MST_CLK2)|bit(MPU6050_I2C_MST_CLK0))
#define MPU6050_I2C_MST_CLK_14 (bit(MPU6050_I2C_MST_CLK3)|bit(MPU6050_I2C_MST_CLK2)|bit(MPU6050_I2C_MST_CLK1))
#define MPU6050_I2C_MST_CLK_15 (bit(MPU6050_I2C_MST_CLK3)|bit(MPU6050_I2C_MST_CLK2)|bit(MPU6050_I2C_MST_CLK1)|bit(MPU6050_I2C_MST_CLK0))

// Alternative names for the combined definitions
// The names uses I2C Master Clock Speed in kHz.
#define MPU6050_I2C_MST_CLK_348KHZ MPU6050_I2C_MST_CLK_0
#define MPU6050_I2C_MST_CLK_333KHZ MPU6050_I2C_MST_CLK_1
#define MPU6050_I2C_MST_CLK_320KHZ MPU6050_I2C_MST_CLK_2
#define MPU6050_I2C_MST_CLK_308KHZ MPU6050_I2C_MST_CLK_3
#define MPU6050_I2C_MST_CLK_296KHZ MPU6050_I2C_MST_CLK_4
#define MPU6050_I2C_MST_CLK_286KHZ MPU6050_I2C_MST_CLK_5
#define MPU6050_I2C_MST_CLK_276KHZ MPU6050_I2C_MST_CLK_6
#define MPU6050_I2C_MST_CLK_267KHZ MPU6050_I2C_MST_CLK_7
#define MPU6050_I2C_MST_CLK_258KHZ MPU6050_I2C_MST_CLK_8
#define MPU6050_I2C_MST_CLK_500KHZ MPU6050_I2C_MST_CLK_9
#define MPU6050_I2C_MST_CLK_471KHZ MPU6050_I2C_MST_CLK_10
#define MPU6050_I2C_MST_CLK_444KHZ MPU6050_I2C_MST_CLK_11
#define MPU6050_I2C_MST_CLK_421KHZ MPU6050_I2C_MST_CLK_12
#define MPU6050_I2C_MST_CLK_400KHZ MPU6050_I2C_MST_CLK_13
#define MPU6050_I2C_MST_CLK_381KHZ MPU6050_I2C_MST_CLK_14
#define MPU6050_I2C_MST_CLK_364KHZ MPU6050_I2C_MST_CLK_15

// I2C_SLV0_ADDR Register
// These are the names for the bits.
// Use these only with the bit() macro.
#define MPU6050_I2C_SLV0_RW MPU6050_D7

// I2C_SLV0_CTRL Register
// These are the names for the bits.
// Use these only with the bit() macro.
#define MPU6050_I2C_SLV0_LEN0    MPU6050_D0
#define MPU6050_I2C_SLV0_LEN1    MPU6050_D1
#define MPU6050_I2C_SLV0_LEN2    MPU6050_D2
#define MPU6050_I2C_SLV0_LEN3    MPU6050_D3
#define MPU6050_I2C_SLV0_GRP     MPU6050_D4
#define MPU6050_I2C_SLV0_REG_DIS MPU6050_D5
#define MPU6050_I2C_SLV0_BYTE_SW MPU6050_D6
#define MPU6050_I2C_SLV0_EN      MPU6050_D7

// A mask for the length
#define MPU6050_I2C_SLV0_LEN_MASK 0x0F

// I2C_SLV1_ADDR Register
// These are the names for the bits.
// Use these only with the bit() macro.
#define MPU6050_I2C_SLV1_RW MPU6050_D7

// I2C_SLV1_CTRL Register
// These are the names for the bits.
// Use these only with the bit() macro.
#define MPU6050_I2C_SLV1_LEN0    MPU6050_D0
#define MPU6050_I2C_SLV1_LEN1    MPU6050_D1
#define MPU6050_I2C_SLV1_LEN2    MPU6050_D2
#define MPU6050_I2C_SLV1_LEN3    MPU6050_D3
#define MPU6050_I2C_SLV1_GRP     MPU6050_D4
#define MPU6050_I2C_SLV1_REG_DIS MPU6050_D5
#define MPU6050_I2C_SLV1_BYTE_SW MPU6050_D6
#define MPU6050_I2C_SLV1_EN      MPU6050_D7

// A mask for the length
#define MPU6050_I2C_SLV1_LEN_MASK 0x0F

// I2C_SLV2_ADDR Register
// These are the names for the bits.
// Use these only with the bit() macro.
#define MPU6050_I2C_SLV2_RW MPU6050_D7

// I2C_SLV2_CTRL Register
// These are the names for the bits.
// Use these only with the bit() macro.
#define MPU6050_I2C_SLV2_LEN0    MPU6050_D0
#define MPU6050_I2C_SLV2_LEN1    MPU6050_D1
#define MPU6050_I2C_SLV2_LEN2    MPU6050_D2
#define MPU6050_I2C_SLV2_LEN3    MPU6050_D3
#define MPU6050_I2C_SLV2_GRP     MPU6050_D4
#define MPU6050_I2C_SLV2_REG_DIS MPU6050_D5
#define MPU6050_I2C_SLV2_BYTE_SW MPU6050_D6
#define MPU6050_I2C_SLV2_EN      MPU6050_D7

// A mask for the length
#define MPU6050_I2C_SLV2_LEN_MASK 0x0F

// I2C_SLV3_ADDR Register
// These are the names for the bits.
// Use these only with the bit() macro.
#define MPU6050_I2C_SLV3_RW MPU6050_D7

// I2C_SLV3_CTRL Register
// These are the names for the bits.
// Use these only with the bit() macro.
#define MPU6050_I2C_SLV3_LEN0    MPU6050_D0
#define MPU6050_I2C_SLV3_LEN1    MPU6050_D1
#define MPU6050_I2C_SLV3_LEN2    MPU6050_D2
#define MPU6050_I2C_SLV3_LEN3    MPU6050_D3
#define MPU6050_I2C_SLV3_GRP     MPU6050_D4
#define MPU6050_I2C_SLV3_REG_DIS MPU6050_D5
#define MPU6050_I2C_SLV3_BYTE_SW MPU6050_D6
#define MPU6050_I2C_SLV3_EN      MPU6050_D7

// A mask for the length
#define MPU6050_I2C_SLV3_LEN_MASK 0x0F

// I2C_SLV4_ADDR Register
// These are the names for the bits.
// Use these only with the bit() macro.
#define MPU6050_I2C_SLV4_RW MPU6050_D7

// I2C_SLV4_CTRL Register
// These are the names for the bits.
// Use these only with the bit() macro.
#define MPU6050_I2C_MST_DLY0     MPU6050_D0
#define MPU6050_I2C_MST_DLY1     MPU6050_D1
#define MPU6050_I2C_MST_DLY2     MPU6050_D2
#define MPU6050_I2C_MST_DLY3     MPU6050_D3
#define MPU6050_I2C_MST_DLY4     MPU6050_D4
#define MPU6050_I2C_SLV4_REG_DIS MPU6050_D5
#define MPU6050_I2C_SLV4_INT_EN  MPU6050_D6
#define MPU6050_I2C_SLV4_EN      MPU6050_D7

// A mask for the delay
#define MPU6050_I2C_MST_DLY_MASK 0x1F

// I2C_MST_STATUS Register
// These are the names for the bits.
// Use these only with the bit() macro.
#define MPU6050_I2C_SLV0_NACK MPU6050_D0
#define MPU6050_I2C_SLV1_NACK MPU6050_D1
#define MPU6050_I2C_SLV2_NACK MPU6050_D2
#define MPU6050_I2C_SLV3_NACK MPU6050_D3
#define MPU6050_I2C_SLV4_NACK MPU6050_D4
#define MPU6050_I2C_LOST_ARB  MPU6050_D5
#define MPU6050_I2C_SLV4_DONE MPU6050_D6
#define MPU6050_PASS_THROUGH  MPU6050_D7

// I2C_PIN_CFG Register
// These are the names for the bits.
// Use these only with the bit() macro.
#define MPU6050_CLKOUT_EN       MPU6050_D0
#define MPU6050_I2C_BYPASS_EN   MPU6050_D1
#define MPU6050_FSYNC_INT_EN    MPU6050_D2
#define MPU6050_FSYNC_INT_LEVEL MPU6050_D3
#define MPU6050_INT_RD_CLEAR    MPU6050_D4
#define MPU6050_LATCH_INT_EN    MPU6050_D5
#define MPU6050_INT_OPEN        MPU6050_D6
#define MPU6050_INT_LEVEL       MPU6050_D7

// INT_ENABLE Register
// These are the names for the bits.
// Use these only with the bit() macro.
#define MPU6050_DATA_RDY_EN    MPU6050_D0
#define MPU6050_I2C_MST_INT_EN MPU6050_D3
#define MPU6050_FIFO_OFLOW_EN  MPU6050_D4
#define MPU6050_ZMOT_EN        MPU6050_D5
#define MPU6050_MOT_EN         MPU6050_D6
#define MPU6050_FF_EN          MPU6050_D7

// INT_STATUS Register
// These are the names for the bits.
// Use these only with the bit() macro.
#define MPU6050_DATA_RDY_INT   MPU6050_D0
#define MPU6050_I2C_MST_INT    MPU6050_D3
#define MPU6050_FIFO_OFLOW_INT MPU6050_D4
#define MPU6050_ZMOT_INT       MPU6050_D5
#define MPU6050_MOT_INT        MPU6050_D6
#define MPU6050_FF_INT         MPU6050_D7

// MOT_DETECT_STATUS Register
// These are the names for the bits.
// Use these only with the bit() macro.
#define MPU6050_MOT_ZRMOT MPU6050_D0
#define MPU6050_MOT_ZPOS  MPU6050_D2
#define MPU6050_MOT_ZNEG  MPU6050_D3
#define MPU6050_MOT_YPOS  MPU6050_D4
#define MPU6050_MOT_YNEG  MPU6050_D5
#define MPU6050_MOT_XPOS  MPU6050_D6
#define MPU6050_MOT_XNEG  MPU6050_D7

// IC2_MST_DELAY_CTRL Register
// These are the names for the bits.
// Use these only with the bit() macro.
#define MPU6050_I2C_SLV0_DLY_EN MPU6050_D0
#define MPU6050_I2C_SLV1_DLY_EN MPU6050_D1
#define MPU6050_I2C_SLV2_DLY_EN MPU6050_D2
#define MPU6050_I2C_SLV3_DLY_EN MPU6050_D3
#define MPU6050_I2C_SLV4_DLY_EN MPU6050_D4
#define MPU6050_DELAY_ES_SHADOW MPU6050_D7

// SIGNAL_PATH_RESET Register
// These are the names for the bits.
// Use these only with the bit() macro.
#define MPU6050_TEMP_RESET  MPU6050_D0
#define MPU6050_ACCEL_RESET MPU6050_D1
#define MPU6050_GYRO_RESET  MPU6050_D2

// MOT_DETECT_CTRL Register
// These are the names for the bits.
// Use these only with the bit() macro.
#define MPU6050_MOT_COUNT0      MPU6050_D0
#define MPU6050_MOT_COUNT1      MPU6050_D1
#define MPU6050_FF_COUNT0       MPU6050_D2
#define MPU6050_FF_COUNT1       MPU6050_D3
#define MPU6050_ACCEL_ON_DELAY0 MPU6050_D4
#define MPU6050_ACCEL_ON_DELAY1 MPU6050_D5

// Combined definitions for the MOT_COUNT
#define MPU6050_MOT_COUNT_0 (0)
#define MPU6050_MOT_COUNT_1 (bit(MPU6050_MOT_COUNT0))
#define MPU6050_MOT_COUNT_2 (bit(MPU6050_MOT_COUNT1))
#define MPU6050_MOT_COUNT_3 (bit(MPU6050_MOT_COUNT1)|bit(MPU6050_MOT_COUNT0))

// Alternative names for the combined definitions
#define MPU6050_MOT_COUNT_RESET MPU6050_MOT_COUNT_0

// Combined definitions for the FF_COUNT
#define MPU6050_FF_COUNT_0 (0)
#define MPU6050_FF_COUNT_1 (bit(MPU6050_FF_COUNT0))
#define MPU6050_FF_COUNT_2 (bit(MPU6050_FF_COUNT1))
#define MPU6050_FF_COUNT_3 (bit(MPU6050_FF_COUNT1)|bit(MPU6050_FF_COUNT0))

// Alternative names for the combined definitions
#define MPU6050_FF_COUNT_RESET MPU6050_FF_COUNT_0

// Combined definitions for the ACCEL_ON_DELAY
#define MPU6050_ACCEL_ON_DELAY_0 (0)
#define MPU6050_ACCEL_ON_DELAY_1 (bit(MPU6050_ACCEL_ON_DELAY0))
#define MPU6050_ACCEL_ON_DELAY_2 (bit(MPU6050_ACCEL_ON_DELAY1))
#define MPU6050_ACCEL_ON_DELAY_3 (bit(MPU6050_ACCEL_ON_DELAY1)|bit(MPU6050_ACCEL_ON_DELAY0))

// Alternative names for the ACCEL_ON_DELAY
#define MPU6050_ACCEL_ON_DELAY_0MS MPU6050_ACCEL_ON_DELAY_0
#define MPU6050_ACCEL_ON_DELAY_1MS MPU6050_ACCEL_ON_DELAY_1
#define MPU6050_ACCEL_ON_DELAY_2MS MPU6050_ACCEL_ON_DELAY_2
#define MPU6050_ACCEL_ON_DELAY_3MS MPU6050_ACCEL_ON_DELAY_3

// USER_CTRL Register
// These are the names for the bits.
// Use these only with the bit() macro.
#define MPU6050_SIG_COND_RESET MPU6050_D0
#define MPU6050_I2C_MST_RESET  MPU6050_D1
#define MPU6050_FIFO_RESET     MPU6050_D2
#define MPU6050_I2C_IF_DIS     MPU6050_D4   // must be 0 for MPU-6050
#define MPU6050_I2C_MST_EN     MPU6050_D5
#define MPU6050_FIFO_EN        MPU6050_D6

// PWR_MGMT_1 Register
// These are the names for the bits.
// Use these only with the bit() macro.
#define MPU6050_CLKSEL0      MPU6050_D0
#define MPU6050_CLKSEL1      MPU6050_D1
#define MPU6050_CLKSEL2      MPU6050_D2
#define MPU6050_TEMP_DIS     MPU6050_D3    // 1: disable temperature sensor
#define MPU6050_CYCLE        MPU6050_D5    // 1: sample and sleep
#define MPU6050_SLEEP        MPU6050_D6    // 1: sleep mode
#define MPU6050_DEVICE_RESET MPU6050_D7    // 1: reset to default values

// Combined definitions for the CLKSEL
#define MPU6050_CLKSEL_0 (0)
#define MPU6050_CLKSEL_1 (bit(MPU6050_CLKSEL0))
#define MPU6050_CLKSEL_2 (bit(MPU6050_CLKSEL1))
#define MPU6050_CLKSEL_3 (bit(MPU6050_CLKSEL1)|bit(MPU6050_CLKSEL0))
#define MPU6050_CLKSEL_4 (bit(MPU6050_CLKSEL2))
#define MPU6050_CLKSEL_5 (bit(MPU6050_CLKSEL2)|bit(MPU6050_CLKSEL0))
#define MPU6050_CLKSEL_6 (bit(MPU6050_CLKSEL2)|bit(MPU6050_CLKSEL1))
#define MPU6050_CLKSEL_7 (bit(MPU6050_CLKSEL2)|bit(MPU6050_CLKSEL1)|bit(MPU6050_CLKSEL0))

// Alternative names for the combined definitions
#define MPU6050_CLKSEL_INTERNAL    MPU6050_CLKSEL_0
#define MPU6050_CLKSEL_X           MPU6050_CLKSEL_1
#define MPU6050_CLKSEL_Y           MPU6050_CLKSEL_2
#define MPU6050_CLKSEL_Z           MPU6050_CLKSEL_3
#define MPU6050_CLKSEL_EXT_32KHZ   MPU6050_CLKSEL_4
#define MPU6050_CLKSEL_EXT_19_2MHZ MPU6050_CLKSEL_5
#define MPU6050_CLKSEL_RESERVED    MPU6050_CLKSEL_6
#define MPU6050_CLKSEL_STOP        MPU6050_CLKSEL_7

// PWR_MGMT_2 Register
// These are the names for the bits.
// Use these only with the bit() macro.
#define MPU6050_STBY_ZG       MPU6050_D0
#define MPU6050_STBY_YG       MPU6050_D1
#define MPU6050_STBY_XG       MPU6050_D2
#define MPU6050_STBY_ZA       MPU6050_D3
#define MPU6050_STBY_YA       MPU6050_D4
#define MPU6050_STBY_XA       MPU6050_D5
#define MPU6050_LP_WAKE_CTRL0 MPU6050_D6
#define MPU6050_LP_WAKE_CTRL1 MPU6050_D7

// Combined definitions for the LP_WAKE_CTRL
#define MPU6050_LP_WAKE_CTRL_0 (0)
#define MPU6050_LP_WAKE_CTRL_1 (bit(MPU6050_LP_WAKE_CTRL0))
#define MPU6050_LP_WAKE_CTRL_2 (bit(MPU6050_LP_WAKE_CTRL1))
#define MPU6050_LP_WAKE_CTRL_3 (bit(MPU6050_LP_WAKE_CTRL1)|bit(MPU6050_LP_WAKE_CTRL0))

// Alternative names for the combined definitions
// The names uses the Wake-up Frequency.
#define MPU6050_LP_WAKE_1_25HZ MPU6050_LP_WAKE_CTRL_0
#define MPU6050_LP_WAKE_2_5HZ  MPU6050_LP_WAKE_CTRL_1
#define MPU6050_LP_WAKE_5HZ    MPU6050_LP_WAKE_CTRL_2
#define MPU6050_LP_WAKE_10HZ   MPU6050_LP_WAKE_CTRL_3

//Direccion predeterminada para el MPU-6050 es 0x68
//Unicamente si el pin AD0 esta en bajo
//SI AD0 esta en alto la direccion se convierte en 0x69
#define MPU6050_I2C_ADDRESS 0x68

//Declaracion de una union para los registros y los valores de los ejes.
//El orden de los bytes del MPU-6050 es: Byte alto en direccion baja
typedef union accel_t_gyro_union
{
  struct
  {
    uint8_t x_accel_h;
    uint8_t x_accel_l;
    uint8_t y_accel_h;
    uint8_t y_accel_l;
    uint8_t z_accel_h;
    uint8_t z_accel_l;
    uint8_t t_h;
    uint8_t t_l;
    uint8_t x_gyro_h;
    uint8_t x_gyro_l;
    uint8_t y_gyro_h;
    uint8_t y_gyro_l;
    uint8_t z_gyro_h;
    uint8_t z_gyro_l;
  } reg;
  struct
  {
    int16_t x_accel;
    int16_t y_accel;
    int16_t z_accel;
    int16_t temperature;
    int16_t x_gyro;
    int16_t y_gyro;
    int16_t z_gyro;
  } value;
};

/*******************************************************************************************
********************************************************************************************
********************************************************************************************
********************************************************************************************/

char str[512]; 

boolean firstSample = true;

float RwAcc[3];  //Proyeccion de vectores de fuerza gravitacional normalizada en ejes x,y,z medidos por el acelerometro
float Gyro_ds[3];  //Lecturas de giroscopio
float RwGyro[3];        //Valores RAW obtenidos del ultimo estimado y movimiento del giroscopio
float Awz[2];           //Angulo entre la proyeccion de R en el plano XZ/YZ y eje Z (grados)
float RwEst[3];

int lastTime = 0;
int interval = 0;
float wGyro = 10.0;

int MPU6050_write(int start, const uint8_t *pData, int size)
{
  int n, error;

  Wire.beginTransmission(MPU6050_I2C_ADDRESS);
  n = Wire.write(start);        // Escribe la direccion de inicio
  if (n != 1)
    return (-20);

  n = Wire.write(pData, size);  // Escribe bytes de datos
  if (n != size)
    return (-21);

  error = Wire.endTransmission(true); // libera el I2C-bus
  if (error != 0)
    return (error);

  return (0);         // return : no error
}

int MPU6050_read(int start, uint8_t *buffer, int size)
{
  int i, n, error;

  Wire.beginTransmission(MPU6050_I2C_ADDRESS);
  n = Wire.write(start);
  if (n != 1)
    return (-10);

  n = Wire.endTransmission(false);    // detener  I2C-bus
  if (n != 0)
    return (n);

  // Si el tercer parametro es verdadero: liberar I2C-bus despues de que haya sido leido el dato.
  Wire.requestFrom(MPU6050_I2C_ADDRESS, size, true);
  i = 0;
  while(Wire.available() && i<size)
  {
    buffer[i++]=Wire.read();
  }
  if ( i != size)
    return (-11);

  return (0);  // return : no error
}

void leer_GY521(){

}

void getAccelerometerData(int * result) {
    int error;
  accel_t_gyro_union accel_t_gyro;
//Lee los valores RAW, 14 bytes a la vez conteniendo aceleracion, temperatura y giroscopio
  //Con las configuraciones predeterminadas no hay fitro habilitado y los valroes no son estables
  error = MPU6050_read (MPU6050_ACCEL_XOUT_H, (uint8_t *) &accel_t_gyro, sizeof(accel_t_gyro));

 //Cada lectura de eje tiene una resolucion de 10 bits (2 bytes)
  result[0] = (((int)accel_t_gyro.reg.x_accel_h) << 8) | accel_t_gyro.reg.x_accel_l;
  result[1] = (((int)accel_t_gyro.reg.y_accel_h) << 8) | accel_t_gyro.reg.y_accel_l;
  result[2] = (((int)accel_t_gyro.reg.z_accel_h) << 8) | accel_t_gyro.reg.z_accel_l;

}
//Conversion de valores RAW de acelerometro a g's
//Dividiendo entre sensibilidad LSB segun el rango de escala (ver hoja de datos, Register Map and Descripcion, Accelerometer Measurements)
void rawAccToG(int * raw, float * RwAcc) {
  RwAcc[0] = ((float) raw[0]) / 16384.0;
  RwAcc[1] = ((float) raw[1]) / 16384.0;
  RwAcc[2] = ((float) raw[2]) / 16384.0;
}

void getGyroscopeData(int * result)
{
  int regAddress = 0x1B;
  int temp, x, y, z;
  int error;
  accel_t_gyro_union accel_t_gyro;
 //Lee los valores RAW, 14 bytes a la vez conteniendo aceleracion, temperatura y giroscopio
  //Con las configuraciones predeterminadas no hay fitro habilitado y los valroes no son estables.
  error = MPU6050_read (MPU6050_ACCEL_XOUT_H, (uint8_t *) &accel_t_gyro, sizeof(accel_t_gyro));
  result[0] = (((int)accel_t_gyro.reg.x_gyro_h) << 8) | accel_t_gyro.reg.x_gyro_l;
  result[1] = (((int)accel_t_gyro.reg.y_gyro_h) << 8) | accel_t_gyro.reg.y_gyro_l;
  result[2] = (((int)accel_t_gyro.reg.z_gyro_h) << 8) | accel_t_gyro.reg.z_gyro_l;
}

//Conversion de valores RAW de giroscopio a grados/seg
//Dividiendo el valor RAW entre sensibilidad LSB segun el rango de escala (ver hoja de datos, Register Map and Descripcion, Gyroscope Measurements )
void rawGyroToDegsec(int * raw, float * gyro_ds) {
  gyro_ds[0] = ((float) raw[0]) / 131;
  gyro_ds[1] = ((float) raw[1]) / 131;
  gyro_ds[2] = ((float) raw[2]) / 131;
}

void normalize3DVec(float * vector) {
  float R;
  R = sqrt(vector[0]*vector[0] + vector[1]*vector[1] + vector[2]*vector[2]);
  vector[0] /= R;
  vector[1] /= R;
  vector[2] /= R;
}

float squared(float x){
  return x*x;
}

void getInclination() {
  int w = 0;
  float tmpf = 0.0;
  int currentTime, signRzGyro;

  currentTime = millis();
  interval = currentTime - lastTime;
  lastTime = currentTime;

  if (firstSample) { //  NaN es utilizado para esperar datos buenos del Arduino
    for(w=0;w<=2;w++) {
      RwEst[w] = RwAcc[w];    //inicializa las lecturas del acelerometro
    }
  }
  else{
    //evalua el vector RwGyro
    if(abs(RwEst[2]) < 0.1) {
      //Rz es demasiado pequeño y es utlizado como referencia para calcular Axz, Ayz sus fluctuaciones de error amplificaran llevandolo a malos resultados
      //En este caso brincar el dato del giroscopio y utilizar el estimado anterior
      for(w=0;w<=2;w++) {
        RwGyro[w] = RwEst[w];
      }
    }
    else {
      //Tomar angulos entre la proyeccion de R en el plano ZX/ZY plane el eje Z,basado en el ultimo RwEst
      for(w=0;w<=1;w++){
        tmpf = Gyro_ds[w];                        //tomar tasa actual  get current de gyro en grado/s
        tmpf *= interval / 1000.0f;                     //tomar cambio de angulo en grados
        Awz[w] = atan2(RwEst[w],RwEst[2]) * 180 / PI;   //Tomar angulos y convertir a grados
        Awz[w] += tmpf;             //tomat angulo actualizado segun el movimiento del giroscopio
      }

      //Estimado de signo de RzGyro se hace viendo en que cuadrante esta el angulo Axz
      //RzGyro es positivo si Axz esta en un rango de -90 ..90 => cos(Awz) >= 0

      //estimar
      signRzGyro = ( cos(Awz[0] * PI / 180) >=0 ) ? 1 : -1;

      //calculo inverso de RwGyro a parit de angulos Awz, para deduccion de formulas ingresa a  http://starlino.com/imu_guide.html
      for(w=0;w<=1;w++){
        RwGyro[0] = sin(Awz[0] * PI / 180);
        RwGyro[0] /= sqrt( 1 + squared(cos(Awz[0] * PI / 180)) * squared(tan(Awz[1] * PI / 180)) );
        RwGyro[1] = sin(Awz[1] * PI / 180);
        RwGyro[1] /= sqrt( 1 + squared(cos(Awz[1] * PI / 180)) * squared(tan(Awz[0] * PI / 180)) );
      }
      RwGyro[2] = signRzGyro * sqrt(1 - squared(RwGyro[0]) - squared(RwGyro[1]));
    }

    //combina lectura de acelerometro y giroscoipio
    for(w=0;w<=2;w++) RwEst[w] = (RwAcc[w] + wGyro * RwGyro[w]) / (1 + wGyro);

    normalize3DVec(RwEst);
  }

  firstSample = false;
}

int MPU6050_write_reg(int reg, uint8_t data)
{
  int error;

  error = MPU6050_write(reg, &data, 1);

  return (error);
}

void setup()
{
  Serial.begin(19200);
 int error;
  uint8_t c;

  // Inicializa clase 'Wire' para I2C-bus.
  Wire.begin();

  // predetermninado al encender :
  //    Gyro a 250 grados por segundo
  //   Aceleracion a +/- 2g
  //    Reloj interno a  8MHz
  //    Dispositivo en modo suspendido
  //

  error = MPU6050_read (MPU6050_WHO_AM_I, &c, 1);

  // According to the datasheet, the 'sleep' bit
  // should read a '1'. But I read a '0'.
  // That bit has to be cleared, since the sensor
  // is in sleep mode at power-up. Even if the
  // bit reads '0'.

  //De acuerdo con la hoja de datos, el bit de 'suspension' debe ser leido en '1'
  //Este bit debe ser quitado
  error = MPU6050_read (MPU6050_PWR_MGMT_2, &c, 1);

  // Asignar '0' al bit de suspension para iniciar el sensor
  MPU6050_write_reg (MPU6050_PWR_MGMT_1, 0);
}

void loop()
{
  if(!Serial.available()) {

	int acc[3];
    int gyro[4];

    getAccelerometerData(acc);
    rawAccToG(acc, RwAcc);
    normalize3DVec(RwAcc);

    getGyroscopeData(gyro);
    rawGyroToDegsec(gyro, Gyro_ds);

    getInclination();

    serialPrintFloatArr(RwAcc, 3);
    serialPrintFloatArr(Gyro_ds, 3);
    serialPrintFloatArr(RwGyro, 3);
    serialPrintFloatArr(Awz, 2);
    serialPrintFloatArr(RwEst, 3);
    Serial.println();
    //Serial.print(10, BYTE);

    //delay(50);
  }
}

void serialPrintFloatArr(float * arr, int length) {
  for(int i=0; i<length; i++) {
    serialFloatPrint(arr[i]);
    Serial.print(",");
  }
}

void serialFloatPrint(float f) {
  byte * b = (byte *) &f;
  Serial.print("f:");
  for(int i=0; i<4; i++) {

    byte b1 = (b[i] >> 4) & 0x0f;
    byte b2 = (b[i] & 0x0f);

    char c1 = (b1 < 10) ? ('0' + b1) : 'A' + b1 - 10;
    char c2 = (b2 < 10) ? ('0' + b2) : 'A' + b2 - 10;

    Serial.print(c1);
    Serial.print(c2);
  }
}

 

DETALLES DE PROGRAMA

Declara la unión para los registros y valores de los ejes.  El MPU-6050 tiene un orden: Byte alto en dirección baja, así que se tiene que corregir. La parte de registro “reg” es usado internamente, y está intercambiando en código.

typedef union accel_t_gyro_union
{
struct
{
uint8_t x_accel_h;
uint8_t x_accel_l;
uint8_t y_accel_h;
uint8_t y_accel_l;
uint8_t z_accel_h;
uint8_t z_accel_l;
uint8_t t_h;
uint8_t t_l;
uint8_t x_gyro_h;
uint8_t x_gyro_l;
uint8_t y_gyro_h;
uint8_t y_gyro_l;
uint8_t z_gyro_h;
uint8_t z_gyro_l;
} reg;
struct
{
int16_t x_accel;
int16_t y_accel;
int16_t z_accel;
int16_t temperature;
int16_t x_gyro;
int16_t y_gyro;
int16_t z_gyro;
} value;
};

 

Inicializa la clase ‘Wire’ para el bus-I2C, cuando se inicializa MPU-6050 por default el giroscopio en 250 g/s,  aceleración a 2g, reloj interno 8MHz, el dispositivo está en modo suspendido. De acuerdo con la hoja de datos, el bit de suspendido debe ser leído como ‘1’. Limpia el bit de suspensión para iniciar el sensor.

void setup(){
  int error;
  uint8_t c;
  Serial.begin(9600);
  Wire.begin();
  error = MPU6050_read (MPU6050_WHO_AM_I, &c, 1);
  error = MPU6050_read (MPU6050_PWR_MGMT_2, &c, 1);
  MPU6050_write_reg (MPU6050_PWR_MGMT_1, 0);
}

 

Lee valores “RAW” del MPU-6050, lee 14 Bytes a la vez, conteniendo valores de aceleración, temperatura y giroscopio. Estos valores son leídos sin filtro. Se hace un cambio de los bytes high y low. Despues de esto, los valores de registro son intercambiados, la estructura xxxxx_l ya no contendrá el low byte.  Imprime los valores ‘Raw’ de aceleración e imprime valores de giroscopio y temperatura.

void loop(){
 int error;
 double dT;
 accel_t_gyro_union accel_t_gyro;
 error = MPU6050_read (MPU6050_ACCEL_XOUT_H,(uint8_t *)&accel_t_gyro,sizeof(accel_t_gyro));
  uint8_t swap;
  #define SWAP(x,y) swap = x; x = y; y = swap
 SWAP (accel_t_gyro.reg.x_accel_h, accel_t_gyro.reg.x_accel_l);
 SWAP (accel_t_gyro.reg.y_accel_h, accel_t_gyro.reg.y_accel_l);
  SWAP (accel_t_gyro.reg.z_accel_h, accel_t_gyro.reg.z_accel_l);
  SWAP (accel_t_gyro.reg.t_h, accel_t_gyro.reg.t_l);
  SWAP (accel_t_gyro.reg.x_gyro_h, accel_t_gyro.reg.x_gyro_l);
  SWAP (accel_t_gyro.reg.y_gyro_h, accel_t_gyro.reg.y_gyro_l);
  SWAP (accel_t_gyro.reg.z_gyro_h, accel_t_gyro.reg.z_gyro_l);
 int accel_x, accel_y, accel_z;
 accel_x=accel_t_gyro.value.x_accel*0.061035156;
 accel_y=accel_t_gyro.value.y_accel*0.061035156;
 accel_z=accel_t_gyro.value.z_accel*0.061035156;
 Serial.print(F("Aceleracion: x="));
  Serial.print(accel_x, DEC);
  Serial.print(F(" mG, y="));
  Serial.print(accel_y, DEC);
  Serial.print(F(" mG, z="));
  Serial.print(accel_z, DEC);
  Serial.print(F(" mG, Giroscopio: x="));
 Serial.print(accel_t_gyro.value.x_gyro, DEC);
  Serial.print(F(" b, y="));
  Serial.print(accel_t_gyro.value.y_gyro, DEC);
  Serial.print(F(" b, z="));
  Serial.print(accel_t_gyro.value.z_gyro, DEC);
  Serial.print(F(", Temp: "));
  dT = ( (double) accel_t_gyro.value.temperature + 12412.0) / 340.0;
  Serial.print(dT, 3);
  Serial.println(F(" C"));
  delay(1000);
}

 

Esta es una función común para leer múltiples bytes para dispositivos I2C, utiliza parámetros booleanos para Wire.endTransMission()para mantener o liberar el bus I2C. Libera bus I2C ya que el dato haya sido leído.

int MPU6050_read(int start, uint8_t *buffer, int size)
{
  int i, n, error;
  Wire.beginTransmission(MPU6050_I2C_ADDRESS);
  n = Wire.write(start);
  if (n != 1)
    return (-10);
    n = Wire.endTransmission(false);
  if (n != 0)
    return (n);
    Wire.requestFrom(MPU6050_I2C_ADDRESS, size, true);
    i = 0;
 	while(Wire.available() && i<size) {
    		buffer[i++]=Wire.read();
  }
  if ( i != size)
           return (-11);
          return (0);  // retorna: no error
}

 

Función común para escribir múltiples bytes a un dispositivo de I2C.

Parámetros:

start : Dirección de inicio

pData: Apuntador al data a escribir A pointer to the data to write.

size : Numero de bytes a escribir

Si se escribiera a un solo registro, es necesario utilizar un puntero al dato y el tamaño es un solo byte.

int MPU6050_write(int start, const uint8_t *pData, int size){
  int n, error;
  Wire.beginTransmission(MPU6050_I2C_ADDRESS);
  n = Wire.write(start);        // write the start address
  if (n != 1)
  return (-20);
  n = Wire.write(pData, size);  // write data bytes
  if (n != size)
 return (-21);
 error = Wire.endTransmission(true); // release the I2C-bus
  if (error != 0)
 return (error);
 return (0);         // return : no error
}

 

Acelerómetro y Giroscopio

Acelerómetro y Giroscopio

Figura: MPU6050 conectado al arduino.

Acelerómetro y Giroscopio

Acelerómetro y Giroscopio

Figura: Información obtenida por el MPU6050 de la aceleración y velocidad angular para los 3 grados de libertad y la temperatura.

Acelerómetro y Giroscopio

Acelerómetro y Giroscopio

Figura: Información obtenida por el MPU6050 de la aceleración y velocidad angular para los 3 grados de libertad y la temperatura.

 

 

Esta tutorial es propiedad de HeTPro. Queda expresamente prohibida la reproducción total o parcial por cualquier medio o soporte de los contenidos de esta publicación sin la autorización expresa del editor, cualquier duda, sugerencia o permiso para redistribuir el material favor de mandar un correo a contacto@hetpro.com.mx

 

Si la redistribución de este material es para fines educativos, difusión tecnológica o cualquier otro fin sin lucro, HeTPro está de acuerdo en que el material sea distribuido sin la necesidad de requerir el permiso del autor.

 

Bibliografia:

 

http://www.slideshare.net/berthatonks/acelermetro

 

http://fuenteabierta.teubi.co/2013/03/inclinometro-digital-con-arduino-uso-de.html

 

14 Comments

  1. Hola, primero de todo darte las gracias por el fantástico tutorial que nos has dejado. Pero tengo un problema cuando pongo el monitor serial de Arduino, y es que solo me salen números hexadecimales. Me podrías decir a que puede ser debido.

    Gracias

    • Jesus es normal, ya que el programa solo esta mandando los datos sin procesar, puedes usar el programa con los datos para verlos en la terminal serial o instalarte el processing y probarlo con este.

  2. Excelente. Tengo una duda. En el monitor serial. Los valores del giroscopio me salen diferentes siempre será algun problema del chip? ?

    • Hola que tal, a que te refieres con diferentes, con mucho ruido quizas? o valores aleatorios??. Es posible si te da mucho ruido que tenga algo, pero no lo creo. Normalmente el giroscopio te debe de dar siempre un valor cercano a 0, y cuando lo mueves se cambia el valor bruscamente y se regresa a cero, saludos.

  3. tengo una respuesta de este estilo

    AcX = -4448 | AcY = -2196 | AcZ = 14224 | Tmp = 25.52 | GyX = -241 | GyY = -173 | GyZ = -25
    AcX = -4344 | AcY = -2232 | AcZ = 14340 | Tmp = 25.57 | GyX = -242 | GyY = -174 | GyZ = -79
    AcX = -4344 | AcY = -2352 | AcZ = 14168 | Tmp = 25.57 | GyX = -238 | GyY = -145 | GyZ = -29
    AcX = -4344 | AcY = -2348 | AcZ = 14192 | Tmp = 25.52 | GyX = -253 | GyY = -163 | GyZ = -41
    AcX = -4344 | AcY = -2244 | AcZ = 14400 | Tmp = 25.57 | GyX = -227 | GyY = -167 | GyZ = -51
    AcX = -4372 | AcY = -2292 | AcZ = 14164 | Tmp = 25.52 | GyX = -232 | GyY = -149 | GyZ = -30
    AcX = -4440 | AcY = -2260 | AcZ = 14304 | Tmp = 25.47 | GyX = -288 | GyY = -177 | GyZ = -11
    AcX = -4464 | AcY = -2344 | AcZ = 14248 | Tmp = 25.52 | GyX = -256 | GyY = -86 | GyZ = 66
    AcX = -4340 | AcY = -2340 | AcZ = 14236 | Tmp = 25.47 | GyX = -241 | GyY = -178 | GyZ = -95
    AcX = -4420 | AcY = -2248 | AcZ = 14116 | Tmp = 25.52 | GyX = -264 | GyY = -149 | GyZ = -74
    AcX = -4544 | AcY = -2408 | AcZ = 13968 | Tmp = 25.61 | GyX = -267 | GyY = -180 | GyZ = -3
    AcX = -4272 | AcY = -2204 | AcZ = 14240 | Tmp = 25.47 | GyX = -227 | GyY = -181 | GyZ = -75
    AcX = -4280 | AcY = -2360 | AcZ = 14316 | Tmp = 25.57 | GyX = -278 | GyY = -148 | GyZ = -27
    AcX = -4400 | AcY = -2332 | AcZ = 14348 | Tmp = 25.61 | GyX = -244 | GyY = -160 | GyZ = -55
    AcX = -4460 | AcY = -2236 | AcZ = 14280 | Tmp = 25.61 | GyX = -262 | GyY = -161 | GyZ = -12
    AcX = -4364 | AcY = -2324 | AcZ = 14316 | Tmp = 25.57 | GyX = -248 | GyY = -174 | GyZ = -34
    AcX = -4404 | AcY = -2152 | AcZ = 14332 | Tmp = 25.57 | GyX = -281 | GyY = -154 | GyZ = -12
    AcX = -4360 | AcY = -2324 | AcZ = 14300 | Tmp = 25.57 | GyX = -241 | GyY = -169 | GyZ = -69
    AcX = -4356 | AcY = -2412 | AcZ = 14296 | Tmp = 25.61 | GyX = -255 | GyY = -190 | GyZ = -49
    AcX = -4396 | AcY = -2252 | AcZ = 14260 | Tmp = 25.61 | GyX = -258 | GyY = -161 | GyZ = -55
    AcX = -4380 | AcY = -2324 | AcZ = 14232 | Tmp = 25.57 | GyX = -291 | GyY = -181 | GyZ = -38
    AcX = -4476 | AcY = -2240 | AcZ = 14216 | Tmp = 25.57 | GyX = -256 | GyY = -194 | GyZ = -11
    AcX = -4444 | AcY = -2216 | AcZ = 14288 | Tmp = 25.57 | GyX = -256 | GyY = -157 | GyZ = -48
    AcX = -4316 | AcY = -2316 | AcZ = 14312 | Tmp = 25.61 | GyX = -222 | GyY = -162 | GyZ = -52
    AcX = -4396 | AcY = -2408 | AcZ = 14332 | Tmp = 25.71 | GyX = -258 | GyY = -182 | GyZ = -27
    AcX = -4348 | AcY = -2388 | AcZ = 14228 | Tmp = 25.71 | GyX = -242 | GyY = -176 | GyZ = -30
    AcX = -4496 | AcY = -2204 | AcZ = 14312 | Tmp = 25.57 | GyX = -249 | GyY = -138 | GyZ = -13
    AcX = -4368 | AcY = -2320 | AcZ = 14136 | Tmp = 25.66 | GyX = -225 | GyY = -187 | GyZ = -41
    AcX = -4376 | AcY = -2312 | AcZ = 14340 | Tmp = 25.66 | GyX = -295 | GyY = -156 | GyZ = -5
    AcX = -4360 | AcY = -2352 | AcZ = 14288 | Tmp = 25.66 | GyX = -268 | GyY = -171 | GyZ = -47
    AcX = -4412 | AcY = -2248 | AcZ = 14224 | Tmp = 25.71 | GyX = -249 | GyY = -172 | GyZ = -36
    AcX = -4348 | AcY = -2108 | AcZ = 14424 | Tmp = 25.61 | GyX = -278 | GyY = -179 | GyZ = -42
    AcX = -4356 | AcY = -2140 | AcZ = 14348 | Tmp = 25.61 | GyX = -271 | GyY = -168 | GyZ = -37
    AcX = -4416 | AcY = -2300 | AcZ = 14280 | Tmp = 25.71 | GyX = -243 | GyY = -162 | GyZ = -50
    AcX = -4176 | AcY = -2136 | AcZ = 14132 | Tmp = 25.71 | GyX = -222 | GyY = -192 | GyZ = 40
    AcX = -4336 | AcY = -2260 | AcZ = 14208 | Tmp = 25.66 | GyX = -227 | GyY = -120 | GyZ = -10
    AcX = -4384 | AcY = -2156 | AcZ = 14036 | Tmp = 25.66 | GyX = -527 | GyY = -287 | GyZ = -290
    AcX = -4404 | AcY = -2168 | AcZ = 14312 | Tmp = 25.71 | GyX = -353 | GyY = -160 | GyZ = -22
    AcX = -4368 | AcY = -2300 | AcZ = 14268 | Tmp = 25.71 | GyX = -245 | GyY = -200 | GyZ = -75
    AcX = -3980 | AcY = -2448 | AcZ = 14276 | Tmp = 25.66 | GyX = 430 | GyY = 101 | GyZ = 335
    AcX = -4420 | AcY = -2172 | AcZ = 14280 | Tmp = 25.61 | GyX = -91 | GyY = -104 | GyZ = -35
    AcX = -4508 | AcY = -2164 | AcZ = 14220 | Tmp = 25.71 | GyX = -270 | GyY = -187 | GyZ = 9
    AcX = -4476 | AcY = -2300 | AcZ = 14304 | Tmp = 25.66 | GyX = -296 | GyY = -202 | GyZ = -49
    AcX = -4280 | AcY = -2240 | AcZ = 14192 | Tmp = 25.80 | GyX = -220 | GyY = -176 | GyZ = -52
    AcX = -4388 | AcY = -2376 | AcZ = 14252 | Tmp = 25.71 | GyX = -227 | GyY = -149 | GyZ = -10
    AcX = -4404 | AcY = -2324 | AcZ = 14336 | Tmp = 25.71 | GyX = -241 | GyY = -160 | GyZ = -80
    AcX = -4420 | AcY = -2304 | AcZ = 14300 | Tmp = 25.71 | GyX = -262 | GyY = -159 | GyZ = -20
    AcX = -4156 | AcY = -2364 | AcZ = 14184 | Tmp = 25.75 | GyX = -315 | GyY = -202 | GyZ = -187
    AcX = -3980 | AcY = -2136 | AcZ = 14276 | Tmp = 25.75 | GyX = 82 | GyY = 65 | GyZ = -211
    AcX = -3908 | AcY = -2116 | AcZ = 14460 | Tmp = 25.71 | GyX = 37 | GyY = -55 | GyZ = 108
    AcX = -4264 | AcY = -2144 | AcZ = 14384 | Tmp = 25.75 | GyX = -279 | GyY = -110 | GyZ = 36
    AcX = -4388 | AcY = -2320 | AcZ = 14228 | Tmp = 25.80 | GyX = -235 | GyY = -209 | GyZ = -70
    AcX = -4276 | AcY = -2196 | AcZ = 14192 | Tmp = 25.80 | GyX = -252 | GyY = -133 | GyZ = 13
    AcX = -4200 | AcY = -2208 | AcZ = 14544 | Tmp = 25.75 | GyX = -250 | GyY = -132 | GyZ = -129
    AcX = -4408 | AcY = -2260 | AcZ = 14140 | Tmp = 25.80 | GyX = -248 | GyY = -145 | GyZ = -24
    AcX = -4296 | AcY = -2256 | AcZ = 14108 | Tmp = 25.80 | GyX = -259 | GyY = -191 | GyZ = -82
    AcX = -4432 | AcY = -2332 | AcZ = 14088 | Tmp = 25.71 | GyX = -247 | GyY = -157 | GyZ = -41
    AcX = -4352 | AcY = -2228 | AcZ = 14276 | Tmp = 25.80 | GyX = -230 | GyY = -199 | GyZ = -75
    AcX = -4348 | AcY = -2380 | AcZ = 14052 | Tmp = 25.71 | GyX = -263 | GyY = -134 | GyZ = -10
    AcX = -4436 | AcY = -2260 | AcZ = 14204 | Tmp = 25.71 | GyX = -193 | GyY = -199 | GyZ = -127
    AcX = -4284 | AcY = -2368 | AcZ = 14280 | Tmp = 25.75 | GyX = -141 | GyY = -82 | GyZ = -100
    AcX = -4492 | AcY = -2220 | AcZ = 13992 | Tmp = 25.80 | GyX = -365 | GyY = -169 | GyZ = -84
    AcX = -4288 | AcY = -2392 | AcZ = 14396 | Tmp = 25.71 | GyX = -232 | GyY = -213 | GyZ = -78
    AcX = -4392 | AcY = -2336 | AcZ = 14256 | Tmp = 25.80 | GyX = -272 | GyY = -197 | GyZ = -95
    AcX = -4408 | AcY = -2132 | AcZ = 14120 | Tmp = 25.80 | GyX = -383 | GyY = -212 | GyZ = -35
    AcX = -4208 | AcY = -2076 | AcZ = 14476 | Tmp = 25.71 | GyX = -500 | GyY = -208 | GyZ = -196
    AcX = -4480 | AcY = -2328 | AcZ = 14064 | Tmp = 25.75 | GyX = -442 | GyY = -262 | GyZ = -137
    AcX = -4204 | AcY = -2224 | AcZ = 14216 | Tmp = 25.80 | GyX = -320 | GyY = -238 | GyZ = -121
    AcX = -4248 | AcY = -2368 | AcZ = 14264 | Tmp = 25.80 | GyX = -338 | GyY = -123 | GyZ = -92
    AcX = -4604 | AcY = -2216 | AcZ = 14104 | Tmp = 25.80 | GyX = -15 | GyY = -99 | GyZ = 148
    AcX = -4352 | AcY = -2236 | AcZ = 14288 | Tmp = 25.75 | GyX = -331 | GyY = -200 | GyZ = -85
    AcX = -4376 | AcY = -2412 | AcZ = 14336 | Tmp = 25.75 | GyX = -151 | GyY = -112 | GyZ = 48
    AcX = -4296 | AcY = -2308 | AcZ = 14268 | Tmp = 25.75 | GyX = -275 | GyY = -131 | GyZ = -2
    AcX = -4484 | AcY = -2308 | AcZ = 14324 | Tmp = 25.85 | GyX = -233 | GyY = -167 | GyZ = -54
    AcX = -4300 | AcY = -2368 | AcZ = 14224 | Tmp = 25.80 | GyX = -262 | GyY = -205 | GyZ = -21
    AcX = -4204 | AcY = -2220 | AcZ = 14388 | Tmp = 25.75 | GyX = -268 | GyY = -79 | GyZ = 79
    AcX = -4244 | AcY = -2256 | AcZ = 14192 | Tmp = 25.80 | GyX = -247 | GyY = -94 | GyZ = 5
    AcX = -4200 | AcY = -2336 | AcZ = 14404 | Tmp = 25.89 | GyX = -74 | GyY = -122 | GyZ = -19
    AcX = -4384 | AcY = -2232 | AcZ = 14240 | Tmp = 25.89 | GyX = -253 | GyY = -171 | GyZ = -55
    AcX = -4484 | AcY = -2152 | AcZ = 14036 | Tmp = 25.94 | GyX = -80 | GyY = -98 | GyZ = 132
    AcX = -4396 | AcY = -2196 | AcZ = 14356 | Tmp = 25.89 | GyX = -198 | GyY = -161 | GyZ = 31
    AcX = -4312 | AcY = -2340 | AcZ = 14364 | Tmp = 25.94 | GyX = -242 | GyY = -175 | GyZ = -81
    AcX = -4268 | AcY = -2372 | AcZ = 14348 | Tmp = 25.89 | GyX = -43 | GyY = -93 | GyZ = 23
    AcX = -4424 | AcY = -2240 | AcZ = 14360 | Tmp = 25.94 | GyX = -284 | GyY = -176 | GyZ = -25
    AcX = -4448 | AcY = -2264 | AcZ = 14228 | Tmp = 25.89 | GyX = -209 | GyY = -212 | GyZ = -36
    AcX = -4284 | AcY = -2324 | AcZ = 14328 | Tmp = 25.89 | GyX = -364 | GyY = -245 | GyZ = -129
    AcX = -4512 | AcY = -2308 | AcZ = 14228 | Tmp = 25.94 | GyX = -485 | GyY = -200 | GyZ = -42
    AcX = -4276 | AcY = -2392 | AcZ = 14420 | Tmp = 25.94 | GyX = -161 | GyY = -167 | GyZ = -28
    AcX = -4400 | AcY = -2300 | AcZ = 14236 | Tmp = 25.89 | GyX = -223 | GyY = -162 | GyZ = -57
    AcX = -4296 | AcY = -2316 | AcZ = 14412 | Tmp = 25.94 | GyX = -419 | GyY = -156 | GyZ = 6
    AcX = -3660 | AcY = -1700 | AcZ = 15020 | Tmp = 26.04 | GyX = -1940 | GyY = -676 | GyZ = -804
    AcX = -4260 | AcY = -2144 | AcZ = 14276 | Tmp = 25.89 | GyX = -559 | GyY = -145 | GyZ = -130
    AcX = -4460 | AcY = -2084 | AcZ = 14344 | Tmp = 26.04 | GyX = 214 | GyY = 99 | GyZ = 415
    AcX = -4516 | AcY = -2284 | AcZ = 14336 | Tmp = 25.85 | GyX = -339 | GyY = -246 | GyZ = -112
    AcX = -4360 | AcY = -2360 | AcZ = 14228 | Tmp = 25.89 | GyX = -270 | GyY = -199 | GyZ = -71
    AcX = -4336 | AcY = -2316 | AcZ = 14344 | Tmp = 26.04 | GyX = -239 | GyY = -167 | GyZ = -42
    AcX = -4404 | AcY = -2268 | AcZ = 14224 | Tmp = 25.89 | GyX = -263 | GyY = -175 | GyZ = -71
    AcX = -4320 | AcY = -2312 | AcZ = 14372 | Tmp = 26.08 | GyX = -283 | GyY = -141 | GyZ = -21
    AcX = -4408 | AcY = -2380 | AcZ = 14288 | Tmp = 25.94 | GyX = -263 | GyY = -196 | GyZ = -54
    AcX = -4296 | AcY = -2152 | AcZ = 14312 | Tmp = 25.99 | GyX = -226 | GyY = -163 | GyZ = -20
    AcX = -4340 | AcY = -2412 | AcZ = 14120 | Tmp = 26.04 | GyX = -223 | GyY = -170 | GyZ = -36
    AcX = -4232 | AcY = -2368 | AcZ = 14112 | Tmp = 26.08 | GyX = -246 | GyY = -173 | GyZ = -55
    AcX = -4376 | AcY = -2352 | AcZ = 14284 | Tmp = 26.04 | GyX = -239 | GyY = -156 | GyZ = -29
    AcX = -4352 | AcY = -2188 | AcZ = 14356 | Tmp = 25.99 | GyX = -245 | GyY = -151 | GyZ = 6
    AcX = -4448 | AcY = -2424 | AcZ = 14168 | Tmp = 25.89 | GyX = -203 | GyY = -137 | GyZ = -60
    AcX = -4456 | AcY = -2328 | AcZ = 14172 | Tmp = 26.04 | GyX = -240 | GyY = -201 | GyZ = -128
    AcX = -4288 | AcY = -2308 | AcZ = 14176 | Tmp = 25.99 | GyX = -294 | GyY = -170 | GyZ = -32
    AcX = -4248 | AcY = -2308 | AcZ = 14268 | Tmp = 26.08 | GyX = -262 | GyY = -172 | GyZ = -56
    AcX = -4416 | AcY = -2104 | AcZ = 14188 | Tmp = 25.99 | GyX = -262 | GyY = -145 | GyZ = -2

    • Luis, los datos se ven coherentes, puedes dejar de mover el módulo y el giroscopio tiene que tender a cero, giralo en un eje y ese eje se tiene que incrementar. Para la resolución del sensor esos valores lucen bien suponiendo que no lo estabas moviendo mucho en ese momento.

  4. creo que algo he conectado mal pero lo he comprobado y nada… dicho esto el tutorial es increible pero me da caractéres muy extraños que windows ni los reconoce.

    • Que tal, estas usando arduino?, que velocidad serial estas configurando?

  5. Obtengo resultados como los siguientes:
    AcX = -4276 | AcY = -2392 | AcZ = 14420 | Tmp = 25.94 | GyX = -161 | GyY = -167 | GyZ = -28

    Esos valores son aceleraciones? Es decir en que unidad están medidos son m/s2 o que unidad tienen esos datos?

    • No tienen unidades fisicas, son cuentas del ADC, para sacar el valor lo puedes hacer en función a la resolución ajustada, por ejemplo si el sensor de de 16 bits, quiere decir que puede contar hasta 65536, de los cuales supongamos que tenemos +/- 2G de rango. Tomando valores positivos y negativos quedaria entonces 32768 = +2G y -2G = -32767 por lo que por ejemplo AxC = (-4276/32768)*2G= -0.26 y si lo quieres en m/s2 seria por 9.8m/s2 que serian = -2.55m/s2. Saludos

  6. Felicidades por tutorial de cómo podrían transformar datos de los sensores que son brutos, porque no contiene ninguna unidad física en grados.

  7. Hola, yo tengo un problema con el eje X. Lo calibro con la gravedad y el eje Y y Z si me dan los valores de manera correcta pero el X no, ese no me respeta nada

    • Pako como sabes que te da los valores incorrectos? o que valores te da?

Post a Reply

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *