MPU6050与NodeMCU的接口
MPU6050传感器是一个集成了6轴运动跟踪装置的模块,分别是3轴陀螺仪和3轴加速度计,同时集成了数字运动处理器和温度传感器。通过I2C总线,他还可以接受来自其他传感器的输入,如3轴磁力计或压力传感器,因此如果将MPU6050与外部的3轴磁力计连接起来,它就可以提供完整的9轴输出了。
MPU6050在X轴、Y轴和Z轴上的陀螺仪和加速计的值是二进制补码,温度值是整数形式。陀螺仪的读数是以每秒(dps)为单位的;加速度计的读数是以 g 为单位的;温度读数的单位是摄氏度。关于MPU6050传感器模块的更多信息,以及如何使用它,可查阅:MPU6050的使用技巧
NodeMCU可以使用I2C通信协议与MPU6050传感器模块进行通信。了解更多关于NodeMCU的资料,请查阅:Nodemcu ESP8266
Nodemcu与MPU6050的接口连接图

测试的过程是通过Nodemcu从MPU6050传感器模块读取加速计、陀螺仪和温度值,并在串行监视器上显示出来。首先,我们需要按照上面Nodemcu与MPU6050的接口图将电路连接起来。然后让我们通过下面的程序来读取MPU6050的加速度计、陀螺仪和温度的值。我们可以通过ESPlorer IDE来编写Lua脚本或使用Arduino IDE来编写c/c++代码。
NodeMCU的Lua脚本
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串口监视器
lua脚本运行后,ESPlorer IDE的串口监视器输出如下所示:
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
NodeMCU的Arduino代码
#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串口监视器
Arduino IDE串口监视器的输出如下所示:
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