介紹
MPU6050模塊
MPU6050 傳感器模塊是一個集成的 6 軸運動跟踪設備。
- 它有一個 3 軸陀螺儀、3 軸加速度計、數字運動處理器和一個溫度傳感器,所有這些都在一個 IC 中。
- 它可以使用其輔助 I2C 總線接受來自其他傳感器的輸入,例如 3 軸磁力計或壓力傳感器。
- 如果外接 3 軸磁力計,可提供完整的 9 軸 Motion Fusion 輸出。
陀螺儀和加速度計沿 X、Y 和 Z 軸的讀數以 2 的補碼形式提供。
溫度讀數以有符號整數形式提供(不是 2 的補碼形式)。
陀螺儀讀數以度/秒 (DPS) 為單位;加速度計讀數以 g 為單位,溫度讀數以攝氏度為單位。
有關 MPU6050 傳感器模塊及其使用方法的更多信息,請參閱傳感器和模塊部分中的主題 MPU6050 傳感器模塊 。
NodeMCU 可以使用 I2C 通信協議與該模塊進行通信。要了解有關 NodeMCU 中 I2C 功能的更多信息,請參閱 NodeMCU I2C with ESPlorer IDE或NodeMCU I2C with Arduino IDE
接口圖
NodeMCU 與 MPU6050 的接口
例子
從 MPU6050 模塊讀取加速度計、陀螺儀和溫度參數,並將它們顯示在串行監視器上。
首先,按照上面的接口圖進行連接。
現在讓我們編寫一個程序,從 MPU6050 讀取加速器、陀螺儀和溫度值。
我們可以用 Lua 腳本或 C/C++ 語言為 NodeMCU DevKit 編寫代碼。我們使用 ESPlorer IDE 用 Lua 腳本編寫代碼,使用 Arduino IDE 用 C/C++ 編寫代碼。要了解更多信息,請參閱 使用 ESPlorer IDE 開始使用 NodeMCU(對 NodeMCU 使用 Lua 腳本)和使用 Arduino IDE 開始使用 NodeMCU(對 NodeMCU 使用基於 C/C++ 語言的 Arduino 草圖)。
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 = 加速度計 x 軸數據,單位為 g
Ay = 加速度計 y 軸數據,單位為 g
Az = 加速度計 z 軸數據,單位為 g
T = 溫度/攝氏度
Gx = 陀螺儀 x 軸數據,以度/秒為單位
Gy = 以度/秒為單位的陀螺 y 軸數據
Gz = 陀螺儀 z 軸數據,以度/秒為單位
用於 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 草圖的 Arduino IDE 串行窗口的輸出窗口如下所示
Ax = 加速度計 x 軸數據,單位為 g
Ay = 加速度計 y 軸數據,單位為 g
Az = 加速度計 z 軸數據,單位為 g
T = 溫度/攝氏度
Gx = 陀螺儀 x 軸數據,以度/秒為單位
Gy = 以度/秒為單位的陀螺 y 軸數據
Gz = 陀螺儀 z 軸數據,以度/秒為單位
資料來源:https://www.electronicwings.com/nodemcu/mpu6050-interfacing-with-nodemcu
沒有留言:
張貼留言