Overview of MPU6050 sensor module
The MPU6050 sensor module is an integrated 6-axis Motion tracking device.
- It has a 3-axis Gyroscope, 3-axis Accelerometer, Digital Motion Processor, and a Temperature sensor, all in a single IC.
- It can accept inputs from other sensors like a 3-axis magnetometer or pressure sensor using its Auxiliary I2C bus.
- If the external 3-axis magnetometer is connected, it can provide complete 9-axis Motion Fusion output.
Gyroscope and accelerometer reading along X, Y, and Z axes are available in 2’s complement form.
The temperature reading is available in a signed integer form (not in 2’s complement form).
Gyroscope readings are in degrees per second (DPS) unit; Accelerometer readings are in g unit, and Temperature reading is in degrees Celsius.
For more information about the MPU6050 Sensor Module and how to use it, refer to the topic MPU6050 Sensor Module in the sensors and modules section.
A NodeMCU can communicate with this module using the I2C communication protocol. To know more about I2C functions in NodeMCU refer to NodeMCU I2C with ESPlorer IDE or NodeMCU I2C with Arduino IDE
Connection Diagram of MPU6050 with NodeMCU
Read MPU6050 using NodeMCU
Reading Accelerometer, Gyroscope, and Temperature parameters from the MPU6050 module and displaying them on the Serial Monitor.
First, do the connections as shown in the above interfacing diagram.
Now let’s write a program for reading accelerator, gyro, and temperature values from MPU6050.
We can write codes for NodeMCU DevKit in either Lua Script or C/C++ language. We are using ESPlorer IDE for writing code in Lua scripts and Arduino IDE for writing code in C/C++. To know more refer to Getting started with NodeMCU using ESPlorer IDE (which uses Lua scripting for NodeMCU) and Getting started with NodeMCU using Arduino IDE (which uses C/C++ language based Arduino sketches for NodeMCU).
Lua Script for NodeMCU
id = 0 -- always 0
scl = 6 -- set pin 6 as scl
sda = 7 -- set pin 7 as sda
MPU6050SlaveAddress = 0x68
AccelScaleFactor = 16384; -- sensitivity scale factor respective to full scale setting provided in datasheet
GyroScaleFactor = 131;
MPU6050_REGISTER_SMPLRT_DIV = 0x19
MPU6050_REGISTER_USER_CTRL = 0x6A
MPU6050_REGISTER_PWR_MGMT_1 = 0x6B
MPU6050_REGISTER_PWR_MGMT_2 = 0x6C
MPU6050_REGISTER_CONFIG = 0x1A
MPU6050_REGISTER_GYRO_CONFIG = 0x1B
MPU6050_REGISTER_ACCEL_CONFIG = 0x1C
MPU6050_REGISTER_FIFO_EN = 0x23
MPU6050_REGISTER_INT_ENABLE = 0x38
MPU6050_REGISTER_ACCEL_XOUT_H = 0x3B
MPU6050_REGISTER_SIGNAL_PATH_RESET = 0x68
function I2C_Write(deviceAddress, regAddress, data)
i2c.start(id) -- send start condition
if (i2c.address(id, deviceAddress, i2c.TRANSMITTER))-- set slave address and transmit direction
then
i2c.write(id, regAddress) -- write address to slave
i2c.write(id, data) -- write data to slave
i2c.stop(id) -- send stop condition
else
print("I2C_Write fails")
end
end
function I2C_Read(deviceAddress, regAddress, SizeOfDataToRead)
response = 0;
i2c.start(id) -- send start condition
if (i2c.address(id, deviceAddress, i2c.TRANSMITTER))-- set slave address and transmit direction
then
i2c.write(id, regAddress) -- write address to slave
i2c.stop(id) -- send stop condition
i2c.start(id) -- send start condition
i2c.address(id, deviceAddress, i2c.RECEIVER)-- set slave address and receive direction
response = i2c.read(id, SizeOfDataToRead) -- read defined length response from slave
i2c.stop(id) -- send stop condition
return response
else
print("I2C_Read fails")
end
return response
end
function unsignTosigned16bit(num) -- convert unsigned 16-bit no. to signed 16-bit no.
if num > 32768 then
num = num - 65536
end
return num
end
function MPU6050_Init() --configure MPU6050
tmr.delay(150000)
I2C_Write(MPU6050SlaveAddress, MPU6050_REGISTER_SMPLRT_DIV, 0x07)
I2C_Write(MPU6050SlaveAddress, MPU6050_REGISTER_PWR_MGMT_1, 0x01)
I2C_Write(MPU6050SlaveAddress, MPU6050_REGISTER_PWR_MGMT_2, 0x00)
I2C_Write(MPU6050SlaveAddress, MPU6050_REGISTER_CONFIG, 0x00)
I2C_Write(MPU6050SlaveAddress, MPU6050_REGISTER_GYRO_CONFIG, 0x00)-- set +/-250 degree/second full scale
I2C_Write(MPU6050SlaveAddress, MPU6050_REGISTER_ACCEL_CONFIG, 0x00)-- set +/- 2g full scale
I2C_Write(MPU6050SlaveAddress, MPU6050_REGISTER_FIFO_EN, 0x00)
I2C_Write(MPU6050SlaveAddress, MPU6050_REGISTER_INT_ENABLE, 0x01)
I2C_Write(MPU6050SlaveAddress, MPU6050_REGISTER_SIGNAL_PATH_RESET, 0x00)
I2C_Write(MPU6050SlaveAddress, MPU6050_REGISTER_USER_CTRL, 0x00)
end
i2c.setup(id, sda, scl, i2c.SLOW) -- initialize i2c
MPU6050_Init()
while true do --read and print accelero, gyro and temperature value
data = I2C_Read(MPU6050SlaveAddress, MPU6050_REGISTER_ACCEL_XOUT_H, 14)
AccelX = unsignTosigned16bit((bit.bor(bit.lshift(string.byte(data, 1), 8), string.byte(data, 2))))
AccelY = unsignTosigned16bit((bit.bor(bit.lshift(string.byte(data, 3), 8), string.byte(data, 4))))
AccelZ = unsignTosigned16bit((bit.bor(bit.lshift(string.byte(data, 5), 8), string.byte(data, 6))))
Temperature = unsignTosigned16bit(bit.bor(bit.lshift(string.byte(data,7), 8), string.byte(data,8)))
GyroX = unsignTosigned16bit((bit.bor(bit.lshift(string.byte(data, 9), 8), string.byte(data, 10))))
GyroY = unsignTosigned16bit((bit.bor(bit.lshift(string.byte(data, 11), 8), string.byte(data, 12))))
GyroZ = unsignTosigned16bit((bit.bor(bit.lshift(string.byte(data, 13), 8), string.byte(data, 14))))
AccelX = AccelX/AccelScaleFactor -- divide each with their sensitivity scale factor
AccelY = AccelY/AccelScaleFactor
AccelZ = AccelZ/AccelScaleFactor
Temperature = Temperature/340+36.53-- temperature formula
GyroX = GyroX/GyroScaleFactor
GyroY = GyroY/GyroScaleFactor
GyroZ = GyroZ/GyroScaleFactor
print(string.format("Ax:%.3g Ay:%.3g Az:%.3g T:%.3g Gx:%.3g Gy:%.3g Gz:%.3g",
AccelX, AccelY, AccelZ, Temperature, GyroX, GyroY, GyroZ))
tmr.delay(100000) -- 100ms timer delay
end
ESPlorer Serial Output Window
The output window of the ESPlorer IDE serial window for the above Lua script is shown below
Ax = Accelerometer x-axis data in g unit
Ay = Accelerometer y-axis data in g unit
Az = Accelerometer z-axis data in g unit
T = temperature in degree/Celcius
Gx = Gyro x axis data in degree/seconds unit
Gy = Gyro y axis data in degree/seconds unit
Gz = Gyro z axis data in degree/seconds unit
MPU6050 Code for NodeMCU using Arduino IDE
#include <Wire.h>
// MPU6050 Slave Device Address
const uint8_t MPU6050SlaveAddress = 0x68;
// Select SDA and SCL pins for I2C communication
const uint8_t scl = D6;
const uint8_t sda = D7;
// sensitivity scale factor respective to full scale setting provided in datasheet
const uint16_t AccelScaleFactor = 16384;
const uint16_t GyroScaleFactor = 131;
// MPU6050 few configuration register addresses
const uint8_t MPU6050_REGISTER_SMPLRT_DIV = 0x19;
const uint8_t MPU6050_REGISTER_USER_CTRL = 0x6A;
const uint8_t MPU6050_REGISTER_PWR_MGMT_1 = 0x6B;
const uint8_t MPU6050_REGISTER_PWR_MGMT_2 = 0x6C;
const uint8_t MPU6050_REGISTER_CONFIG = 0x1A;
const uint8_t MPU6050_REGISTER_GYRO_CONFIG = 0x1B;
const uint8_t MPU6050_REGISTER_ACCEL_CONFIG = 0x1C;
const uint8_t MPU6050_REGISTER_FIFO_EN = 0x23;
const uint8_t MPU6050_REGISTER_INT_ENABLE = 0x38;
const uint8_t MPU6050_REGISTER_ACCEL_XOUT_H = 0x3B;
const uint8_t MPU6050_REGISTER_SIGNAL_PATH_RESET = 0x68;
int16_t AccelX, AccelY, AccelZ, Temperature, GyroX, GyroY, GyroZ;
void setup() {
Serial.begin(9600);
Wire.begin(sda, scl);
MPU6050_Init();
}
void loop() {
double Ax, Ay, Az, T, Gx, Gy, Gz;
Read_RawValue(MPU6050SlaveAddress, MPU6050_REGISTER_ACCEL_XOUT_H);
//divide each with their sensitivity scale factor
Ax = (double)AccelX/AccelScaleFactor;
Ay = (double)AccelY/AccelScaleFactor;
Az = (double)AccelZ/AccelScaleFactor;
T = (double)Temperature/340+36.53; //temperature formula
Gx = (double)GyroX/GyroScaleFactor;
Gy = (double)GyroY/GyroScaleFactor;
Gz = (double)GyroZ/GyroScaleFactor;
Serial.print("Ax: "); Serial.print(Ax);
Serial.print(" Ay: "); Serial.print(Ay);
Serial.print(" Az: "); Serial.print(Az);
Serial.print(" T: "); Serial.print(T);
Serial.print(" Gx: "); Serial.print(Gx);
Serial.print(" Gy: "); Serial.print(Gy);
Serial.print(" Gz: "); Serial.println(Gz);
delay(100);
}
void I2C_Write(uint8_t deviceAddress, uint8_t regAddress, uint8_t data){
Wire.beginTransmission(deviceAddress);
Wire.write(regAddress);
Wire.write(data);
Wire.endTransmission();
}
// read all 14 register
void Read_RawValue(uint8_t deviceAddress, uint8_t regAddress){
Wire.beginTransmission(deviceAddress);
Wire.write(regAddress);
Wire.endTransmission();
Wire.requestFrom(deviceAddress, (uint8_t)14);
AccelX = (((int16_t)Wire.read()<<8) | Wire.read());
AccelY = (((int16_t)Wire.read()<<8) | Wire.read());
AccelZ = (((int16_t)Wire.read()<<8) | Wire.read());
Temperature = (((int16_t)Wire.read()<<8) | Wire.read());
GyroX = (((int16_t)Wire.read()<<8) | Wire.read());
GyroY = (((int16_t)Wire.read()<<8) | Wire.read());
GyroZ = (((int16_t)Wire.read()<<8) | Wire.read());
}
//configure MPU6050
void MPU6050_Init(){
delay(150);
I2C_Write(MPU6050SlaveAddress, MPU6050_REGISTER_SMPLRT_DIV, 0x07);
I2C_Write(MPU6050SlaveAddress, MPU6050_REGISTER_PWR_MGMT_1, 0x01);
I2C_Write(MPU6050SlaveAddress, MPU6050_REGISTER_PWR_MGMT_2, 0x00);
I2C_Write(MPU6050SlaveAddress, MPU6050_REGISTER_CONFIG, 0x00);
I2C_Write(MPU6050SlaveAddress, MPU6050_REGISTER_GYRO_CONFIG, 0x00);//set +/-250 degree/second full scale
I2C_Write(MPU6050SlaveAddress, MPU6050_REGISTER_ACCEL_CONFIG, 0x00);// set +/- 2g full scale
I2C_Write(MPU6050SlaveAddress, MPU6050_REGISTER_FIFO_EN, 0x00);
I2C_Write(MPU6050SlaveAddress, MPU6050_REGISTER_INT_ENABLE, 0x01);
I2C_Write(MPU6050SlaveAddress, MPU6050_REGISTER_SIGNAL_PATH_RESET, 0x00);
I2C_Write(MPU6050SlaveAddress, MPU6050_REGISTER_USER_CTRL, 0x00);
}
Arduino Serial Output Window
The output window of the Arduino IDE serial window for the above Arduino sketch is shown below
Ax = Accelerometer x-axis data in g unit
Ay = Accelerometer y-axis data in g unit
Az = Accelerometer z-axis data in g unit
T = temperature in degree/Celcius
Gx = Gyro x axis data in degree/seconds unit
Gy = Gyro y axis data in degree/seconds unit
Gz = Gyro z axis data in degree/seconds unit
Components Used |
||
---|---|---|
MPU6050 Gyroscope and Accelerometer MPU6050 (Gyroscope + Accelerometer + Temperature) is a combination of 3-axis Gyroscope, 3-axis Accelerometer and Temperature sensor with on-chip Digital Motion Processor (DMP). It is used in mobile devices, motion enabled games, 3D mice, Gesture (motion command) technology etc |
X 1 | |
NodeMCU NodeMCUNodeMCU |
X 1 | |
ESP12F ESP12E |
X 1 |