ARDUINO從入門到創(chuàng)客帶師8:水平儀與指南針
ARDUINO從入門到創(chuàng)客帶師⑧:利用MPU 9250做個水平儀和指南針
其實大多數(shù)時候這樣的功能買個20塊錢的手機裝個軟件就都有了,但是不是所有的時候都可以綁著手機上的是吧
前作:用ESP8266 WIFI模塊自制MP3
ARDUINO 6050 9250
首先不同模塊之間每個模塊規(guī)格都不一樣的,從命名能看出來。就像CH340/CH341 CP210X一樣,MPU6050 6500 6555 9150 9250 9255雖然都是加速度傳感器,但是明顯的就存在區(qū)別 常見的MPU6050是非常便宜的三軸陀螺儀 + 三軸加速度傳感器模塊,MPU-6000整合了3軸陀螺儀、3軸加速器,并含可藉由第二個I2C端口連接其他廠牌之加速器、磁力傳感器、或其他傳感器的數(shù)位運動處理(DMP: Digital Motion Processor)硬件加速引擎,它的成本通常不超過5塊錢:

而這期我們用的MPU9250實際上是MPU6050加了別的傳感器的膠水封裝,但是價格就貴了很多:

MPU9150是只支持I2C的,MPU9250是支持SPI/I2C兩種方式。里面的傳感器也是不同的,MPU9150里面是MPU6050+AK8975,而MPU9250里面是MPU6500+AK8963,總之咱一開始出這個教程的動機其實很簡單,就是因為咱不小心在插了9250模塊的面包板上同時插了一個NODEMCU,結(jié)果上電之后NODEMCU炸了,所以咱很方,怕9250也跟著炸了,畢竟面包板里面都是直通的,結(jié)果就有了這期教程。事實證明它還行,沒炸,所以省下了NODEMCU炸了無所謂,14包郵現(xiàn)在,MPU9250 20不包郵可還行,炸了損失快頂倆NODEMCU了

此外咱在插上之前有系統(tǒng)鏡像的SD卡之后,樹莓派PI0 W也點亮了,所以下期我們出點亮樹莓派的教程的時候選型會有點更改,優(yōu)先考慮之前有屏幕的3B

總之我們需要這樣的一個模塊和一個支持I2C的開發(fā)板,從51單片機到樹莓派都行,這里我們用的還是ARDUINO

按正常的I2C定義把線接上就行了
6500 9205
MPU9250 ---> UNO
vcc-> 5v
接地->接地
SCL-> A5
SDA-> A4
對于其他開發(fā)板,請根據(jù)引腳定義圖檢查I2C引腳分配

至于需要的資料可以用全世界最好的搜索引擎去找

基本上商品介紹頁的信息都是沒啥問題的
MPU9250內(nèi)部是MPU6050和AK8963兩個芯片合并在一起的
MPU9250默認(rèn)情況下MPU9250用它的I2C主機控制器與AK8963通信,把磁力值讀到出放到指定的寄存器中,這需要設(shè)置一堆寄存器。好在MPU9250還集成了一個I2C主機控制器。這個模式相當(dāng)于MPU9250和AK8963共同使用一條I2C總線,它們的通信地址不一樣

實際操作上因為我們用的是ARDUINO所有庫和項目代碼都是開源且打包好的所以各位可以直接上GITHUB的項目下載你需要的所有資源,讓我看看之前咱的教程的成果怎么樣
前作:ARDUINO環(huán)境庫的安裝和使用GITHUB上的開源項目
如果GITHUB上不去,可以用這個備用鏈接,但是我還是希望各位能會用GITHUB,因為它介紹的很全

總之我們需要安裝好一個庫,直接用ARDUINO把GUTHUB的ZIP當(dāng)ZIP庫安裝就可以,然后打開例程,配置好串口驅(qū)動選定開發(fā)板所在串口,然后上傳程序之后打開串口監(jiān)視器,配置好波特率就可以看到傳感器模塊的實時返回信息了,就這么簡單:

默認(rèn)波特率是不對的,換個代碼標(biāo)注的波特率就行了

示例代碼:
#include <MPU9250_asukiaaa.h>
#ifdef _ESP32_HAL_I2C_H_
#define SDA_PIN 21
#define SCL_PIN 22
#endif
MPU9250_asukiaaa mySensor;
float aX, aY, aZ, aSqrt, gX, gY, gZ, mDirection, mX, mY, mZ;
void setup() {
?Serial.begin(115200);
?while(!Serial);
?Serial.println("started");
#ifdef _ESP32_HAL_I2C_H_ // For ESP32
?Wire.begin(SDA_PIN, SCL_PIN);
?mySensor.setWire(&Wire);
#endif
?mySensor.beginAccel();
?mySensor.beginGyro();
?mySensor.beginMag();
?// You can set your own offset for mag values
?// mySensor.magXOffset = -50;
?// mySensor.magYOffset = -55;
?// mySensor.magZOffset = -10;
}
void loop() {
?uint8_t sensorId;
?if (mySensor.readId(&sensorId) == 0) {
? ?Serial.println("sensorId: " + String(sensorId));
?} else {
? ?Serial.println("Cannot read sensorId");
?}
?if (mySensor.accelUpdate() == 0) {
? ?aX = mySensor.accelX();
? ?aY = mySensor.accelY();
? ?aZ = mySensor.accelZ();
? ?aSqrt = mySensor.accelSqrt();
? ?Serial.println("accelX: " + String(aX));
? ?Serial.println("accelY: " + String(aY));
? ?Serial.println("accelZ: " + String(aZ));
? ?Serial.println("accelSqrt: " + String(aSqrt));
?} else {
? ?Serial.println("Cannod read accel values");
?}
?if (mySensor.gyroUpdate() == 0) {
? ?gX = mySensor.gyroX();
? ?gY = mySensor.gyroY();
? ?gZ = mySensor.gyroZ();
? ?Serial.println("gyroX: " + String(gX));
? ?Serial.println("gyroY: " + String(gY));
? ?Serial.println("gyroZ: " + String(gZ));
?} else {
? ?Serial.println("Cannot read gyro values");
?}
?if (mySensor.magUpdate() == 0) {
? ?mX = mySensor.magX();
? ?mY = mySensor.magY();
? ?mZ = mySensor.magZ();
? ?mDirection = mySensor.magHorizDirection();
? ?Serial.println("magX: " + String(mX));
? ?Serial.println("maxY: " + String(mY));
? ?Serial.println("magZ: " + String(mZ));
? ?Serial.println("horizontal direction: " + String(mDirection));
?} else {
? ?Serial.println("Cannot read mag values");
?}
?Serial.println("at " + String(millis()) + "ms");
?Serial.println(""); // Add an empty line
?delay(500);
}
用同樣的方法可以讀取MPU9250磁傳感器的絕對值,并且可以利用別的項目來做指南針。至于水平儀可以到正點原子找開源的代碼。這里我們也可以提供一個備用連接。

這個模塊實際上的功能是異常強悍的,有了這個模塊你甚至可以做慣性導(dǎo)航,無人機、火箭之類的都可以造了??傊也辉僬f了,ARDUINO玩好了未來的潛力是不可限量的,各位自己領(lǐng)會吧。