【雕爺學編程】Arduino動手做(48)---GY-291 ADXL345 三軸模塊2

37款傳感器與模塊的提法,在網絡上廣泛流傳,其實Arduino能夠兼容的傳感器模塊肯定是不止37種的。鑑於本人手頭積累了一些傳感器和執行器模塊,依照實踐出真知(一定要動手做)的理念,以學習和交流爲目的,這裏準備逐一動手試試多做實驗,不管成功與否,都會記錄下來——小小的進步或是搞不掂的問題,希望能夠拋磚引玉。

【Arduino】168種傳感器模塊系列實驗(資料代碼+仿真編程+圖形編程)
實驗四十八:GY-291 ADXL345 數字三軸重力加速度傾斜度模塊 IIC/SPI傳輸

知識點:加速度與三軸加速度傳感器
一、加速度(acceleration)
1、加速度是物理學中的一個物理量,是一個向量,主要應用於經典物理當中,一般用字母a 表示,在國際單位制中的單位爲米每二次方秒(m/s^{2})。加速度是速度向量對於時間的變化率,描述速度的方向和大小變化的快慢。加速度的圖標見下圖。

在經典力學中,牛頓第二定律說明了力和加速度成正比,這定律又稱爲「加速度定律」。假設施加於物體的淨外力爲零,則加速度爲零,速度爲常數,由於動量是質量與速度的乘積,所以動量守恆。在電動力學裏,呈加速度運動的帶電粒子會發射電磁輻射。


簡單地說,速度描述了位置是如何變化的,而加速度描述了速度是如何變化的。這是兩個層面的變化!比如,水平地向前扔出一個物體,起初它的速度朝向正前,然而由於重力它開始在向前的同時向下墜落,即其速度改變了。這裏改變物體速度的主要是地球的重力引起的重力加速度。加速度是我們對任何速度變化的稱呼。因爲速度包含大小和方向,所以產生加速度只有兩種方式:改變速度或者改變方向——或者兩個都改變。

加速度具有向量性質,即需要用大小和方向同時描述一個加速度。在光滑水平面上向前運動的物體,如果向左或向右施以力,即給予了不同的加速度,則其速度會發生變化(包含了速率及方向),然而向左的加速度和向右的加速度顯然引起了不同的效果。同樣,施力的大小不同,引起的加速度不同,最終的結果也不一樣,亦可以從向量的加成性來看。作爲一個向量,加速度的疊加和分解分別遵循平行四邊形法則和三角形法則。


具體而言,加速度描述的是速度隨時間的變化率。需要注意的是,由於速度也是向量,因此加速度不爲零的物體速度的大小(稱之爲速率)也不一定會發生變化,實際上,如果加速度保持與速度垂直,速度大小就一直不會改變,同時方向一直改變。這種情況在生活中最常見的是圓周運動,比如在被拴在一端固定的線的另一端的一個小物體在線保持繃直時做的運動,又比如帶電粒子在僅受靜磁場的勞侖茲力 F=qv x B時做的運動。


加速度是物體速度隨時間的變化率,是矢量,具有大小量值和方向性(方向由+、-號代表)。加速度的大小等於單位時間內速度的改變量;加速度的方向與速度變化量ΔV方向始終相同。特別,在直線運動中,如果加速度的方向與速度相同,速度增加;加速度的方向與速度相反,速度減小。加速度等於速度對時間的一階導數,等於位置座標對時間的二階導數。

如果你沒有改變你的速度和方向,那麼你就不可能產生加速度。因此,因爲速度沒有變化,一架以每小時800英里的速度沿直線勻速飛行的飛機的加速度爲0,儘管這架飛機的速度非常快。當這架飛機降落並且迅速停下的時候它將會有加速度,因爲它正在減速。或者你也可以這樣想。在車裏,你可以通過踩油門或者剎車來產生加速度,因爲這會導致速度大小的變化。你也可以使用方向盤轉彎來產生加速度,因爲這會導致你的速度方向變化。這兩者中的任何一個都會被認爲是產生了加速度,因爲他們都會導致速度的變化。

人們會想,“如果加速度是負值,那麼物體就在減速,如果加速度是正值,那麼物體就在加速,對吧?”錯了。加速度爲負值的物體可能在加速,加速度爲正值的物體也可能在減速。爲什麼會這樣呢?考慮到加速度是一個矢量,它指向與 速度變化 相同的方向。這意味着加速度的方向決定了速度應該加還是減去加速度。從數學上講,負加速度意味着你應該從當前速度減去加速度,正加速度則表示你應該從當前速度加上加速度。如果速度一開始就是負值,那麼從速度值中減去加速度可能會使物體的速度大小增加。

如果加速度與速度指向同一方向,則物體將加速。如果加速度與速度指向不同方向,物體將會減速。以下圖爲例,一輛車不小心開入了泥潭中—這會讓車減速—或者追逐一個甜甜圈—會讓車加速。假設右爲正方向,車向右移動時速度爲正值,車向左移動時速度爲負值。如果車在加速,加速度指向速度相同方向;如果汽車減速加速度指向速度相反方向。另一種說法是,如果加速度與速度同號,物體將會加速。如果加速度與速度異號,物體將會減速。


三軸加速度傳感器(Three-axis accelerometer)
加速度傳感器有多種實現方式,主要可分爲壓電式、電容式及熱感應式三種,按輸入軸數目分類,有單軸、雙軸和三軸加速度計。三軸加速度傳感器是基於加速度的基本原理去實現工作,具有體積小和重量輕特點,可以測量空間加速度,能夠全面準確反映物體的運動性質,在航空航天、機器人、汽車和醫學等領域得到廣泛的應用。下圖爲無人機中使用的三軸加速度傳感器。

三軸加速度傳感器的物理原理
加速度的感測基本原理相當簡單,這類加速度計是利用特殊硅材料特質而設計出的可移動式結構,它的機械結構包括可移動的質量塊與彈簧連接感測器的相對固定端,分別作爲電容的兩極。當外界因加速度而使得質量塊與彈簧固定端發生相對位移時,兩極間的電容量即會產生變化,透過特殊電路可將此變化量轉換成相對應的輸出訊號,進而得到相對加速度值。但是如果只有一個方向的加速度感測器,在應用方面來說相對較少,因此,爲了適用於真實的 3D 世界,我們再進一步將其擴增立體三個方向,也就是三軸加速度感測器,因此其能檢測 X、Y、Z 的加速度資料,並根據三軸資訊來判斷當前的運動狀態,進而推廣出大量的應用端。

在空間飛行器的慣性測量系統、車輛船舶的傾斜測量、機器人的平衡姿態檢測、肢體姿態檢測等許多方面都需要測量物體的傾斜角。採用MEMS加速度傳感器來測量傾斜角角度,具有體積小、質量輕、成本低、不影響被測物體的機械機構的特點。以電容式三軸加速度計的技術原理爲例。電容式加速度計能夠感測不同方向的加速度或振動等運動狀況。其主要爲利用硅的機械性質設計出的可移動機構,機構中主要包括兩組硅梳齒,一組固定,另一組隨即運動物體移動;前者相當於固定的電極,後者的功能則是可移動電極。當可移動的梳齒產生了位移,就會隨之產生與位移成比例電容值的改變。三軸加速度傳感器的好處就是在預先不知道物體運動方向的場合下,只有應用三維加速度傳感器來檢測加速度信號。三維加速度傳感器具有體積小和重量輕特點,可以測量空間加速度,能夠全面準確反映物體的運動性質。

三軸加速度傳感器的幾個應用
(1)車身安全、控制及導航系統中的應用
加速度傳感器在進入消費電子市場之前,實際上已被廣泛應用於汽車電子領域,主要集中在車身操控、安全系統和導航,典型的應用如汽車安全氣囊、ABS防抱死剎車系統、電子穩定程序、電控懸掛系統等。車身安全越來越得到人們的重視,汽車中安全氣囊的數量越來越多,相應對傳感器的要求也越來越嚴格。整個氣囊控制系統包括車身外的衝擊傳感器、安置於車門、車頂,和前後座等位置的加速度傳感器、電子控制器,以及安全氣囊等。電子控制器通常爲16位或32位MCU,當車身受到撞擊時,衝擊傳感器會在幾微秒內將信號發送至該電子控制器。隨後電子控制器會立即根據碰撞的強度、乘客數量及座椅/安全帶的位置等參數,配合分佈在整個車廂的傳感器傳回的數據進行計算和做出相應評估,並在最短的時間內通過電爆驅動器啓動安全氣囊保證乘客的生命安全。除了車身安全系統這類重要應用以外,加速度傳感器在導航系統中的也在扮演重要角色。專家預測便攜式導航設備(PND)將成爲中國市場的熱點,其主要利於GPS衛星信號實現定位。而當PND進入衛星信號接收不良的區域或環境中就會因失去信號而喪失導航功能。基於MEMS技術的三軸加速度傳感器配合陀螺儀或電子羅盤等元件一起可創建方位推算系統,對GPS系統實現互補性應用。

(2)硬盤抗衝擊防護
由於海量數據對存儲方面的需求,硬盤和光驅等元器件被廣泛應用到筆記本電腦、手機、數碼相機/攝相機、便攜式DVD機、PMP等設備中。便攜式設備由於其應用場合的原因,經常會意外跌落或受到碰撞,而造成對內部元器件的巨大沖擊。爲了使設備以及其中數據免受損傷,越來越多的用戶對便攜式設備的抗衝擊能力提出要求。一般便攜式產品的跌落高度爲1.2~1.3米,其在撞擊大理石質地面時會受到約50KG的衝擊力。雖然良好的緩衝設計可由設備外殼或PCB板來分解大部分衝擊力,但硬盤等高速旋轉的器件卻在此類衝擊下顯得十分脆弱。如果在硬盤中內置3軸加速度傳感器,當跌落髮生時,系統會檢測到加速的突然變化,並執行相應的自我保護操作,如關閉抗震性能差的電子或機械器件,從而避免其受損,或發生硬盤磁頭損壞或刮傷盤片等可能造成數據永久丟失的情況。


(3)消費產品中的創新應用
三軸加速度傳感器爲傳統消費及手持電子設備實現了革命性的創新空間。其可被安裝在遊戲機手柄上,作爲用戶動作採集器來感知其手臂前後、左右,和上下等的移動動作,並在遊戲中轉化爲虛擬的場景動作如揮拳、揮球拍、跳躍、甩魚竿等,把過去單純的手指運動變成真正的肢體和身體的運動,實現比以往按鍵操作所不能實現的臨場遊戲感和參與感。


(4)姿態與動作識別
三軸加速度傳感器的應用範圍很廣,除了文中提到的遊戲動作操控外,還能用於手持設備的姿態識別和UI操作。例如藉助3軸加速度傳感器,手持設備可實現畫面自動轉向。iPod Touch就內建了此功能,設備顯示的畫面和信息會根據用戶的動作而自動旋轉。其通過內部傳感器對重力向量的方向檢測來確定設備處於水平或垂直狀態,並自動調整顯示狀態,給用戶帶來方便。傳感器對震動的感知性能也可將以前傳統的按鍵動作變化爲震動,用戶可通過單次或多次震動來進行功能的選擇,如曲目的選擇、音量控制等。此外,該功能還可擴展至對用戶界面元素的操控。如屏幕顯示內容的上下左右等方向的瀏覽可通過傾斜手持設備來完成。

(5)趣味性擴展功能
三軸加速度傳感器對用戶操控動作的轉變還可轉化爲許多趣味性的擴展功能上,如虛擬樂器、虛擬骰子游戲,以及“閃訊”(Wave Message)等。虛擬樂器內置的加速度傳感器可檢測用戶對手持設備的揮動來控制樂器的節奏和音量等;骰子游戲也採用類似的原理,通過對揮動等動作的感知來控制虛擬骰子的旋轉速度,並藉助內部數學模型抽象的物理定律決定其停止的時間。

“閃訊”是一個更富有想象力的應用,用戶可利用此功能在空中進行文字編輯。“閃訊”即讓手持設備通過加速度傳感器捕捉用戶在空中模擬寫字的快速動作,主要適合較暗的環境下使用。手持設備上會安裝發光的LED,由於人眼視網膜的視覺暫留現象,其在空中揮動的動作會在其眼中留下短暫的連續畫面,完成寫字的所有動作筆順。


ADXL345三軸加速度傳感器模塊實驗所需硬件清單
8x8LED點陣屏模塊X1
Arduino Uno開發板 X1
杜邦線 若干(備了9條)
LED發光二極管(藍色)X1
IIC/I2C 1602 LCD液晶屏模塊X1
ADXL345三軸加速度傳感器模塊X2
Proto Shield原型擴展板(帶mini麪包板)X1

傳感器模塊實驗所需軟件平臺
代碼編程 Arduino IDE (版本1.8.19)
仿真編程 Linkboy (版本V4.6.3)
圖形編程 Mind+ (版本 V1.7.0 RC2.0)
以及編玩邊學(線上平臺https://ide.codepku.com/?type=Arduino)

 

搜索和安裝“ADXL345”相關庫
1、打開Arduino IDE——工具——管理庫,搜索ADXL345

2、打開網頁https://github.com/,搜索ADXL345

Arduino實驗接線示意圖

【Arduino】168種傳感器模塊系列實驗(資料代碼+仿真編程+圖形編程)

實驗四十八:GY-291 ADXL345 數字三軸重力加速度傾斜度模塊 IIC/SPI傳輸

程序一:在串口顯示ADXL345的動態波形

Arduino實驗開源代碼

 

/*
  【Arduino】168種傳感器模塊系列實驗(資料代碼+仿真編程+圖形編程)
  程序一:在串口顯示ADXL345的動態波形
*/

#include <Wire.h>  // 線庫 - 用於 I2C 通信
int ADXL345 = 0x53; // ADXL345傳感器I2C地址
float X_out, Y_out, Z_out;  // 輸出

void setup() {
  Serial.begin(9600); 
  Wire.begin(); // 啓動 Wire 庫
  Wire.beginTransmission(ADXL345); // 開始與設備通信
  Wire.write(0x2D); /// 訪問/與 POWER_CTL 寄存器對話 - 0x2D
  // (8dec -> 0000 1000 binary) Bit D3 High 用於測量啓用
  Wire.write(8); 
  Wire.endTransmission();
  delay(10);
}

void loop() {
  // === 讀取加速度計數據 === //
  Wire.beginTransmission(ADXL345);
  Wire.write(0x32); // 從寄存器 0x​​32 (ACCEL_XOUT_H) 開始
  Wire.endTransmission(false);
  // 共讀取 6 個寄存器,每個軸的值存儲在 2 個寄存器中
  Wire.requestFrom(ADXL345, 6, true); 
  X_out = ( Wire.read()| Wire.read() << 8); // X軸值
  X_out = X_out/2; //將原始值除以2
  Y_out = ( Wire.read()| Wire.read() << 8); // Y軸值
  Y_out = Y_out/2;
  Z_out = ( Wire.read()| Wire.read() << 8); // Y軸值
  Z_out = Z_out/2; 
  Serial.print("Xa= ");
  Serial.print(X_out);
  delay(500);
  Serial.print("   Ya= ");
  Serial.print(Y_out);
  delay(500);
  Serial.print("   Za= ");
  Serial.println(Z_out);
  delay(500);
}

  

實驗串口返回情況

打開Arduino IDE——工具——串口繪圖器,查看實驗波形

實驗串口繪圖器返回情況

【Arduino】168種傳感器模塊系列實驗(資料代碼+仿真編程+圖形編程)

實驗四十八:GY-291 ADXL345 數字三軸重力加速度傾斜度模塊 IIC/SPI傳輸

程序二:在串口顯示ADXL345的動態波形之二

Arduino實驗開源代碼

 

/*
  【Arduino】168種傳感器模塊系列實驗(資料代碼+仿真編程+圖形編程)
  程序二:在串口顯示ADXL345的動態波形之二
  Arduino------ADXL345
  5V------------VCC
  GND-----------GND
  A4-----------SDA IIC 數據線
  A5-----------SCL IIC 時鐘線
*/

#include <Wire.h>

#define DEVICE (0x53)  //ADXL345設備地址
#define TO_READ (6)    //我們每次要讀取的字節數(每個軸兩個字節)
byte buff[TO_READ] ;   //6字節緩衝區,用於保存從設備讀取的數據

char str[512];   //字符串緩衝區,用於在將數據發送到串行端口之前對其進行轉換
int regAddress = 0x32;  //ADXL345上的第一個軸加速度數據寄存器
int x, y, z;      //三軸加速度數據

double roll = 0.00, pitch = 0.00;  //Roll & Pitch 是繞 X 軸和 y 軸旋轉的角度

void setup() {
  Wire.begin();    // 加入 i2c 總線(主機地址可選)
  Serial.begin(9600);  // 啓動串口輸出

  //開啓ADXL345
  writeTo(DEVICE, 0x2D, 0);
  writeTo(DEVICE, 0x2D, 16);
  writeTo(DEVICE, 0x2D, 8);
}

void loop() {
  readFrom(DEVICE, regAddress, TO_READ, buff); //從ADXL345讀取加速度數據

  //每個軸讀數的分辨率爲 10 位,即 2 個字節。最低有效字節優先!!
  //因此我們將兩個字節轉換爲一個整數
  x = (((int)buff[1]) << 8) | buff[0];
  y = (((int)buff[3]) << 8) | buff[2];
  z = (((int)buff[5]) << 8) | buff[4];

  //我們將x y z值作爲字符串發送到串口
  Serial.print("x,y,z的加速度信息爲:");
  sprintf(str, "%d %d %d", x, y, z);
  Serial.print(str);
  Serial.write(10);

  //計算Roll & Pitch 
  RP_calculate();
  Serial.print("滾動:");
  Serial.println( roll );
  Serial.print("間距:");
  Serial.println( pitch );
  Serial.println("");
  //看來需要延遲才能不阻塞端口
  delay(500);
}

//將val寫入設備上的地址寄存器
void writeTo(int device, byte address, byte val) {
  Wire.beginTransmission(device); //開始傳輸到設備
  Wire.write(address);        // 發送寄存器地址
  Wire.write(val);        // 發送要寫入的值
  Wire.endTransmission(); //結束傳輸
}

//從設備上的地址寄存器開始讀取num字節到buff數組
void readFrom(int device, byte address, int num, byte buff[]) {
  Wire.beginTransmission(device); //開始傳輸到設備
  Wire.write(address);        //發送要讀取的地址
  Wire.endTransmission();     //結束傳輸

  Wire.beginTransmission(device); //開始傳輸到設備
  Wire.requestFrom(device, num);  // 從設備請求 6 個字節

  int i = 0;
  while (Wire.available()) //設備發送的數據可能少於請求的數據(異常)
  {
    buff[i] = Wire.read(); // 接收一個字節
    i++;
  }
  Wire.endTransmission(); //結束傳輸
}

//計算Roll&Pitch
void RP_calculate() {
  double x_Buff = float(x);
  double y_Buff = float(y);
  double z_Buff = float(z);

  roll = atan2(y_Buff , z_Buff) * 57.3;
  pitch = atan2((- x_Buff) , sqrt(y_Buff * y_Buff + z_Buff * z_Buff)) * 57.3;
}

  實驗串口返回情況

 

實驗串口繪圖器返回情況

 

Arduino實驗場景圖

程序三:串口顯示ADXL345的動態波形
實驗開源仿真編程(Linkboy V4.63)

打開Linkboy——各種常用小工具——串口繪圖器,查看實驗波形

 

 

實驗串口繪圖器返回情況

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章