├── LICENSE ├── Mpu6050.cpp ├── Mpu6050.h ├── README.md ├── Vector3f.cpp ├── Vector3f.h ├── circuit.png ├── examples ├── AccelerationWarning │ └── accelerationWarning.ino ├── ReadMeasurements │ └── readMeasurements.ino └── fullConfiguration │ └── readMeasurements.ino └── keywords.txt /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Thomas Havy 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Mpu6050.cpp: -------------------------------------------------------------------------------- 1 | /* ***************************************************************************** 2 | * Filename: Mpu6050.cpp 3 | * 4 | * Description: This is file contains the implementation of the Mpu6050 class. 5 | * All the information you need to understand how to communicate and setup the 6 | * chip can be found in the datasheet and register map from Invensense: 7 | * https://www.invensense.com/wp-content/uploads/2015/02/MPU-6000-Datasheet1.pdf 8 | * https://www.invensense.com/wp-content/uploads/2015/02/MPU-6000-Register-Map1.pdf 9 | * 10 | * Author: Thomas Havy 11 | * 12 | * License: MIT License - Copyright (c) 2017 Thomas Havy 13 | * A copy of the license can be found at: 14 | * https://github.com/Th-Havy/Simple-MPU6050-Arduino/blob/master/LICENSE 15 | * 16 | * Changes: 17 | * - Created: 07-Sept-2017 18 | * 19 | * ************************************************************************* */ 20 | 21 | #include "Mpu6050.h" 22 | 23 | // Selected Mpu6050 register addresses (found in the invensense datasheet) 24 | #define MPU6050_REGISTER_SMPRT_DIV 0x19 // Sample rate divider 25 | #define MPU6050_REGISTER_CONFIG 0x1A // DLPF config 26 | #define MPU6050_REGISTER_GYRO_CONFIG 0x1B 27 | #define MPU6050_REGISTER_ACCEL_CONFIG 0x1C 28 | #define MPU6050_REGISTER_ACCEL_XOUT_H 0x3B // Accelerometer measurement 29 | #define MPU6050_REGISTER_ACCEL_XOUT_L 0x3C 30 | #define MPU6050_REGISTER_ACCEL_YOUT_H 0x3D 31 | #define MPU6050_REGISTER_ACCEL_YOUT_L 0x3E 32 | #define MPU6050_REGISTER_ACCEL_ZOUT_H 0x3F 33 | #define MPU6050_REGISTER_ACCEL_ZOUT_L 0x40 34 | #define MPU6050_REGISTER_TEMP_OUT_H 0x41 // Temperature measurement 35 | #define MPU6050_REGISTER_TEMP_OUT_L 0x42 36 | #define MPU6050_REGISTER_GYRO_XOUT_H 0x43 // Gyroscope measurement 37 | #define MPU6050_REGISTER_GYRO_XOUT_L 0x44 38 | #define MPU6050_REGISTER_GYRO_YOUT_H 0x45 39 | #define MPU6050_REGISTER_GYRO_YOUT_L 0x46 40 | #define MPU6050_REGISTER_GYRO_ZOUT_H 0x47 41 | #define MPU6050_REGISTER_GYRO_ZOUT_L 0x48 42 | #define MPU6050_REGISTER_PWR_MGMT_1 0x6B // Power management 43 | #define MPU6050_REGISTER_WHO_AM_I 0x75 // Contains address of the device (0x68) 44 | 45 | // Default I2C address of the MPU6050 (0x69 if AD0 pin set to HIGH) 46 | #define MPU6050_DEFAULT_ADDRESS 0x68 47 | 48 | // Constant to convert raw temperature to Celsius degrees 49 | #define MPU6050_TEMP_LINEAR_COEF (1.0/340.00) 50 | #define MPU6050_TEMP_OFFSET 36.53 51 | 52 | // Constant to convert raw gyroscope to degree/s 53 | #define MPU6050_GYRO_FACTOR_250 (1.0/131.0) 54 | #define MPU6050_GYRO_FACTOR_500 (1.0/65.5) 55 | #define MPU6050_GYRO_FACTOR_1000 (1.0/32.8) 56 | #define MPU6050_GYRO_FACTOR_2000 (1.0/16.4) 57 | 58 | // Constant to convert raw acceleration to m/s^2 59 | #define GRAVITATIONAL_CONSTANT_G 9.81 60 | #define MPU6050_ACCEL_FACTOR_2 (GRAVITATIONAL_CONSTANT_G / 16384.0) 61 | #define MPU6050_ACCEL_FACTOR_4 (GRAVITATIONAL_CONSTANT_G / 8192.0) 62 | #define MPU6050_ACCEL_FACTOR_8 (GRAVITATIONAL_CONSTANT_G / 4096.0) 63 | #define MPU6050_ACCEL_FACTOR_16 (GRAVITATIONAL_CONSTANT_G / 2048.0) 64 | 65 | Mpu6050::Mpu6050(bool ad0 = LOW, TwoWire *bus = &Wire) : 66 | m_address(MPU6050_DEFAULT_ADDRESS + ad0), 67 | m_wire(bus), 68 | m_accelerometerRange(Max2g), 69 | m_gyroscopeRange(Max250Dps) 70 | { 71 | 72 | } 73 | 74 | bool Mpu6050::init(Mpu6050AccelerometerRange accelRange = Max2g, 75 | Mpu6050GyroscopeRange gyroRange = Max250Dps, 76 | Mpu6050DLPFBandwidth bandwidth = Max260Hz, 77 | byte SampleRateDivider = 7) 78 | { 79 | // Pull sensor out of sleep mode 80 | wakeUp(); 81 | 82 | // Test connection between the Arduino and the sensor 83 | if (!isConnected()) 84 | { 85 | return false; 86 | } 87 | 88 | // Reduce output rate of the sensor 89 | setSampleRateDivider(SampleRateDivider); 90 | 91 | setAccelerometerRange(accelRange); 92 | setGyroscopeRange(gyroRange); 93 | setDLPFBandwidth(bandwidth); 94 | 95 | return true; 96 | } 97 | 98 | Mpu6050Data Mpu6050::readData() 99 | { 100 | Mpu6050Data data; 101 | 102 | data.acceleration = readAcceleration(); 103 | data.gyroscope = readGyroscope(); 104 | data.temperature = readTemperature(); 105 | 106 | return data; 107 | } 108 | 109 | Vector3f Mpu6050::readAcceleration() 110 | { 111 | int16_t rawAccelX, rawAccelY, rawAccelZ; 112 | 113 | // Read 6 consecutive bytes (2 bytes per axis) 114 | m_wire->beginTransmission(m_address); 115 | m_wire->write(MPU6050_REGISTER_ACCEL_XOUT_H); 116 | m_wire->endTransmission(false); 117 | m_wire->requestFrom(m_address,6,true); 118 | 119 | // Each accel component is composed of 2 concatenated bytes 120 | rawAccelX = m_wire->read()<<8 | m_wire->read(); 121 | rawAccelY = m_wire->read()<<8 | m_wire->read(); 122 | rawAccelZ = m_wire->read()<<8 | m_wire->read(); 123 | 124 | // Convert each integer value to physical units 125 | Vector3f accel = Vector3f(); 126 | accel.x = rawAccelerationToMps2(rawAccelX); 127 | accel.y = rawAccelerationToMps2(rawAccelY); 128 | accel.z = rawAccelerationToMps2(rawAccelZ); 129 | 130 | return accel; 131 | } 132 | 133 | Vector3f Mpu6050::readGyroscope() 134 | { 135 | int16_t rawGyroX, rawGyroY, rawGyroZ; 136 | 137 | // Read 6 consecutive bytes (2 bytes per axis) 138 | m_wire->beginTransmission(m_address); 139 | m_wire->write(MPU6050_REGISTER_GYRO_XOUT_H); 140 | m_wire->endTransmission(false); 141 | m_wire->requestFrom(m_address,6,true); 142 | 143 | // Each gyro component is composed of 2 concatenated bytes 144 | rawGyroX = m_wire->read()<<8 | m_wire->read(); 145 | rawGyroY = m_wire->read()<<8 | m_wire->read(); 146 | rawGyroZ = m_wire->read()<<8 | m_wire->read(); 147 | 148 | // Convert each integer value to physical units 149 | Vector3f gyro = Vector3f(); 150 | gyro.x = rawGyroscopeToDps(rawGyroX); 151 | gyro.y = rawGyroscopeToDps(rawGyroY); 152 | gyro.z = rawGyroscopeToDps(rawGyroZ); 153 | 154 | return gyro; 155 | } 156 | 157 | float Mpu6050::readTemperature() 158 | { 159 | int16_t rawTemperature = read16(MPU6050_REGISTER_TEMP_OUT_H); 160 | 161 | return rawTemperatureToCelsius(rawTemperature); 162 | } 163 | 164 | void Mpu6050::setAccelerometerRange(Mpu6050AccelerometerRange range) 165 | { 166 | byte accelRange = static_cast(range) << 3; 167 | 168 | byte accelRangeRegister = read8(MPU6050_REGISTER_ACCEL_CONFIG); 169 | 170 | // Change only the range in the register 171 | accelRangeRegister = (accelRangeRegister & 0b11100111) | accelRange; 172 | 173 | write8(MPU6050_REGISTER_ACCEL_CONFIG, accelRangeRegister); 174 | 175 | m_accelerometerRange = range; 176 | } 177 | 178 | void Mpu6050::setGyroscopeRange(Mpu6050GyroscopeRange range) 179 | { 180 | byte gyroRange = static_cast(range) << 3; 181 | 182 | byte gyroRangeRegister = read8(MPU6050_REGISTER_GYRO_CONFIG); 183 | 184 | // Change only the range in the register 185 | gyroRangeRegister = (gyroRangeRegister & 0b11100111) | gyroRange; 186 | 187 | write8(MPU6050_REGISTER_GYRO_CONFIG, gyroRangeRegister); 188 | 189 | m_gyroscopeRange = range; 190 | } 191 | 192 | void Mpu6050::setDLPFBandwidth(Mpu6050DLPFBandwidth bandwidth) 193 | { 194 | byte band = static_cast(bandwidth); 195 | 196 | byte registerDLPF = read8(MPU6050_REGISTER_CONFIG); 197 | 198 | registerDLPF = (registerDLPF & 0b11111000) | band; // change only bandwidth 199 | 200 | write8(MPU6050_REGISTER_CONFIG, registerDLPF); 201 | } 202 | 203 | void Mpu6050::setSampleRateDivider(byte divider) 204 | { 205 | write8(MPU6050_REGISTER_SMPRT_DIV, divider); 206 | } 207 | 208 | Mpu6050AccelerometerRange Mpu6050::getAccelerometerRange() 209 | { 210 | return m_accelerometerRange; 211 | } 212 | 213 | Mpu6050GyroscopeRange Mpu6050::getGyroscopeRange() 214 | { 215 | return m_gyroscopeRange; 216 | } 217 | 218 | Mpu6050DLPFBandwidth Mpu6050::getDLPFBandwidth() 219 | { 220 | byte registerDLPF = read8(MPU6050_REGISTER_CONFIG); 221 | registerDLPF &= 0b00000111; // Keep only the value of DLPF_CFG 222 | 223 | return static_cast(registerDLPF); 224 | } 225 | 226 | byte Mpu6050::getSampleRateDivider() 227 | { 228 | return read8(MPU6050_REGISTER_SMPRT_DIV); 229 | } 230 | 231 | void Mpu6050::reset() 232 | { 233 | write8(MPU6050_REGISTER_PWR_MGMT_1, 0b10000000); 234 | } 235 | 236 | bool Mpu6050::isConnected() 237 | { 238 | // The content of WHO_AM_I is always 0x68, so if the wiring is right and 239 | // the I2C communication works fine this function should return true 240 | return read8(MPU6050_REGISTER_WHO_AM_I) == MPU6050_DEFAULT_ADDRESS; 241 | } 242 | 243 | void Mpu6050::sleepMode() 244 | { 245 | write8(MPU6050_REGISTER_PWR_MGMT_1, 0b01000000); 246 | } 247 | 248 | void Mpu6050::wakeUp() 249 | { 250 | write8(MPU6050_REGISTER_PWR_MGMT_1, 0b00000000); 251 | } 252 | 253 | void Mpu6050::set_ad0(bool ad0) 254 | { 255 | m_address = MPU6050_DEFAULT_ADDRESS + ad0; 256 | } 257 | 258 | bool Mpu6050::get_ad0() 259 | { 260 | if (m_address == MPU6050_DEFAULT_ADDRESS) 261 | { 262 | return false; 263 | } 264 | else 265 | { 266 | return true; 267 | } 268 | } 269 | 270 | void Mpu6050::setBus(TwoWire *bus) 271 | { 272 | m_wire = bus; 273 | } 274 | 275 | TwoWire* Mpu6050::getBus() 276 | { 277 | return m_wire; 278 | } 279 | 280 | float Mpu6050::rawTemperatureToCelsius(int16_t rawTemperature) 281 | { 282 | return rawTemperature * MPU6050_TEMP_LINEAR_COEF + MPU6050_TEMP_OFFSET; 283 | } 284 | 285 | float Mpu6050::rawGyroscopeToDps(int16_t rawGyroscope) 286 | { 287 | switch (m_gyroscopeRange) 288 | { 289 | case Max250Dps: 290 | return rawGyroscope * MPU6050_GYRO_FACTOR_250; 291 | break; 292 | case Max500Dps: 293 | return rawGyroscope * MPU6050_GYRO_FACTOR_500; 294 | break; 295 | case Max1000Dps: 296 | return rawGyroscope * MPU6050_GYRO_FACTOR_1000; 297 | break; 298 | case Max2000Dps: 299 | return rawGyroscope * MPU6050_GYRO_FACTOR_2000; 300 | break; 301 | default: 302 | break; 303 | } 304 | } 305 | 306 | float Mpu6050::rawAccelerationToMps2(int16_t rawAcceleration) 307 | { 308 | switch (m_accelerometerRange) 309 | { 310 | case Max2g: 311 | return rawAcceleration * MPU6050_ACCEL_FACTOR_2; 312 | break; 313 | case Max4g: 314 | return rawAcceleration * MPU6050_ACCEL_FACTOR_4; 315 | break; 316 | case Max8g: 317 | return rawAcceleration * MPU6050_ACCEL_FACTOR_8; 318 | break; 319 | case Max16g: 320 | return rawAcceleration * MPU6050_ACCEL_FACTOR_16; 321 | break; 322 | default: 323 | break; 324 | } 325 | } 326 | 327 | // Read one register 328 | byte Mpu6050::read8(byte registerAddr) 329 | { 330 | m_wire->beginTransmission(m_address); 331 | m_wire->write(registerAddr); 332 | m_wire->endTransmission(false); 333 | m_wire->requestFrom(m_address,1,true); 334 | 335 | return m_wire->read(); 336 | } 337 | 338 | // read a value contained in two consecutive registers 339 | int16_t Mpu6050::read16(byte registerAddr) 340 | { 341 | m_wire->beginTransmission(m_address); 342 | m_wire->write(registerAddr); 343 | m_wire->endTransmission(false); 344 | m_wire->requestFrom(m_address,2,true); 345 | 346 | // Concatenate the two bytes 347 | return m_wire->read()<<8 | m_wire->read(); 348 | } 349 | 350 | // write one register 351 | byte Mpu6050::write8(byte registerAddr, byte value) 352 | { 353 | m_wire->beginTransmission(m_address); 354 | m_wire->write(registerAddr); 355 | m_wire->write(value); 356 | m_wire->endTransmission(true); 357 | } 358 | -------------------------------------------------------------------------------- /Mpu6050.h: -------------------------------------------------------------------------------- 1 | /* ***************************************************************************** 2 | * Filename: Mpu6050.h 3 | * 4 | * Description: This is file contains the definition of the Mpu6050 class, that 5 | * is used to configure and read data from the eponymous sensor. 6 | * Each instance of this class represents a different sensor that has an I2C 7 | * address 0x68 or 0x69 if the AD0 pin is connected to logic 1 (3.3V). 8 | * The Mpu6050Data struct is also defined here and has 3 member variables for 9 | * each type of measurement (accel,gyro,temp). 10 | * A set of useful enumerations is defined for configuring the sensor in a more 11 | * readable way. 12 | * 13 | * Author: Thomas Havy 14 | * 15 | * License: MIT License - Copyright (c) 2017 Thomas Havy 16 | * A copy of the license can be found at: 17 | * https://github.com/Th-Havy/Simple-MPU6050-Arduino/blob/master/LICENSE 18 | * 19 | * Changes: 20 | * - Created: 07-Sept-2017 21 | * 22 | * ************************************************************************* */ 23 | 24 | #ifndef MPU6050_H 25 | #define MPU6050_H 26 | 27 | #include 28 | #include 29 | #include "Vector3f.h" 30 | 31 | struct Mpu6050Data 32 | { 33 | public: 34 | Vector3f acceleration; // m/s^2 35 | Vector3f gyroscope; // degree/s 36 | float temperature; // Celsius degrees 37 | }; 38 | 39 | // Used to select the gyroscope measurement range. 40 | // Always select the smallest possible range for precision. 41 | enum Mpu6050GyroscopeRange 42 | { 43 | Max250Dps, // +/- 250 degree per second of rotational speed 44 | Max500Dps, 45 | Max1000Dps, 46 | Max2000Dps 47 | }; 48 | 49 | // Used to select the accelerometer measurement range. 50 | // Always select the smallest possible range for precision. 51 | enum Mpu6050AccelerometerRange 52 | { 53 | Max2g, // +/- 2g (19.6 m/s^2) of acceleration 54 | Max4g, 55 | Max8g, 56 | Max16g 57 | }; 58 | 59 | // Used to configure the internal Digital Low Pass Filter (DLPF) 60 | // The DLPF will average the measurement which is useful for slow varying 61 | // motion, as it removes high frequency components (such as vibrations) 62 | enum Mpu6050DLPFBandwidth 63 | { 64 | Max260Hz, // 260 measurements per second 65 | Max184Hz, 66 | Max94Hz, 67 | Max44Hz, 68 | Max21Hz, 69 | Max10Hz, 70 | Max5Hz 71 | }; 72 | 73 | class Mpu6050 74 | { 75 | public: 76 | // Specify AD0 pin level and I2C bus when instantiating a device 77 | Mpu6050(bool ad0 = LOW, TwoWire *bus = &Wire); 78 | 79 | // Initialize the device before reading data 80 | bool init(Mpu6050AccelerometerRange accelRange = Max2g, 81 | Mpu6050GyroscopeRange gyroRange = Max250Dps, 82 | Mpu6050DLPFBandwidth bandwidth = Max260Hz, 83 | byte SampleRateDivider = 7); 84 | 85 | // Methods to read measurements 86 | Mpu6050Data readData(); 87 | Vector3f readAcceleration(); 88 | Vector3f readGyroscope(); 89 | float readTemperature(); 90 | 91 | // Configuration of the sensors 92 | void setAccelerometerRange(Mpu6050AccelerometerRange range); 93 | void setGyroscopeRange(Mpu6050GyroscopeRange range); 94 | void setDLPFBandwidth(Mpu6050DLPFBandwidth bandwidth); 95 | void setSampleRateDivider(byte divider); // sample rate = 8kHz / (1 + divider) 96 | 97 | Mpu6050AccelerometerRange getAccelerometerRange(); 98 | Mpu6050GyroscopeRange getGyroscopeRange(); 99 | Mpu6050DLPFBandwidth getDLPFBandwidth(); 100 | byte getSampleRateDivider(); 101 | 102 | // Resets the registers to their default value (init() should be called 103 | // after a reset to use again the device) 104 | void reset(); 105 | 106 | // Return true if the connection is established with the MPU6050 107 | bool isConnected(); 108 | 109 | // Set sensor in sleep mode (power saving mode, no data measurements) 110 | void sleepMode(); 111 | void wakeUp(); 112 | 113 | void set_ad0(bool ad0); 114 | bool get_ad0(); 115 | 116 | // Change the I2C bus (there is only one on the Arduino uno) 117 | void setBus(TwoWire* bus); 118 | TwoWire* getBus(); 119 | 120 | private: 121 | byte m_address; 122 | Mpu6050AccelerometerRange m_accelerometerRange; 123 | Mpu6050GyroscopeRange m_gyroscopeRange; 124 | 125 | // Allow the use of devices on different I2C buses 126 | TwoWire *m_wire; 127 | 128 | // Raw data to real-world units 129 | float rawTemperatureToCelsius(int16_t rawTemperature); 130 | float rawGyroscopeToDps(int16_t rawGyroscope); // degree/s 131 | float rawAccelerationToMps2(int16_t rawAcceleration); // m/s^2 132 | 133 | // For convenience: 134 | byte Mpu6050::read8(byte registerAddr); 135 | int16_t Mpu6050::read16(byte registerAddr); 136 | byte Mpu6050::write8(byte registerAddr, byte value); 137 | }; 138 | 139 | #endif // MPU6050_H 140 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Simple-MPU6050-Arduino 2 | This is a simple Arduino library for using the MPU6050 accelerometer & gyroscope sensor from invensense. It allows to easily read the acceleration, gyroscope (angular speed) and temperature measurements directly as a float value in physical units. 3 | 4 | ## Features 5 | 6 | This library is meant as a starting base when using the MPU6050 sensor. It is meant to be simple and easy to use, as part of an arduino project. In particular, the library does not implement or make use of all the features of the chip (such as the FIFO buffer, Digital Motion Processor), and the code is not optimized for any board. 7 | 8 | The Mpu6050 class represents a sensor (more than one sensor can be used) and can be used to configure it and read measurements. 9 | The technical aspects of understanding how to use the chip are hidden behind a simple interface: the user can read the measurements in real-world units without having to go through all the database to find how to convert a raw 16-bit integer to °/s, etc... 10 | 11 | The Mpu6050Data represents the data measured by the sensor: acceleration (Vector3f), gyroscope (Vector3f), temperature (float) 12 | 13 | A Vector3f class is used by the two previous classes; it is a simple class to represent a 3D vector with 3 float components. It has some useful methods such as magnitude and dot product, and some operator have been overloaded (+,-,/,...) to make vector computations easier to read. 14 | 15 | Here's a list of some of the supported features: 16 | - Read measurements in physical units (gyro:°/s, accel:m/s^2, temp:°C) 17 | - Gyroscope and accelerometer configuration (selecting the range of measurements) 18 | - Digital Low Pass Filter (DLPF) configuration 19 | - Multiple sensors (up to 2 sensors on the same I2C bus, support of multiple I2C buses) 20 | - Enter and Exit sleep mode (power saving mode) 21 | 22 | Here's a list of some features NOT supported (on purpose): 23 | - Interrupts 24 | - FIFO buffer 25 | - Digital Motion Processor (DMP) 26 | 27 | ## Getting Started 28 | 29 | You will first need to install the Arduino IDE if you haven't already, and of course you will need a MPU6050 (for example, the GY-521 board that is a minimal board for this sensor can be bought for 2-3$). 30 | 31 | ### Installing 32 | 33 | Copy the [Simple-MPU6050-Arduino](https://github.com/Th-Havy/Simple-MPU6050-Arduino) folder to your Arduino libraries folder (located where you installed the Arduino IDE, for ex: C:\Program Files (x86)\Arduino\libraries). 34 | 35 | ### Schematic 36 | 37 | Connect the GY-521 board (or any equivalent MPU6050 powered board) to your Arduino board as follows: 38 | 39 | | Arduino | MPU6050 board | 40 | | ------- | ------------- | 41 | | 3.3V | Vcc | 42 | | GND | GND | 43 | | SCL | A5 | 44 | | SDA | A4 | 45 | 46 | Note that the MPU6050 chip itself is not 5V tolerant, but some board like the GY-521 include a voltage converter to be able to connect it to 5V. If you don't know which voltage to choose it's safer to use 3.3V in order not to destroy the sensor. 47 | 48 | ![basic ciruit image](circuit.png) 49 | 50 | ### Running an example 51 | 52 | Restart the arduino IDE and select an example: File > Examples > Simple-MPU6050-Arduino. 53 | 54 | ## Authors 55 | 56 | * **Thomas Havy** 57 | 58 | ## License 59 | 60 | This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details 61 | 62 | ## Acknowledgments 63 | 64 | * The invensense datasheet for the MPU6050 is useful if you wish to understand the implementation of the methods. Here is the [Datasheet](https://www.invensense.com/wp-content/uploads/2015/02/MPU-6000-Datasheet1.pdf) and even more importantly the [Register Map](https://www.invensense.com/wp-content/uploads/2015/02/MPU-6000-Register-Map1.pdf). 65 | * If you want a more in-depth use of the MPU6050 you can use Jeff Rowberg's [library](https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/MPU6050) which is much more advanced. 66 | -------------------------------------------------------------------------------- /Vector3f.cpp: -------------------------------------------------------------------------------- 1 | /* ***************************************************************************** 2 | * Filename: Vector3f.h 3 | * 4 | * Description: Implementation the Vector3f class. 5 | * 6 | * Author: Thomas Havy 7 | * 8 | * License: MIT License - Copyright (c) 2017 Thomas Havy 9 | * A copy of the license can be found at: 10 | * https://github.com/Th-Havy/Simple-MPU6050-Arduino/blob/master/LICENSE 11 | * 12 | * Changes: 13 | * - Created: 07-Sept-2017 14 | * 15 | * ************************************************************************* */ 16 | 17 | #include "Vector3f.h" 18 | #include 19 | 20 | Vector3f::Vector3f(float X, float Y, float Z) 21 | { 22 | x = X; 23 | y = Y; 24 | z = Z; 25 | } 26 | 27 | float Vector3f::magnitude(void) const 28 | { 29 | return sqrt(x*x + y*y + z*z); 30 | } 31 | 32 | void Vector3f::normalize(void) 33 | { 34 | *this /= magnitude(); 35 | } 36 | 37 | float Vector3f::dotProduct(const Vector3f& a, const Vector3f& b) 38 | { 39 | return a.x*b.x + a.y*b.y + a.z*b.z; 40 | } 41 | 42 | Vector3f Vector3f::crossProduct(const Vector3f& a, const Vector3f& b) 43 | { 44 | Vector3f c; 45 | 46 | c.x = a.y*b.z - b.y*a.z; 47 | c.y = a.z*b.x - b.z*a.x; 48 | c.z = a.x*b.y - b.x*a.y; 49 | 50 | return c; 51 | } 52 | 53 | Vector3f Vector3f::operator-() const 54 | { 55 | Vector3f a; 56 | a.x = -x; 57 | a.y = -y; 58 | a.z = -z; 59 | 60 | return a; 61 | } 62 | 63 | Vector3f& Vector3f::operator+=(const Vector3f& right) 64 | { 65 | x += right.x; 66 | y += right.x; 67 | z += right.x; 68 | 69 | return *this; 70 | } 71 | 72 | Vector3f& Vector3f::operator-=(const Vector3f& right) 73 | { 74 | *this += -right; 75 | 76 | return *this; 77 | } 78 | 79 | Vector3f& Vector3f::operator*=(const float &a) 80 | { 81 | x *= a; 82 | y *= a; 83 | z *= a; 84 | 85 | return *this; 86 | } 87 | 88 | Vector3f& Vector3f::operator/=(const float &a) 89 | { 90 | return *this *= (1/a); 91 | } 92 | 93 | bool operator==(const Vector3f& a, const Vector3f& b) 94 | { 95 | return a.x == b.x && a.y == b.y && a.z == b.z; 96 | } 97 | 98 | bool operator!=(const Vector3f& a, const Vector3f& b) 99 | { 100 | return !(a == b); 101 | } 102 | 103 | Vector3f operator+(const Vector3f& a, const Vector3f& b) 104 | { 105 | Vector3f c(a); 106 | 107 | c += b; 108 | 109 | return c; 110 | } 111 | 112 | Vector3f operator-(const Vector3f& a, const Vector3f& b) 113 | { 114 | Vector3f c(a); 115 | 116 | c -= b; 117 | 118 | return c; 119 | } 120 | -------------------------------------------------------------------------------- /Vector3f.h: -------------------------------------------------------------------------------- 1 | // File: Vector3f.h 2 | // Author: Thomas Havy 3 | // Description: Simple utility class for 3D vectors and operations 4 | 5 | #ifndef VECTOR3F_H 6 | #define VECTOR3F_H 7 | 8 | 9 | class Vector3f 10 | { 11 | public: 12 | float x,y,z; 13 | 14 | Vector3f(float X=0, float Y=0, float Z=0); 15 | 16 | float magnitude(void) const; 17 | void normalize(void); 18 | 19 | static float dotProduct(const Vector3f& a, const Vector3f& b); 20 | static Vector3f crossProduct(const Vector3f& a, const Vector3f& b); 21 | 22 | Vector3f operator-() const; 23 | Vector3f& operator+=(const Vector3f& right); 24 | Vector3f& operator-=(const Vector3f& right); 25 | Vector3f& operator*=(const float& a); 26 | Vector3f& operator/=(const float& a); 27 | 28 | friend bool operator==(const Vector3f& a, const Vector3f& b); 29 | friend bool operator!=(const Vector3f& a, const Vector3f& b); 30 | friend Vector3f operator+(const Vector3f& a, const Vector3f& b); 31 | friend Vector3f operator-(const Vector3f& a, const Vector3f& b); 32 | }; 33 | 34 | #endif // VECTOR3F_H 35 | -------------------------------------------------------------------------------- /circuit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Th-Havy/Simple-MPU6050-Arduino/eeea77a9d93c54b8e2fe9ba83062537cf19c850e/circuit.png -------------------------------------------------------------------------------- /examples/AccelerationWarning/accelerationWarning.ino: -------------------------------------------------------------------------------- 1 | /* ***************************************************************************** 2 | * Filename: readMeasurements.ino 3 | * 4 | * Description: This is a simple example for the Simple-MPU6050-Arduino library. 5 | * The acceleration is read over and over, and the built-in LED is turned on 6 | * whenever the acceleration is "strong". 7 | * 8 | * Author: Thomas Havy 9 | * 10 | * License: MIT License - Copyright (c) 2017 Thomas Havy 11 | * A copy of the license can be found at: 12 | * https://github.com/Th-Havy/Simple-MPU6050-Arduino/blob/master/LICENSE 13 | * 14 | * Changes: 15 | * - Created: 10-Sept-2017 16 | * 17 | * ************************************************************************* */ 18 | 19 | // Include the library 20 | #include 21 | 22 | // Global variables 23 | Mpu6050 sensor; 24 | Vector3f accel; 25 | 26 | void setup() 27 | { 28 | Serial.begin(9600); 29 | 30 | pinMode(LED_BUILTIN, OUTPUT); 31 | 32 | // Add sensor and then initialize it 33 | sensor = Mpu6050(); 34 | 35 | if (sensor.init()) 36 | { 37 | Serial.println("Mpu6050 Connected!"); 38 | } 39 | else 40 | { 41 | Serial.println("Failed to connect to Mpu6050."); 42 | } 43 | } 44 | 45 | void loop() 46 | { 47 | // Collect the current sensor measurement 48 | accel = sensor.readAcceleration(); 49 | 50 | // Turn on LED if the acceleration is intense 51 | if (accel.magnitude() > 15.0) 52 | { 53 | digitalWrite(LED_BUILTIN, HIGH); 54 | } 55 | else 56 | { 57 | digitalWrite(LED_BUILTIN, LOW); 58 | } 59 | } 60 | 61 | -------------------------------------------------------------------------------- /examples/ReadMeasurements/readMeasurements.ino: -------------------------------------------------------------------------------- 1 | /* ***************************************************************************** 2 | * Filename: readMeasurements.ino 3 | * 4 | * Description: This is a simple example for the Simple-MPU6050-Arduino library. 5 | * It shows how to setup the sensor and how to read the acceleration, gyroscope 6 | * and temperature measurements. Each second, all these values are sent to the 7 | * Serial port, and can be displyed in the Serial monitor: in the Arduino IDE, 8 | * go to Tools > Serial Monitor (Ctrl+Maj+m). 9 | * 10 | * Author: Thomas Havy 11 | * 12 | * License: MIT License - Copyright (c) 2017 Thomas Havy 13 | * A copy of the license can be found at: 14 | * https://github.com/Th-Havy/Simple-MPU6050-Arduino/blob/master/LICENSE 15 | * 16 | * Changes: 17 | * - Created: 10-Sept-2017 18 | * 19 | * ************************************************************************* */ 20 | 21 | // Include the library 22 | #include 23 | 24 | // Global variables 25 | Mpu6050 sensor; 26 | Mpu6050Data data; 27 | 28 | void setup() 29 | { 30 | Serial.begin(9600); 31 | 32 | // Add sensor and then initialize it 33 | sensor = Mpu6050(); 34 | 35 | if (sensor.init()) 36 | { 37 | Serial.println("Mpu6050 Connected!"); 38 | } 39 | else 40 | { 41 | Serial.println("Failed to connect to Mpu6050."); 42 | } 43 | } 44 | 45 | void loop() 46 | { 47 | // Collect the current sensor measurements 48 | data = sensor.readData(); 49 | 50 | // 51 | Serial.println("---------------------------------------"); 52 | Serial.print("Acceleration (m/s^2): X="); Serial.print(data.acceleration.x); Serial.print(" Y="); Serial.print(data.acceleration.y); Serial.print(" Z="); Serial.println(data.acceleration.z); 53 | Serial.print("Gyroscope (°/s): X="); Serial.print(data.gyroscope.x); Serial.print(" Y="); Serial.print(data.gyroscope.y); Serial.print(" Z="); Serial.println(data.gyroscope.z); 54 | Serial.print("Temperature (°C): "); Serial.println(data.temperature); 55 | 56 | delay(1000); 57 | } 58 | 59 | -------------------------------------------------------------------------------- /examples/fullConfiguration/readMeasurements.ino: -------------------------------------------------------------------------------- 1 | /* ***************************************************************************** 2 | * Filename: fullConfiguration.ino 3 | * 4 | * Description: This is a simple example for the Simple-MPU6050-Arduino library. 5 | * It shows how to fully configure the sensors. 6 | * 7 | * Author: Thomas Havy 8 | * 9 | * License: MIT License - Copyright (c) 2017 Thomas Havy 10 | * A copy of the license can be found at: 11 | * https://github.com/Th-Havy/Simple-MPU6050-Arduino/blob/master/LICENSE 12 | * 13 | * Changes: 14 | * - Created: 10-Sept-2017 15 | * 16 | * ************************************************************************* */ 17 | 18 | // Include the library 19 | #include 20 | 21 | // Constants 22 | const bool ad0 = LOW; // AD0 pin 23 | 24 | // Global variables 25 | Mpu6050 sensor; 26 | Mpu6050Data data; 27 | 28 | void setup() 29 | { 30 | Serial.begin(9600); 31 | 32 | // Add sensor, specifying ad0 and the I2C bus used 33 | sensor = Mpu6050(ad0, &Wire); 34 | 35 | /* Initialise the sensor specifying all options: 36 | * 37 | * Acceleration range: how much acceleration can be measured, 38 | * can be +/-2g,4g,8g,16g (use the constans Max2g,Max4g,etc...) 39 | * You should use the lowest possible range for your need, because 40 | * you then get more precision on the measurement, but any 41 | * acceleration greater than the range will be incorrectly 42 | * measured. 43 | * 44 | * Gyroscope range: how much rotationnal speed can be measured, 45 | * can be +/-250 °/s,500,1000,2000 (use the constans Max250Dps, 46 | * Max500Dps,etc...). 47 | * You should use the lowest possible range for your need,for 48 | * the same reasons as the acceleration range. 49 | * 50 | * Digital Low Pass Filter (DLPF): this parameter can be use to 51 | * enable the DLPF, which will (I'm simplifying) average the 52 | * measurements on a short time (microseconds to milliseconds) 53 | * leading to less "jittery" measurements. However, this limits 54 | * the number of sample readable per second. Use the constants 55 | * Max260Hz, Max184Hz, Max94Hz, Max44Hz, Max21Hz, Max10Hz, 56 | * Max5Hz (number of different samples per second). 57 | * 58 | * Sample Rate Divider: Change the number of sample per second 59 | * sample rate = 8kHz / (1 + divider), I recommand leaving it 60 | * with a value of 7 unless you need to synchronize the output 61 | * rate of the sensor for some reason. 62 | 63 | */ 64 | 65 | if (sensor.init(Max4g, Max500Dps, Max184Hz, 7)) 66 | { 67 | Serial.println("Mpu6050 Connected!"); 68 | } 69 | else 70 | { 71 | Serial.println("Failed to connect to Mpu6050."); 72 | } 73 | } 74 | 75 | void loop() 76 | { 77 | // Collect the current sensor measurements 78 | data = sensor.readData(); 79 | 80 | // Print data 81 | Serial.println("---------------------------------------"); 82 | Serial.print("Acceleration (m/s^2): X="); Serial.print(data.acceleration.x); Serial.print(" Y="); Serial.print(data.acceleration.y); Serial.print(" Z="); Serial.println(data.acceleration.z); 83 | Serial.print("Gyroscope (°/s): X="); Serial.print(data.gyroscope.x); Serial.print(" Y="); Serial.print(data.gyroscope.y); Serial.print(" Z="); Serial.println(data.gyroscope.z); 84 | Serial.print("Temperature (°C): "); Serial.println(data.temperature); 85 | 86 | delay(1000); 87 | } 88 | 89 | -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For Mpu6050 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | Mpu6050 KEYWORD1 10 | Mpu6050Data KEYWORD1 11 | Vector3f KEYWORD1 12 | 13 | ####################################### 14 | # Methods and Functions (KEYWORD2) 15 | ####################################### 16 | 17 | init KEYWORD2 18 | reset KEYWORD2 19 | isConnected KEYWORD2 20 | readData KEYWORD2 21 | readAcceleration KEYWORD2 22 | readGyroscope KEYWORD2 23 | readTemperature KEYWORD2 24 | 25 | ####################################### 26 | # Instances (KEYWORD2) 27 | ####################################### 28 | 29 | ####################################### 30 | # Constants (LITERAL1) 31 | ####################################### --------------------------------------------------------------------------------