{"id":4331,"date":"2019-03-06T20:00:32","date_gmt":"2019-03-06T19:00:32","guid":{"rendered":"https:\/\/msalamon.pl\/?p=4331"},"modified":"2025-12-27T19:57:08","modified_gmt":"2025-12-27T18:57:08","slug":"6-degrees-of-freedom-with-the-mpu6050-on-stm32","status":"publish","type":"post","link":"https:\/\/msalamon.pl\/en\/6-degrees-of-freedom-with-the-mpu6050-on-stm32\/","title":{"rendered":"6 Degrees of Freedom with the MPU6050 on STM32"},"content":{"rendered":"\n<p>I remember when the Nokia N95 hit the market, which was a huge technological leap. It had a built-in accelerometer thanks to which, among other things, the interface would change orientation by itself. Today this probably doesn\u2019t impress anyone anymore, but in 2007 an app with lightsaber sounds triggered by <\/p>\n\n\n\n<!--more-->\n\n\n\n<p>waving the phone blew my mind. Today accelerometers are present in many devices. And not just accelerometers, because these are powerful and extensive IMU (<em>Inertial Measurement Unit<\/em>) units having not\u2014like an accelerometer\u20143 degrees of freedom (acceleration along the X, Y and Z axes), but 6, 9, and in combination with a barometer even 10 degrees of freedom, also denoted as XDoF (X \u2013 number of degrees).<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">MPU6050 Accelerometer<\/h1>\n\n\n\n<p>Today\u2019s patient will be the <a href=\"https:\/\/sklep.msalamon.pl\/produkt\/mpu6050-modul\/?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=mpu6050&amp;utm_content=Text\">MPU6050<\/a> from <em>InvenSense. <\/em>It\u2019s a 6\u2011degree\u2011of\u2011freedom IMU. Thanks to the built\u2011in gyroscope it extends the basic 3 degrees from the accelerometer by another 3 from the gyroscope. Thus, with it we can measure acceleration (accelerometer) and angular velocity (gyroscope) around each axis. This sensor is a MEMS (<em>M<\/em><i>icroelectromechanical System)<\/i>, which means that in addition to electronics it also contains mechanical (moving) elements in its structure.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"https:\/\/sklep.msalamon.pl\/produkt\/mpu6050-modul\/?utm_source=blog&amp;utm_medium=banner&amp;utm_campaign=mpu6050&amp;utm_content=mpu6050\" target=\"_blank\" rel=\"noopener noreferrer\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"341\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2019\/03\/MPU6050_baner-1024x341.jpg\" alt=\"\" class=\"wp-image-949\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2019\/03\/MPU6050_baner-1024x341.jpg 1024w, https:\/\/msalamon.pl\/wp-content\/uploads\/2019\/03\/MPU6050_baner-300x100.jpg 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2019\/03\/MPU6050_baner-768x256.jpg 768w, https:\/\/msalamon.pl\/wp-content\/uploads\/2019\/03\/MPU6050_baner-24x8.jpg 24w, https:\/\/msalamon.pl\/wp-content\/uploads\/2019\/03\/MPU6050_baner-36x12.jpg 36w, https:\/\/msalamon.pl\/wp-content\/uploads\/2019\/03\/MPU6050_baner-160x53.jpg 160w, https:\/\/msalamon.pl\/wp-content\/uploads\/2019\/03\/MPU6050_baner.jpg 1200w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Parameters<\/h2>\n\n\n\n<p>The chip is very small. Its dimensions are only 4 x 4 x 0.9 mm, which makes it ideal for use in small devices such as smartphones, watches or drones. The MPU6050 has six 16\u2011bit converters built in, one for each measured value. The measured acceleration and rotational speed ranges are set in software. The accelerometer can measure within \u00b12g, \u00b14g, \u00b18g or \u00b116g, while the gyroscope within \u00b1250, \u00b1500, \u00b11000, \u00b12000\u00b0\/sec (aka dps \u2013 <em>degrees per second<\/em>).<\/p>\n\n\n\n<p>The chip has a built\u2011in 1024\u2011byte FIFO queue. Thanks to this, you can read from the chip less often and save more power if the device is battery\u2011powered.<\/p>\n\n\n\n<p>To offload the microcontroller that will fetch data from the accelerometer, the <a href=\"https:\/\/sklep.msalamon.pl\/produkt\/mpu6050-modul\/?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=mpu6050&amp;utm_content=Text\">MPU6050<\/a> has a built\u2011in \u2018motion processor\u2019 DMP (<em>Digital Motion Process<\/em>). This unit allows, for example, motion detection or free\u2011fall detection as well as many other useful things. Unfortunately, the user has no direct access to it. Even the documentation doesn\u2019t say much about the DMP. On the Internet there are many results of reverse engineering that allow you to use part of the DMP\u2019s features. To fully enjoy the motion processor assistance, you should use the libraries provided by <em>InvenSense<\/em>.<\/p>\n\n\n\n<p>As for electrical parameters, the supply voltage tolerated by the chip is in the range 2.375\u20133.46 V. The interface through which you can talk to the IMU is I\u00b2C. Interestingly, the chip itself allows the I\u00b2C logic to operate at voltages as low as 1.71 V. However, Chinese modules do not allow this\u2014all of the chip\u2019s power pins are connected to 3.3 V.<\/p>\n\n\n\n<p>An interesting tidbit is the built\u2011in temperature sensor, which we can simply use.<\/p>\n\n\n\n<p>Another interesting thing is the ability to connect additional I\u00b2C devices to the MPU6050. The chip can communicate with other devices and collect data from them. You can use, for example, an external magnetometer\/compass and thus add another three degrees of freedom. We can simultaneously handle four different I\u00b2C devices via the MPU6050\u2019s external I\u00b2C lines.<\/p>\n\n\n\n<p>More data such as current consumption under various conditions and configurations can be found in the documentation: <a data-e-disable-page-transition=\"true\" class=\"download-link\" title=\"\" href=\"https:\/\/msalamon.pl\/download\/627\/?tmstv=1766859693\" rel=\"nofollow\" id=\"download-link-627\" data-redirect=\"false\"><br>MPU60X0 Datasheet.pdf<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Schematic and configuration<\/h2>\n\n\n\n<p>Today I\u2019ll use the <a href=\"https:\/\/sklep.msalamon.pl\/produkt\/nucleo-f401re\/?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=dlaczegostm32&amp;utm_content=Text\">Nucleo board with the STM32F401RE microcontroller.<\/a><\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"https:\/\/sklep.msalamon.pl\/kategoria-produktu\/dev-boardy\/stm32-nucleo\/?utm_source=blog&amp;utm_medium=banner&amp;utm_campaign=mpu6050&amp;utm_content=nucleo\"><img loading=\"lazy\" decoding=\"async\" width=\"1200\" height=\"400\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/07\/Nucleo-64-baner.jpg\" alt=\"\" class=\"wp-image-1593\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/07\/Nucleo-64-baner.jpg 1200w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/07\/Nucleo-64-baner-300x100.jpg 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/07\/Nucleo-64-baner-1024x341.jpg 1024w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/07\/Nucleo-64-baner-768x256.jpg 768w\" sizes=\"auto, (max-width: 1200px) 100vw, 1200px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p>My module with the MPU6050 is the popular <a class=\"thirstylink\" title=\"MPU6050\" href=\"https:\/\/sklep.msalamon.pl\/produkt\/mpu6050-modul\/?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=mpu6050&amp;utm_content=Text\">GY-521<\/a>. The wiring diagram is as follows:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_schematic.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"1000\" height=\"530\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_schematic.jpg\" alt=\"\" class=\"wp-image-623\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_schematic.jpg 1000w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_schematic-300x159.jpg 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_schematic-768x407.jpg 768w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_schematic-24x13.jpg 24w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_schematic-36x19.jpg 36w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_schematic-151x80.jpg 151w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<p>The Cube configuration is simple\u2014I\u00b2C and an external interrupt on pin PA6. I\u00b2C can be sped up to 400 kHz. I pulled the interrupt down to ground with an external resistor, and in the configuration I chose no internal pull\u2011up. Of course, you can use the internal ones. UART, LED and TEST are for testing and debugging purposes.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_cube_i2c.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"1680\" height=\"1010\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_cube_i2c.jpg\" alt=\"\" class=\"wp-image-625\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_cube_i2c.jpg 1680w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_cube_i2c-300x180.jpg 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_cube_i2c-1024x616.jpg 1024w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_cube_i2c-768x462.jpg 768w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_cube_i2c-1536x923.jpg 1536w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_cube_i2c-24x14.jpg 24w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_cube_i2c-36x22.jpg 36w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_cube_i2c-133x80.jpg 133w\" sizes=\"auto, (max-width: 1680px) 100vw, 1680px\" \/><\/a><\/figure>\n<\/div>\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_cube_exti.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"326\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_cube_exti.jpg\" alt=\"\" class=\"wp-image-624\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_cube_exti.jpg 624w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_cube_exti-300x157.jpg 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_cube_exti-24x13.jpg 24w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_cube_exti-36x19.jpg 36w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_cube_exti-153x80.jpg 153w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Code<\/h2>\n\n\n\n<p>The code can basically be divided into 4 sections:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Accelerometer configuration<\/li>\n\n\n\n<li>Reading measured values<\/li>\n\n\n\n<li>Interrupt configuration<\/li>\n\n\n\n<li>Hidden DMP functions<\/li>\n<\/ul>\n\n\n\n<p>In the configuration part there\u2019s the standard device initialization function.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">void MPU6050_Init(I2C_HandleTypeDef *hi2c);<\/pre>\n\n\n\n<p>It resets the accelerometer to default values, sets the clock source, and sets the measurement ranges for acceleration and angular velocity to \u00b12g and \u00b1250\u00b0\/sec.<\/p>\n\n\n\n<p>Besides that, a number of functions handle configuration. The names really speak for themselves. You can reset the MPU6050, set the clocks, put the individual sensors to sleep or disable them. If needed, you can also increase the measurement range of the accelerometer and gyroscope.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/\n\/\/ PWR_MGMT_1\n\/\/\nvoid MPU6050_DeviceReset(uint8_t Reset);\nvoid MPU6050_SetClockSource(uint8_t Source);\nvoid MPU6050_SetSleepEnabled(uint8_t Enable);\nvoid MPU6050_SetCycleEnabled(uint8_t Enable);\nvoid MPU6050_SetTemperatureSensorDisbled(uint8_t Disable);\n\n\/\/\n\/\/ PWR_MGMT_2\n\/\/\nvoid MPU6050_SetLowPowerWakeUpFrequency(uint8_t Frequency);\nvoid MPU6050_AccelerometerAxisStandby(uint8_t XA_Stby, uint8_t YA_Stby, uint8_t ZA_Stby);\nvoid MPU6050_GyroscopeAxisStandby(uint8_t XG_Stby, uint8_t YG_Stby, uint8_t ZG_Stby);\n\n\/\/\n\/\/ Measurement scale configuration\n\/\/\nvoid MPU6050_SetFullScaleGyroRange(uint8_t Range);\nvoid MPU6050_SetFullScaleAccelRange(uint8_t Range);<\/pre>\n\n\n\n<p>Probably the most important part from the user\u2019s point of view is reading data from the accelerometer. I prepared several functions returning data in different variants. Functions with the RAW suffix return exactly what\u2019s in the registers. The <em>Scaled<\/em> functions return values scaled to the selected maximum range, i.e., directly in units of gravitational acceleration, angular velocity in degrees per second, or degrees Celsius. The last function returns <em>Pitch<\/em> and <em>Roll<\/em>, i.e., in short, the tilt around the Y and X axes with respect to the Earth. I have one note regarding temperature. In my opinion the MPU6050 slightly overestimates the readings by about 3\u20134\u00baC. However, I didn\u2019t modify the formula provided by the datasheet.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">int16_t MPU6050_GetTemperatureRAW(void);\nfloat MPU6050_GetTemperatureCelsius(void);\n\nint16_t MPU6050_GetAccelerationXRAW(void);\nint16_t MPU6050_GetAccelerationYRAW(void);\nint16_t MPU6050_GetAccelerationZRAW(void);\nvoid MPU6050_GetAccelerometerRAW(int16_t* x, int16_t* y, int16_t* z);\nvoid MPU6050_GetAccelerometerScaled(float* x, float* y, float* z);\n\nint16_t MPU6050_GetRotationXRAW(void);\nint16_t MPU6050_GetRotationYRAW(void);\nint16_t MPU6050_GetRotationZRAW(void);\nvoid MPU6050_GetGyroscopeRAW(int16_t* x, int16_t* y, int16_t* z);\nvoid MPU6050_GetGyroscopeScaled(float* x, float* y, float* z);\n\nvoid MPU6050_GetRollPitch(float* Roll, float* Pitch);<\/pre>\n\n\n\n<p>In the interrupt configuration section, a significant part is taken by functions concerning the INT pin. You can choose, for example, the level with which it signals an interrupt and how the interrupt flag is cleared. The accelerometer offers three interrupts as standard:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>FIFO overflow<\/li>\n\n\n\n<li>I\u00b2C Master interrupt<\/li>\n\n\n\n<li>Data ready for reading<\/li>\n<\/ul>\n\n\n\n<p>I haven\u2019t dealt with the FIFO for now. Same for the I\u00b2C Master function. The <em>DataReady<\/em> interrupt can be said to be almost always active because the accelerometer by default continuously generates data.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/\n\/\/ Setting INT pin\n\/\/\n\/\/ INT_PIN_CFG register\nvoid MPU6050_SetInterruptMode(uint8_t Mode);\nvoid MPU6050_SetInterruptDrive(uint8_t Drive);\nvoid MPU6050_SetInterruptLatch(uint8_t Latch);\nvoid MPU6050_SetInterruptLatchClear(uint8_t Clear);\n\/\/ INT_ENABLE register\nvoid MPU6050_SetIntEnableRegister(uint8_t Value);\nvoid MPU6050_SetIntDataReadyEnabled(uint8_t Enable);\n\/\/ INT_STATUS register\nuint8_t MPU6050_GetIntStatusRegister(void);<\/pre>\n\n\n\n<p>So what the heck do we need this interrupt for? Well, the <a href=\"https:\/\/sklep.msalamon.pl\/produkt\/mpu6050-modul\/?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=mpu6050&amp;utm_content=Text\">MPU6050<\/a> has a built\u2011in DMP which is not described in the sensor documentation nor in the register map. Probably because InvenSense provides its extensive driver for this purpose. The Internet, of course, never sleeps and has figured out a few things. Thanks to that we have easy access to basic motion processor functions.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Digital Motion Process<\/h2>\n\n\n\n<p>The DMP gives us three very useful interrupts. These are:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Free\u2011fall detection<\/li>\n\n\n\n<li>Motion detection<\/li>\n\n\n\n<li>No\u2011motion detection<\/li>\n<\/ul>\n\n\n\n<p>The chip can process the sensor data itself and assert the appropriate interrupt. I\u2019ve included all three in the library. There are also a few options around them to set.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/\n\/\/ Motion functions - not included in documentation\/register map\n\/\/\nuint8_t MPU6050_GetMotionStatusRegister(void);\n\nvoid MPU6050_SetDHPFMode(uint8_t Dhpf);\n\/\/ INT_ENABLE register\nvoid MPU6050_SetIntZeroMotionEnabled(uint8_t Enable);\nvoid MPU6050_SetIntMotionEnabled(uint8_t Enable);\nvoid MPU6050_SetIntFreeFallEnabled(uint8_t Enable);\n\nvoid MPU6050_SetMotionDetectionThreshold(uint8_t Threshold);\nvoid MPU6050_SetMotionDetectionDuration(uint8_t Duration);\n\nvoid MPU6050_SetZeroMotionDetectionThreshold(uint8_t Threshold);\nvoid MPU6050_SetZeroMotionDetectionDuration(uint8_t Duration);\n\nvoid MPU6050_SetFreeFallDetectionThreshold(uint8_t Threshold);\nvoid MPU6050_SetFreeFallDetectionDuration(uint8_t Duration);<\/pre>\n\n\n\n<p>The first function reads the status register responsible for detected motion. It contains information about which direction of motion triggered the <em>MotionDetect<\/em> interrupt. Maybe someone will find it useful. At the moment I don\u2019t see an application for it in my case.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/\n\/\/ Not documented\n\/\/ Register 91 - Motion Status\n\/\/\n#define MPU6050_MOTION_MOT_XNEG_BIT 7\n#define MPU6050_MOTION_MOT_XPOS_BIT 6\n#define MPU6050_MOTION_MOT_YNEG_BIT 5\n#define MPU6050_MOTION_MOT_YPOS_BIT 4\n#define MPU6050_MOTION_MOT_ZNEG_BIT 3\n#define MPU6050_MOTION_MOT_ZPOS_BIT 2<\/pre>\n\n\n\n<p>The second function sets the high\u2011pass filter for the DMP. I didn\u2019t notice any effect on the interrupts\u2019 behavior. Maybe someone knows more details about this filter? I recommend setting it to the value MPU6050_DHPF_5 as I did.<\/p>\n\n\n\n<p>And then there are the functions responsible for event detection. First, you can use them in two ways: with the INT pin, or without it by polling the interrupt status cyclically. I don\u2019t see a reason to poll the MPU for interrupt status. It\u2019s better to have this handled in hardware, which you enable with the appropriate functions.<\/p>\n\n\n\n<p>Next come the settings for the conditions under which an interrupt occurs. <em>Threshold<\/em> is the change in acceleration at which the internal counter starts counting. <em>Duration<\/em> is the value of that counter after which the interrupt will be asserted. If the acceleration value drops below the threshold before the interrupt, the counter resets.<\/p>\n\n\n\n<p>The threshold is expressed in mg (milli\u2011g), and the value written is multiplied by 2. The duration is in milliseconds. So by writing <em>Threshold = 2, Duration = 5<\/em> into the <em>MotionCapture<\/em> registers, the interrupt will occur 5 milliseconds after exceeding a 4 mg difference compared to the rest state. It may sound a bit complicated, so I recommend experimenting. I tested all the interrupts and they definitely work. A tap on the desk triggers the appropriate <em>Motion<\/em> and <em>ZeroMotion<\/em>.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_dmp_motions.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"809\" height=\"557\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_dmp_motions.jpg\" alt=\"\" class=\"wp-image-630\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_dmp_motions.jpg 809w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_dmp_motions-300x207.jpg 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_dmp_motions-768x529.jpg 768w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_dmp_motions-24x17.jpg 24w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_dmp_motions-36x25.jpg 36w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_dmp_motions-116x80.jpg 116w\" sizes=\"auto, (max-width: 809px) 100vw, 809px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<p>Dropping the sensor will generate the <em>Freefall<\/em> interrupt.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_dmp_freefall.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"809\" height=\"557\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_dmp_freefall.jpg\" alt=\"\" class=\"wp-image-629\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_dmp_freefall.jpg 809w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_dmp_freefall-300x207.jpg 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_dmp_freefall-768x529.jpg 768w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_dmp_freefall-24x17.jpg 24w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_dmp_freefall-36x25.jpg 36w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_dmp_freefall-116x80.jpg 116w\" sizes=\"auto, (max-width: 809px) 100vw, 809px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Gyroscope drift<\/h2>\n\n\n\n<p>Unfortunately, IMU chips, like everything in electronics, are imperfect. You can feel this most on the gyroscope. It has something called drift, i.e., it constantly indicates some value even though it\u2019s standing still. This can be seen in the terminal screenshot below.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_terminal.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"688\" height=\"441\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_terminal.jpg\" alt=\"\" class=\"wp-image-631\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_terminal.jpg 688w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_terminal-300x192.jpg 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_terminal-24x15.jpg 24w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_terminal-36x23.jpg 36w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/mpu6050_terminal-125x80.jpg 125w\" sizes=\"auto, (max-width: 688px) 100vw, 688px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<p><a href=\"https:\/\/sklep.msalamon.pl\/produkt\/mpu6050-modul\/?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=mpu6050&amp;utm_content=Text\">MPU6050<\/a> I have on my desk has quite a large drift on the X axis. From this it follows that in about 180 seconds it makes a full rotation around X. I\u2019ll tell you, I\u2019m looking at it and to me it\u2019s not spinning on this desk at all \ud83d\ude41<\/p>\n\n\n\n<p>One way to minimize this error is filtering. The most effective here is the Kalman filter, which will have a separate post.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Summary<\/h2>\n\n\n\n<p>MEMS systems are very interesting creations. Thanks to them you can easily bring \u201cmechanical quantities\u201d into the world of electronics and thus easily process them. Without accelerometers there would be no drones or VR glasses.<\/p>\n\n\n\n<p>Thanks to the built\u2011in DMP you can save many CPU cycles or even use interrupts for cool purposes. I see, for example, putting a smartwatch to sleep and waking it based on detected motion\/no\u2011motion. There are certainly many other applications for this kind of detection. Share your ideas in the comments.<\/p>\n\n\n\n<p>If you like the chip, you can buy it <a href=\"https:\/\/sklep.msalamon.pl\/produkt\/mpu6050-modul\/?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=mpu6050&amp;utm_content=Text\">in my store<\/a>.<\/p>\n\n\n\n<p>You can find the code on my GitHub as usual: <a href=\"https:\/\/github.com\/lamik\/MPU6050_STM32_HAL\" target=\"_blank\" rel=\"noopener\">link<\/a><\/p>\n\n\n\n<p><span>If you noticed any mistake, disagree with something, would like to add something important, or simply feel like discussing this topic, write a comment. Remember that the discussion should be polite and consistent with the rules of the Polish language.<\/span><\/p>\n\n\n<div class=\"kk-star-ratings kksr-auto kksr-align-left kksr-valign-bottom\"\n    data-payload='{&quot;align&quot;:&quot;left&quot;,&quot;id&quot;:&quot;4331&quot;,&quot;slug&quot;:&quot;default&quot;,&quot;valign&quot;:&quot;bottom&quot;,&quot;ignore&quot;:&quot;&quot;,&quot;reference&quot;:&quot;auto&quot;,&quot;class&quot;:&quot;&quot;,&quot;count&quot;:&quot;0&quot;,&quot;legendonly&quot;:&quot;&quot;,&quot;readonly&quot;:&quot;&quot;,&quot;score&quot;:&quot;0&quot;,&quot;starsonly&quot;:&quot;&quot;,&quot;best&quot;:&quot;5&quot;,&quot;gap&quot;:&quot;0&quot;,&quot;greet&quot;:&quot;&quot;,&quot;legend&quot;:&quot;0\\\/5 - (0 votes)&quot;,&quot;size&quot;:&quot;24&quot;,&quot;title&quot;:&quot;6 Degrees of Freedom with the MPU6050 on STM32&quot;,&quot;width&quot;:&quot;0&quot;,&quot;_legend&quot;:&quot;{score}\\\/{best} - ({count} {votes})&quot;,&quot;font_factor&quot;:&quot;1.25&quot;}'>\n            \n<div class=\"kksr-stars\">\n    \n<div class=\"kksr-stars-inactive\">\n            <div class=\"kksr-star\" data-star=\"1\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"2\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"3\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"4\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"5\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n    <\/div>\n    \n<div class=\"kksr-stars-active\" style=\"width: 0px;\">\n            <div class=\"kksr-star\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n    <\/div>\n<\/div>\n                \n\n<div class=\"kksr-legend\" style=\"font-size: 19.2px;\">\n            <span class=\"kksr-muted\"><\/span>\n    <\/div>\n    <\/div>\n","protected":false},"excerpt":{"rendered":"<p>I remember when the Nokia N95 hit the market, which was a huge technological leap. It had a built-in accelerometer thanks to which, among other things, the interface would change orientation by itself. Today this probably doesn\u2019t impress anyone anymore, but in 2007 an app with lightsaber sounds triggered by<\/p>\n","protected":false},"author":1,"featured_media":3132,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_links_to":"","_links_to_target":""},"categories":[160],"tags":[175,176,174,177],"class_list":["post-4331","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-stm32","tag-electronics","tag-programming","tag-stm32","tag-stm32cubemx"],"_links":{"self":[{"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/posts\/4331","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/comments?post=4331"}],"version-history":[{"count":3,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/posts\/4331\/revisions"}],"predecessor-version":[{"id":4438,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/posts\/4331\/revisions\/4438"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/media\/3132"}],"wp:attachment":[{"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/media?parent=4331"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/categories?post=4331"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/tags?post=4331"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}