- 物聯網ESP32教程
- 首頁
- 物聯網簡述
- ESP32介紹
- 在Arduino IDE中安裝ESP32開發板
- 設定RTOS進行雙核和多執行緒操作
- ESP32與MPU6050介面連線
- ESP32與模擬感測器的介面連線
- ESP32引數設定
- ESP32 SPIFFS儲存器(晶片內建迷你SD卡)
- ESP32與OLED顯示屏介面連線
- ESP32上的WiFi
- 使用HTTP透過WiFi傳輸資料
- 使用HTTPS透過WiFi傳輸資料
- 使用MQTT透過WiFi傳輸資料
- 透過藍牙傳輸資料
- 使用NTP客戶端獲取當前時間
- 執行ESP32韌體的(OTA)更新
- ESP32的應用
- 開發者後續步驟
- 物聯網ESP32實用資源
- 快速指南
- 實用資源
- 討論
ESP32與MPU6050介面連線
加速度計和陀螺儀廣泛應用於工業物聯網,用於測量各種機器的健康狀況和執行引數。MPU6050是一款流行的六軸加速度計+陀螺儀。它是一種MEMS(微機電系統)感測器,這意味著它非常緊湊(從下圖可以看出),並且在很寬的頻率範圍內也非常精確。
在本教程中,我們將學習如何將ESP32與MPU6050連線。在這個過程中,您將學習I2C(積體電路間通訊)協議的使用,這將使您能夠將ESP32與使用I2C協議進行通訊的多個感測器和外圍裝置連線。本教程需要您的ESP32、一個MPU6050和幾根跳線。
MPU6050與ESP32的連線
如下圖所示,您需要將MPU6050的SDA線連線到ESP32的21引腳,SCL線連線到22引腳,GND連線到GND,VCC連線到3V3引腳。MPU6050的其他引腳無需連線。
程式碼詳解
GitHub連結 − https://github.com/
ESP32和Arduino通常將I2C協議稱為“Wire”。因此,所需的庫匯入是Wire.h
#include<Wire.h>
接下來,我們定義常量和全域性變數。
const int MPU_ADDR = 0x68; // I2C address of the MPU-6050 int16_t AcX, AcY, AcZ, Tmp, GyX, GyY, GyZ;
每個I2C裝置都有一個固定的地址,其他裝置使用該地址識別它並與其通訊。對於MPU6050,該地址為0x68。我們稍後將在初始化與MPU6050的I2C通訊時使用它。接下來我們進入設定程式碼。
void setup() {
Serial.begin(115200);
Wire.begin(21, 22, 100000); // sda, scl, clock speed
Wire.beginTransmission(MPU_ADDR);
Wire.write(0x6B); // PWR_MGMT_1 register
Wire.write(0); // set to zero (wakes up the MPU−6050)
Wire.endTransmission(true);
Serial.println("Setup complete");
}
第一行很簡單。我們正在以115200波特率啟動與序列監視器的通訊。接下來,我們開始I2C通訊。為此,我們向Wire.begin()函式提供3個引數。
這些是SDA和SCL引腳以及時鐘速度。現在,I2C通訊需要兩條線:資料線(SDA)和時鐘線(SCL)。在ESP32上,引腳21和22通常保留用於I2C,其中21為SDA,22為SCL。為了與MPU6050通訊,我們有兩個速度選項:100kbit/s和400kbit/s。我們在這裡選擇了100kHz。如果您的用例需要,您也可以選擇更高的速度選項。
接下來,我們使用Wire.beginTransmission()命令指示ESP32我們想要與地址等於MPU_ADDR的晶片通訊。此時,您可能已經猜到一個ESP32晶片可以與多個I2C外設通訊。事實上,共有128個唯一的地址(地址欄位為7位長),因此ESP32可以使用I2C與128個不同的外設通訊,前提是它們都具有不同的地址。
在接下來的幾行中,我們將MPU6050的PWR_MGMT_1暫存器設定為0。這用於喚醒MPU6050。PWR_MGMT_1暫存器的地址0x6B是MPU6050記憶體中的地址。
它與MPU6050的I2C地址無關。MPU喚醒後,我們結束這段I2C傳輸,設定完成,並在序列監視器上使用列印語句進行指示。現在讓我們跳到迴圈中。您會注意到我們將布林值true作為引數傳遞給Wire.endTransmission。這告訴ESP32傳送停止命令並釋放I2C線路。如果我們將true替換為false,則ESP32將傳送重啟而不是停止,保持連線活動。
void loop() {
Wire.beginTransmission(MPU_ADDR);
Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H)
Wire.endTransmission(true);
Wire.beginTransmission(MPU_ADDR);
Wire.requestFrom(MPU_ADDR, 14, true); // request a total of 14 registers
AcX = Wire.read() −− 8 | Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
AcY = Wire.read() −− 8 | Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
AcZ = Wire.read() −− 8 | Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
Tmp = Wire.read() −− 8 | Wire.read(); // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
GyX = Wire.read() −− 8 | Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
GyY = Wire.read() −− 8 | Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
GyZ = Wire.read() −− 8 | Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
Serial.print(AcX); Serial.print(" , ");
Serial.print(AcY); Serial.print(" , ");
Serial.print(AcZ); Serial.print(" , ");
Serial.print(GyX); Serial.print(" , ");
Serial.print(GyY); Serial.print(" , ");
Serial.print(GyZ); Serial.print("\n");
}
在迴圈中,如果您掃描上面的程式碼片段,您會看到我們總共執行了兩次傳輸。在第一次傳輸中,我們指示MPU6050我們想要從中開始讀取資料的地址,或者更確切地說,將MPU6050的內部指標設定為這個特定地址。在第二次傳輸中,我們告訴MPU我們請求從前面傳送的地址開始的14個位元組。然後我們逐個讀取位元組。您可能會注意到我們沒有在讀取結束時使用Wire.endTransmission(true)命令。這是因為Wire.requestFrom(MPU,14,true)的第三個引數指示ESP32在讀取所需數量的位元組後傳送停止命令。如果我們傳遞false而不是true,ESP32將傳送重啟命令而不是停止命令。
現在,您可能想知道如何確定哪個暫存器對應於哪個讀數。答案是MPU6050暫存器對映。顧名思義,它提供了可以從哪個暫存器獲取哪個值的資訊。根據此對映,我們意識到0x3B和0x3C對應於16位X方向加速度值的較高和較低位元組。接下來的兩個暫存器(0x3D和0x3E)包含16位Y方向加速度值的較高和較低位元組,依此類推。在加速度計和陀螺儀讀數之間,有兩個位元組包含溫度讀數,我們讀取並忽略它們,因為我們不需要它們。這樣,您就可以成功地在ESP32上獲取MPU6050的資料。恭喜!!繼續下一個教程,學習如何在ESP32上獲取模擬感測器的資料。