MPU6050是一款 集成 了 IC 3 軸加速度計(jì)和 3 軸陀螺儀的 單元。它還包含一個(gè)溫度傳感器和一個(gè) DCM 來執(zhí)行復(fù)雜的任務(wù)。MPU6050 常用于構(gòu)建無人機(jī)和其他遠(yuǎn)程機(jī)器人,如自平衡機(jī)器人。在這個(gè)項(xiàng)目中,我們將使用MPU6050 和 Arduino構(gòu)建一個(gè)數(shù)字量角器。
什么是加速度計(jì)和陀螺儀傳感器?
加速度計(jì)用于測(cè)量加速度。它實(shí)際上感應(yīng)靜態(tài)和動(dòng)態(tài)加速度。例如,手機(jī)使用加速度傳感器來感知手機(jī)處于橫向模式還是縱向模式。
陀螺儀用于測(cè)量角速度,該角速度使用地球重力來確定運(yùn)動(dòng)中物體的方向。角速度是旋轉(zhuǎn)體角位置的變化率。
例如,今天的手機(jī)使用陀螺儀傳感器根據(jù)手機(jī)的方位來玩手機(jī)游戲。此外,VR 耳機(jī)使用陀螺儀傳感器具有 360 度視圖
因此,雖然加速度計(jì)可以測(cè)量線性加速度,但陀螺儀可以幫助找到旋轉(zhuǎn)加速度。當(dāng)使用兩個(gè)傳感器作為單獨(dú)的模塊時(shí),很難找到方向、位置和速度。但是通過組合這兩個(gè)傳感器,它可以作為一個(gè)慣性測(cè)量單元(IMU)。因此,在MPU6050 模塊中,加速度計(jì)和陀螺儀存在于單個(gè) PCB 上,以查找方向、位置和速度。
應(yīng)用:
用于無人機(jī)方向控制
自平衡機(jī)器人
機(jī)械臂控制
傾斜傳感器
用于手機(jī)、視頻游戲機(jī)
人形機(jī)器人
用于飛機(jī)、汽車等。
MPU6050 加速度計(jì)和陀螺儀傳感器模塊
MPU6050 是一種微機(jī)電系統(tǒng) ( MEMS ),內(nèi)部包含一個(gè) 3 軸加速度計(jì)和 3 軸陀螺儀。它也有溫度傳感器。
它可以測(cè)量:
加速
速度
方向
移位
溫度
該模塊內(nèi)部還有一個(gè)(DMP)數(shù)字運(yùn)動(dòng)處理器,其功能強(qiáng)大到足以執(zhí)行復(fù)雜的計(jì)算,從而為微控制器騰出工作。
該模塊還有兩個(gè)輔助引腳,可用于連接外部 IIC 模塊,如磁力計(jì)。由于模塊的 IIC 地址是可配置的,因此可以使用 AD0 引腳將多個(gè) MPU6050 傳感器 連接到微控制器。
特點(diǎn)和規(guī)格:
電源:3-5V
通訊方式:I2C協(xié)議
內(nèi)置 DMP 提供高計(jì)算能力
可用于連接其他 IIC 設(shè)備,如磁力計(jì)
可配置的 IIC 地址
內(nèi)置溫度傳感器
MPU6050的管腳:
我們之前使用MPU6050 和 Arduino來構(gòu)建自平衡機(jī)器人和測(cè)斜儀。
所需組件
Arduino UNO
MPU6050陀螺儀模塊
16x2 液晶顯示器
電位器 10k
SG90-伺服電機(jī)
量角器圖像
電路原理圖
這個(gè)DIY Arduino 量角器的電路圖如下所示:
Arduino UNO 和 MPU6050 之間的電路連接:
Arduino UNO 和伺服電機(jī)之間的電路連接:
Arduino UNO 和 16x2 LCD 之間的電路連接:
編程說明
這里伺服電機(jī)與 Arduino 連接,其軸投影在量角器圖像上,指示傾斜 MPU6050 的角度。
首先包括所有必需的庫 - 用于使用伺服的伺服電機(jī)庫、用于使用 LCD 的 LCD 庫和用于使用 I2C 通信的 Wire 庫。
MPU6050 使用I2C 通信,因此,它只能連接到 Arduino 的 I2C 引腳。因此,Wire.h庫用于建立 Arduino UNO 和 MPU6050 之間的通信。我們之前將 MPU6050 與 Arduino 連接,并在 16x2 LCD 上顯示 x、y、z 坐標(biāo)值。
?
#include#include #include
?
接下來定義與 Arduino UNO 連接的 LCD 顯示引腳 RS、E、D4、D5、D6、D7。
?
液晶液晶(2,3,4,5,6,7);
?
接下來定義 MPU6050 的 I2C 地址。
?
常量 int MPU_addr=0x68;
?
然后初始化myservo對(duì)象以使用 Servo 類和三個(gè)變量來存儲(chǔ) X、Y 和 Z 軸值。
?
伺服myservo; int16_t 軸_X,軸_Y,軸_Z;
?
下一個(gè)最小值和最大值設(shè)置為 265 和 402,用于測(cè)量從 0 到 360 的角度。
?
int minVal=265; 詮釋 maxVal=402;
?
無效設(shè)置():
在void setup函數(shù)中,首先啟動(dòng) I2C 通信,并使用地址為 0x68 的 MPU6050 開始傳輸。
?
Wire.begin(); Wire.beginTransmission(MPU_addr);
?
通過寫入 0x6B 將 MPU6050 置于睡眠模式,然后通過寫入 0 喚醒它
?
Wire.write(0x6B); Wire.write(0);
?
使MPU6050激活后,結(jié)束傳輸
?
Wire.endTransmission(true);
?
此處伺服電機(jī)的 PWM 引腳與 Arduino UNO 引腳 9 相連。
?
myservo.attach(9);
?
一旦我們給電路加電,液晶顯示屏就會(huì)顯示一條歡迎消息,并在 3 秒后清除它?
?
lcd.開始(16,2);//將 LCD 設(shè)置為 16X2 模式 lcd.print("CIRCUIT DIGEST"); 延遲(1000); lcd.clear(); lcd.setCursor(0,0); lcd.print("Arduino"); lcd.setCursor(0,1); lcd.print("MPU6050"); 延遲(3000); lcd.clear();
?
無效循環(huán)():
同樣,I2C 通信是從 MPU6050 開始的。
?
Wire.beginTransmission(MPU_addr);
?
然后從寄存器 0x??3B (ACCEL_XOUT_H) 開始????????????
?
Wire.write(0x3B);
?
現(xiàn)在,通過將結(jié)束傳輸設(shè)置為 false 重新啟動(dòng)該過程,但連接處于活動(dòng)狀態(tài)。
?
Wire.endTransmission(false);
?
之后,現(xiàn)在從 14 個(gè)寄存器請(qǐng)求數(shù)據(jù)。
?
Wire.requestFrom(MPU_addr,14,true);
?
現(xiàn)在獲得尊重的軸寄存器值(x,y,z)并將其存儲(chǔ)在變量axis_X,axis_Y,axis_Z中。
?
axis_X=Wire.read()<<8|Wire.read(); axis_Y=Wire.read()<<8|Wire.read(); axis_Z=Wire.read()<<8|Wire.read();
?
然后將這些值從 265 映射到 402 為 -90 到 90。這對(duì)所有三個(gè)軸都完成了。?
?
int xAng = map(axis_X,minVal,maxVal,-90,90); int yAng = map(axis_Y,minVal,maxVal,-90,90); int zAng = map(axis_Z,minVal,maxVal,-90,90);
?
下面給出了以度(0 到 360)為單位計(jì)算 x 值的公式。這里我們只轉(zhuǎn)換 x,因?yàn)樗欧姍C(jī)的旋轉(zhuǎn)是基于 x 值移動(dòng)的。
?
x= RAD_TO_DEG * (atan2(-yAng, -zAng)+PI);
?
X 角度值,從 0 到 360 度,轉(zhuǎn)換為 0 到 180。
?
int pos = map(x,0,180,0,180);
?
然后寫入角度值以在量角器圖像上旋轉(zhuǎn)伺服并將這些值打印在 16x2 LCD 顯示器上。????
?
myservo.write(pos); lcd.setCursor(0,0); lcd.print("角度"); lcd.setCursor(0,1); lcd.print(x); 延遲(500); lcd.clear();
?
#include
#include
#include
液晶液晶(2,3,4,5,6,7); //定義LCD顯示引腳RS,E,D4,D5,D6,D7
常量 int MPU_addr=0x68; //I2C MPU6050地址
伺服myservo;//類伺服的myservo對(duì)象
int16_t 軸_X,軸_Y,軸_Z;
int minVal=265;
詮釋 maxVal=402;
雙x;
雙 y;
雙z;
整數(shù)位置 = 0;
void setup()
{
Wire.begin(); //開始 I2C 通信
Wire.beginTransmission(MPU_addr); //使用 MPU6050 開始傳輸
Wire.write(0x6B); //將 MPU6050 置于睡眠模式
Wire.write(0); //將 MPU6050 置于電源模式
Wire.endTransmission(true); //結(jié)束
傳輸 myservo.attach(9);
//UNO lcd.begin(16,2)中的伺服 PWM 引腳為 9 ;//將 LCD 設(shè)置為 16X2 模式
lcd.print("CIRCUIT DIGEST");
延遲(1000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Arduino");
lcd.setCursor(0,1);
lcd.print("MPU6050");
延遲(2000);
lcd.clear();
}
無效循環(huán)()
{
Wire.beginTransmission(MPU_addr);//開始 I2C 傳輸
Wire.write(0x3B); //從寄存器 0x??3B (ACCEL_XOUT_H) 開始
Wire.endTransmission(false);
Wire.requestFrom(MPU_addr,14,true); //向MPU6050請(qǐng)求14個(gè)寄存器
axis_X=Wire.read()<<8|Wire.read(); //獲取0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
axis_Y=Wire.read()<<8|Wire.read(); //0x3B (ACCEL_YOUT_H) & 0x3C (ACCEL_YOUT_L)
axis_Z=Wire.read()<<8|Wire.read(); //0x3B (ACCEL_ZOUT_H) & 0x3C (ACCEL_ZOUT_L)
int xAng = map(axis_X,minVal,maxVal,-90,90);
int yAng = map(axis_Y,minVal,maxVal,-90,90);
int zAng = map(axis_Z,minVal,maxVal,-90,90);
x= RAD_TO_DEG * (atan2(-yAng, -zAng)+PI); //計(jì)算度數(shù)x值的公式
int pos = map(x,0,180,0,180); // 因?yàn)?X 值是從 0 到 360 度
myservo.write(pos); // 將獲得的角度 0 到 180 寫入伺服
lcd.setCursor(0,0);
lcd.print("角度");
lcd.setCursor(0,1);
lcd.print(x);
延遲(500);
lcd.clear();
}
?
評(píng)論