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