Library 43- MPU-6050 6-axes gyro and accelerometer for STM32F4
MPU-6050 is a 3-axes accelerometer and 3-axes gyroscope MEMS sensor in one piece. It can also measure temperature. It is very cheap device but also very powerful. It can measure simultaneously three (X, Y and Z) channels for accelerometer and gyroscope at the same time with 16-bit resolution. This chip is also compatible with MPU9150, except that MPU9150 has 3axes magnetometer (or compass) included.
MPU-6050 Features
- Accelerometer
- 4 selectable full scales (2G, 4G, 8G and 16G)
- Gyroscope
- 4 selectable full scales (250°, 500°, 1000° and 2000°)
- Temperature sensor
- 1°C accuracy
- I2C driven
- Selectable LSB bit for I2C address, used with AD0 pin
- AD0 low: I2C address is 0xD0
- AD0 high: I2C address is 0xD2
- Max SCL speed is 400kHz
- Selectable LSB bit for I2C address, used with AD0 pin
Library
Features
- Read accelerometer data
- Read gyroscope data
- Read temperature
- Read everything above in one single function or separatelly
- Use 2 independent MPU-6050 devices on the same I2C bus
- Devices must have different AD0 pin state
Dependencies
- CMSIS
- STM32F4xx
- STM32F4xx RCC
- STM32F4xx GPIO
- STM32F4xx I2C
- TM
- TM I2C
- defines.h
- TM I2C
MPU-6050 | STM32F4 | Description |
---|---|---|
SCL | PA8 | I2C clock line |
SDA | PC9 | I2C data line |
AD0 | LSB address pin. If pin is high, address is 0xD2, otherwise 0xD0 | |
VCC | 3.3V power supply | |
GND | GND |
By default, I2C3 is used for communication. If you want to change it, open defines.h file and edit lines:
1 2 3 |
/* If you need to select custom I2C pins, uncomment and edit here */ //#define MPU6050_I2C I2C3 //#define MPU6050_I2C_PINSPACK TM_I2C_PinsPack_1 |
Note: If you want to connect 2 MPU6050 devices, you have to connect them to the same I2C pins but with different AD0 pin on MPU6050 device.
Functions and enumerations
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
/** * MPU6050 can have 2 different slave addresses, depends on it's input AD0 pin * This feature allows you to use 2 different sensors with this library at the same time * * Parameters: * - TM_MPU6050_Device_0: * AD0 pin is set to low * - TM_MPU6050_Device_1: * AD0 pin is set to high */ typedef enum { TM_MPU6050_Device_0 = 0, TM_MPU6050_Device_1 = 0x02 } TM_MPU6050_Device_t; /** * Result enumeration * * ParameterS: * - TM_MPU6050_Result_Ok: * Everything OK * - TM_MPU6050_Result_DeviceNotConnected: * There is no device with valid slave address * - TM_MPU6050_Result_DeviceInvalid: * Connected device with address is not MPU6050 */ typedef enum { TM_MPU6050_Result_Ok = 0x00, TM_MPU6050_Result_DeviceNotConnected, TM_MPU6050_Result_DeviceInvalid } TM_MPU6050_Result_t; /** * Set parameters for accelerometer range * * Parameters: * - TM_MPU6050_Accelerometer_2G: * Range is +- 2G * - TM_MPU6050_Accelerometer_4G: * Range is +- 4G * - TM_MPU6050_Accelerometer_8G: * Range is +- 8G * - TM_MPU6050_Accelerometer_16G: * Range is +- 16G */ typedef enum { TM_MPU6050_Accelerometer_2G = 0x00, TM_MPU6050_Accelerometer_4G = 0x01, TM_MPU6050_Accelerometer_8G = 0x02, TM_MPU6050_Accelerometer_16G = 0x03 } TM_MPU6050_Accelerometer_t; /** * Set parameters for gyroscope range * * Parameters: * - TM_MPU6050_Gyroscope_250s: * Range is +- 250°/s * - TM_MPU6050_Gyroscope_500s: * Range is +- 500°/s * - TM_MPU6050_Gyroscope_1000s: * Range is +- 1000°/s * - TM_MPU6050_Gyroscope_2000s: * Range is +- 20000°/s */ typedef enum { TM_MPU6050_Gyroscope_250s = 0x00, TM_MPU6050_Gyroscope_500s = 0x01, TM_MPU6050_Gyroscope_1000s = 0x02, TM_MPU6050_Gyroscope_2000s = 0x03 } TM_MPU6050_Gyroscope_t; /** * Main MPU6050 struct * * Parameters: * - uint8_t Address: * I2C address of device * Only for private use * - float Gyro_Mult: * Gyroscope corrector from raw data to "degrees/s" * Only for private use * - float Acce_Mult: * Accelerometer corrector from raw data to "g" * Only for private use * * - int16_t Accelerometer_X: * Accelerometer value X axis * - int16_t Accelerometer_Y: * Accelerometer value Y axis * - int16_t Accelerometer_Z: * Accelerometer value Z axis * - int16_t Gyroscope_X: * Gyroscope value X axis * - int16_t Gyroscope_Y: * Gyroscope value Y axis * - int16_t Gyroscope_Z: * Gyroscope value Z axis * - float Temperature: * Temperature in degrees */ typedef struct { /* Private */ uint8_t Address; float Gyro_Mult; float Acce_Mult; /* Public */ int16_t Accelerometer_X; int16_t Accelerometer_Y; int16_t Accelerometer_Z; int16_t Gyroscope_X; int16_t Gyroscope_Y; int16_t Gyroscope_Z; float Temperature; } TM_MPU6050_t; /** * Initialize MPU6050 * * Parameters: * - TM_MPU6050_t* DataStruct: * Pointer to TM_MPU6050_t empty working struct * - TM_MPU6050_Device_t DeviceNumber: * Device number. MPU6050 has one pin, AD0 which can be used to set address of device. * This feature allows you to use 2 different sensors on the same board with same library. * If you set AD0 pin to low, then this parameter should be TM_MPU6050_Device_0, * but if AD0 pin is high, then you should use TM_MPU6050_Device_1 * - TM_MPU6050_Accelerometer_t AccelerometerSensitivity: * Set accelerometer sensitivity * - TM_MPU6050_Gyroscope_t GyroscopeSensitivity: * Set gyroscope sensitivity * * Returns TM_MPU6050_Result_Ok if everything is OK */ extern TM_MPU6050_Result_t TM_MPU6050_Init(TM_MPU6050_t* DataStruct, TM_MPU6050_Device_t DeviceNumber, TM_MPU6050_Accelerometer_t AccelerometerSensitivity, TM_MPU6050_Gyroscope_t GyroscopeSensitivity); /** * Read accelerometer data from sensor * * Parameters: * - TM_MPU6050_t* DataStruct: * Pointer to TM_MPU6050_t struct to store accelerometer data * * Returns TM_MPU6050_Result_Ok if everything is OK */ extern TM_MPU6050_Result_t TM_MPU6050_ReadAccelerometer(TM_MPU6050_t* DataStruct); /** * Read gyroscope data from sensor * * Parameters: * - TM_MPU6050_t* DataStruct: * Pointer to TM_MPU6050_t struct to store gyroscope data * * Returns TM_MPU6050_Result_Ok if everything is OK */ extern TM_MPU6050_Result_t TM_MPU6050_ReadGyroscope(TM_MPU6050_t* DataStruct); /** * Read temperature data from sensor * * Parameters: * - TM_MPU6050_t* DataStruct: * Pointer to TM_MPU6050_t struct to store temperature data * * Returns TM_MPU6050_Result_Ok if everything is OK */ extern TM_MPU6050_Result_t TM_MPU6050_ReadTemperature(TM_MPU6050_t* DataStruct); /** * Read accelerometer, gyrscope and temperature data from sensor * * Parameters: * - TM_MPU6050_t* DataStruct: * Pointer to TM_MPU6050_t struct to store data * * Returns TM_MPU6050_Result_Ok if everything is OK */ extern TM_MPU6050_Result_t TM_MPU6050_ReadAll(TM_MPU6050_t* DataStruct); |
Example 1
- One MPU-6050 device is connected to pins PA8 and PC9 on STM32F4
- AD0 of MPU6050 is connected to GND, gives us address 0xD0
- Read is performed every 500ms, displayed on USART1 (PB6, at 115200 baud) to the computer
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
/** * Keil project example for 2 MPU6050 6-axes sensors * * Before you start, select your target, on the right of the "Load" button * * @author Tilen Majerle * @email tilen@majerle.eu * @website http://stm32f4-discovery.net * @ide Keil uVision 5 * @packs STM32F4xx Keil packs version 2.2.0 or greater required * @stdperiph STM32F4xx Standard peripheral drivers version 1.4.0 or greater required */ /* Include core modules */ #include "stm32f4xx.h" /* Include my libraries here */ #include "defines.h" #include "tm_stm32f4_delay.h" #include "tm_stm32f4_usart.h" #include "tm_stm32f4_mpu6050.h" #include <stdio.h> int main(void) { TM_MPU6050_t MPU6050_Data0; TM_MPU6050_t MPU6050_Data1; uint8_t sensor1 = 0, sensor2 = 0; char str[120]; /* Initialize system */ SystemInit(); /* Initialize delay */ TM_DELAY_Init(); /* Initialize USART, TX: PB6 */ TM_USART_Init(USART1, TM_USART_PinsPack_2, 115200); /* Initialize MPU6050 sensor 0, address = 0xD0, AD0 pin on sensor is low */ if (TM_MPU6050_Init(&MPU6050_Data0, TM_MPU6050_Device_0, TM_MPU6050_Accelerometer_8G, TM_MPU6050_Gyroscope_250s) == TM_MPU6050_Result_Ok) { /* Display message to user */ TM_USART_Puts(USART1, "MPU6050 sensor 0 is ready to use!\n"); /* Sensor 1 OK */ sensor1 = 1; } /* Initialize MPU6050 sensor 1, address = 0xD2, AD0 pin on sensor is high */ if (TM_MPU6050_Init(&MPU6050_Data1, TM_MPU6050_Device_1, TM_MPU6050_Accelerometer_8G, TM_MPU6050_Gyroscope_250s) == TM_MPU6050_Result_Ok) { /* Display message to user */ TM_USART_Puts(USART1, "MPU6050 sensor 1 is ready to use!\n"); /* Sensor 2 OK */ sensor2 = 1; } while (1) { /* Every 500ms */ if (TM_DELAY_Time() >= 500) { /* Reset time */ TM_DELAY_SetTime(0); /* If sensor 1 is connected */ if (sensor1) { /* Read all data from sensor 1 */ TM_MPU6050_ReadAll(&MPU6050_Data0); /* Format data */ sprintf(str, "1. Accelerometer\n- X:%d\n- Y:%d\n- Z:%d\nGyroscope\n- X:%d\n- Y:%d\n- Z:%d\nTemperature\n- %3.4f\n\n\n", MPU6050_Data0.Accelerometer_X, MPU6050_Data0.Accelerometer_Y, MPU6050_Data0.Accelerometer_Z, MPU6050_Data0.Gyroscope_X, MPU6050_Data0.Gyroscope_Y, MPU6050_Data0.Gyroscope_Z, MPU6050_Data0.Temperature ); /* Show to usart */ TM_USART_Puts(USART1, str); } /* If sensor 2 is connected */ if (sensor2) { /* Read all data from sensor 1 */ TM_MPU6050_ReadAll(&MPU6050_Data1); /* Format data */ sprintf(str, "2. Accelerometer\n- X:%d\n- Y:%d\n- Z:%d\nGyroscope\n- X:%d\n- Y:%d\n- Z:%d\nTemperature\n- %3.4f\n\n\n", MPU6050_Data1.Accelerometer_X, MPU6050_Data1.Accelerometer_Y, MPU6050_Data1.Accelerometer_Z, MPU6050_Data1.Gyroscope_X, MPU6050_Data1.Gyroscope_Y, MPU6050_Data1.Gyroscope_Z, MPU6050_Data1.Temperature ); /* Show to usart */ TM_USART_Puts(USART1, str); } } } } |
Example 2
- Two MPU-6050 devices are connected to STM32F4, both to pins PA8 and PC9
- First device has AD0 pin connected to GND, gives us 0xD0 address
- Second device has AD0 pin connected to 3.3V, gives is 0xD2 address
- Both devices are send to USART
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
/** * Keil project example for 2 MPU6050 6-axes sensors * * Before you start, select your target, on the right of the "Load" button * * @author Tilen Majerle * @email tilen@majerle.eu * @website http://stm32f4-discovery.net * @ide Keil uVision 5 * @packs STM32F4xx Keil packs version 2.2.0 or greater required * @stdperiph STM32F4xx Standard peripheral drivers version 1.4.0 or greater required */ /* Include core modules */ #include "stm32f4xx.h" /* Include my libraries here */ #include "defines.h" #include "tm_stm32f4_delay.h" #include "tm_stm32f4_usart.h" #include "tm_stm32f4_mpu6050.h" #include <stdio.h> int main(void) { TM_MPU6050_t MPU6050_Data0; TM_MPU6050_t MPU6050_Data1; uint8_t sensor1 = 0, sensor2 = 0; char str[120]; /* Initialize system */ SystemInit(); /* Initialize delay */ TM_DELAY_Init(); /* Initialize USART, TX: PB6 */ TM_USART_Init(USART1, TM_USART_PinsPack_2, 115200); /* Initialize MPU6050 sensor 0, address = 0xD0, AD0 pin on sensor is low */ if (TM_MPU6050_Init(&MPU6050_Data0, TM_MPU6050_Device_0, TM_MPU6050_Accelerometer_8G, TM_MPU6050_Gyroscope_250s) == TM_MPU6050_Result_Ok) { /* Display message to user */ TM_USART_Puts(USART1, "MPU6050 sensor 0 is ready to use!\n"); /* Sensor 1 OK */ sensor1 = 1; } /* Initialize MPU6050 sensor 1, address = 0xD2, AD0 pin on sensor is high */ if (TM_MPU6050_Init(&MPU6050_Data1, TM_MPU6050_Device_1, TM_MPU6050_Accelerometer_8G, TM_MPU6050_Gyroscope_250s) == TM_MPU6050_Result_Ok) { /* Display message to user */ TM_USART_Puts(USART1, "MPU6050 sensor 1 is ready to use!\n"); /* Sensor 2 OK */ sensor2 = 1; } while (1) { /* Every 500ms */ if (TM_DELAY_Time() >= 500000) { /* Reset time */ TM_DELAY_SetTime(0); /* If sensor 1 is connected */ if (sensor1) { /* Read all data from sensor 1 */ TM_MPU6050_ReadAll(&MPU6050_Data0); /* Format data */ sprintf(str, "1. Accelerometer\n- X:%d\n- Y:%d\n- Z:%d\nGyroscope\n- X:%d\n- Y:%d\n- Z:%d\nTemperature\n- %3.4f\n\n\n", MPU6050_Data0.Accelerometer_X, MPU6050_Data0.Accelerometer_Y, MPU6050_Data0.Accelerometer_Z, MPU6050_Data0.Gyroscope_X, MPU6050_Data0.Gyroscope_Y, MPU6050_Data0.Gyroscope_Z, MPU6050_Data0.Temperature ); /* Show to usart */ TM_USART_Puts(USART1, str); } /* If sensor 2 is connected */ if (sensor2) { /* Read all data from sensor 1 */ TM_MPU6050_ReadAll(&MPU6050_Data1); /* Format data */ sprintf(str, "2. Accelerometer\n- X:%d\n- Y:%d\n- Z:%d\nGyroscope\n- X:%d\n- Y:%d\n- Z:%d\nTemperature\n- %3.4f\n\n\n", MPU6050_Data1.Accelerometer_X, MPU6050_Data1.Accelerometer_Y, MPU6050_Data1.Accelerometer_Z, MPU6050_Data1.Gyroscope_X, MPU6050_Data1.Gyroscope_Y, MPU6050_Data1.Gyroscope_Z, MPU6050_Data1.Temperature ); /* Show to usart */ TM_USART_Puts(USART1, str); } } } } |
Both projects are available on Github, download library below.
MPU-6050 6-axes gyroscope and accelerometer library for STM32F4
Recent comments