公告版位
需要找什麼嗎? 左邊分類或許可以幫助你...

ADXL345 是一種常見、便宜、簡單、好用的 3 軸加速度計。我這片 ADXL345 模組是我在露天拍賣買的,約台幣 110 元...,比起之前買的 LSM303DLH 就要台幣 6、7 百元要來的便宜多了...Orz

另外記得 信號線 都要接 10K 上拉電阻,不然會讀不到...( 只要是走 i2c 協定的都要接上拉電阻

實際接線圖 (右邊小塊板子就是 ADXL345 )

3

特寫 ADXL345 模組:

2

執行結果:

Forbidden filename  

程式碼:

#include <Wire.h>

int I2C_Address = 0xA7 >> 1; // ADXL345 的 I2C 地址

int X0, X1, Y0, Y1, Z1, Z0;
float X,Y,Z;

void setup(){
    Serial.begin(9600);
    Serial.println("Start : \n------------------------------------");
    
    Wire.begin();  //初始化 I2C
    setReg(0x2D, 0xA); // (打開電源, 設定輸出資料速度為 100 Hz)  
}

void loop(){
    X0 = getData(0x32); // 取得 X 軸 低位元資料
    X1 = getData(0x33); // 取得 X 軸 高位元資料
    X = ((X1 << 8)  + X0) / 256.0;
 
    Y0 = getData(0x34); // 取得 Y 軸 低位元資料
    Y1 = getData(0x35); // 取得 Y 軸 高位元資料
    Y = ((Y1 << 8)  + Y0) / 256.0;
 
    Z0 = getData(0x36); // 取得 Z 軸 低位元資料
    Z1 = getData(0x37); // 取得 Y 軸 高位元資料
    Z = ((Z1 << 8)  + Z0) / 256.0;
    
    Serial.print("X= ");
    Serial.print(X);
    Serial.print("    Y= ");
    Serial.print(Y);
    Serial.print("    Z= ");
    Serial.println(Z);
    
    delay(500);
}

/* setReg(reg,data):寫入佔存器
 * 參數:
 *     reg → 指定佔存器位址
 *     data → 要寫入的資料
 */
void setReg(int reg, int data){
    Wire.beginTransmission(I2C_Address);
    Wire.write(reg); // 指定佔存器
    Wire.write(data); // 寫入資料
    Wire.endTransmission();
}

/* getData(reg):取得佔存器裡的資料
 * 參數:reg → 佔存器位址
 */
int getData(int reg){
    Wire.beginTransmission(I2C_Address);
    Wire.write(reg);
    Wire.endTransmission();
    
    Wire.requestFrom(I2C_Address,1);
    
    if(Wire.available()<=1){
        return Wire.read();
    }
}
 




創作者介紹

彥霖 實驗筆記

黃彥霖 發表在 痞客邦 PIXNET 留言(42) 人氣()


留言列表 (42)

發表留言
  • 訪客
  • 你好!!你真的太厲害了 我非常佩服 我試著用你的程式 非常成功
    setReg(0x2D, 0xA); 但這個地方我無意間把它刪掉 可是程式還是跑得動
    我想請問他是要幹嘛的?是和int getData(int reg){
    Wire.beginTransmission(I2C_Address); 等程式有關嗎 可否解釋一下大概的概念?麻煩你了 感恩


  • 謝謝,我的文章能幫助到你實在太好了。

    setReg(0x2D, 0xA); 刪掉還可以執行,代表你之前已經執行過一次,第二次執行時不需要寫也沒關係,但是如果你的 ADXL345 是新買回來的一定要寫,(打開電源, 設定輸出資料速度為 100 Hz) 這只要設定一次之後就不用再設定了,除非你要更改。

    setReg() 這是寫入佔存器,也就是說 ADXL345 它裡面的內部記憶體,通過設置ADXL345裡面的記憶體,可以改變 ADXL345 的行為,例如打開電源/關閉電源、每秒讀取次數、讀取的解析度,這種方式在 I2C 很常見。

    而 getData() 則是從 ADXL345 裡的記憶體讀取資料,例如 X、Y、Z 的數值。

    Wire.beginTransmission(I2C_Address); 則是開始使用 I2C ,地址則是 I2C_Address,也就是上面宣告的 int I2C_Address = 0xA7 >> 1;,而為什麼需要使用 0xA7 這則是需要看ADXL345的資料手冊的,相對的有開始就必須有結束,所以下方也要使用 Wire.endTransmission(); 來做為 I2C結束。

    黃彥霖 於 2014/03/14 01:31 回覆

  • 訪客
  • 你好!感謝回復受益良多,我有繼續上網找尋這方面的資料但我又產生了一點問題
    https://github.com/Anilm3/ADXL345-Accelerometer/tree/master/Arduino
    上面網址example裡程式是有關於pitch和roll的角度值,若要運作的話要有.cpp 和 .h,我想問問我的觀念對不對。 .h就是定義那些0x??的地方 .cpp就像是你這篇內容原理一樣讀出加速度計的數據 而他example裡的程式是藉由.cpp裡面讀出來的值來算出roll和pitch的角度 不知這樣的觀念有沒有正確?假設是正確的 我還想在請問一下網址裡example的程式 有一行是acc.read(&Xg, &Yg, &Zg); 我不太懂為啥是&Xg, &Yg, &Zg而不是acc.read(&X, &Y, &Z);因為我在.cpp或.h裡面也沒看到&Xg, &Yg, &Zg的相關定義 問題很長 麻煩解惑 感激不盡
  • 訪客
  • 您好~~請問為何要低位元資料+高位元資料呢 ? 如果說要讓他靈敏些 應該要/2吧?
  • 訪客
  • 您好!!請問為什麼getData裡面的Wire.endTransmission();
    該副函式的怎麼不寫在最後面
    謝謝
  • 訪客
  • 你好 請問要把數值輸出到七段顯示器上請問要怎麼寫
  • 他喵的
  • 好奇問一下,SCL SDA是用一般腳位就可以了嗎?
    要如何更改腳位
    感謝~
  • 不可以用一般腳位喔!!
    Arduino 有固定的 SCL SDA 腳位
    看你的板子是哪一種,到Google查詢應該就可以找到了

    黃彥霖 於 2014/07/27 13:10 回覆

  • 訪客
  • 可以請問一下
    X1 << 8 是甚麼意思嗎?
  • 向左移八位元,如果溢位的話,數字會變成負號

    黃彥霖 於 2014/07/29 08:53 回覆

  • 訪客
  • 請問要怎麼提升準確度例如能分大位移跟小位移在數值上的差異
  • 位移錯誤的話數字就會亂跳,已經沒有準確度了...( 所以都要設置正確
    要達到超高解析度可以去買 ADXL335 然後接 12bit (或更高) 的ADC
    這樣就可以達到很高的解析度

    黃彥霖 於 2014/07/29 23:36 回覆

  • 訪客
  • 請問在執行結果那邊serial monitor裡面的數值不是因為有loop會一直跑嗎為什麼我的跑到一半有時候會中斷或者同樣的執會持續出現?
  • 檢查一下線是否有插好,或換一條新的傳輸線試試

    黃彥霖 於 2014/08/24 16:08 回覆

  • 悄悄話
  • 訪客
  • 版主你好,這行> setReg(0x2D, 0xA); // (打開電源, 設定輸出資料速度為 100 Hz) 這行我直接打上去好像不行,是否要改哪邊!?

    X0 = getData(0x32); // 取得 X 軸 低位元資料 還有這行 是否要改那些值
  • 訪客
  • 同上...... 我是用arduino 寫
  • 悄悄話
  • 訪客
  • 你好,
    我執行程式只看得到“Start : \n------------------------------------”這行,沒有看見輸出XYZ值,請問是哪裡發生錯誤了呢?
  • 訪客
  • 可以請教您這塊 ADXL345 模組 的型號,或者在哪買得到呢??
    感恩 !!
  • 露天拍賣很多呦~

    黃彥霖 於 2015/03/19 23:37 回覆

  • pib35483
  • 感謝提供此資訊,但我測試的結果一直都是X=-2 Y=-2 Z=-2,是哪裡出問題嗎?還是ADXL345故障?
  • 1. 檢查是否有接好,如果是麵包板可以換個地方插
    2. 電壓是否正確
    3. 換另外一個試試

    黃彥霖 於 2015/03/23 19:26 回覆

  • 訪客
  • 我用I2C scanner 程式,顯示I2C device address 0x53,和0xA7 >>1是相同的嗎?
  • 訪客
  • 你好,請問我 已經有一個 I2C 介面的LCM接在 arduino 328P上, 如果要再接一個 I2C 面的 ADXL345 , 需如何設定 I2C address?
  • 直接 "並聯" i2c 設備即可, i2c 可以支援多設備共享 Bus

    每個元件的 Address 不同,要查元件的 Datasheet 才能夠知道

    黃彥霖 於 2015/04/27 15:22 回覆

  • 訪客
  • 你好,那如果一個位置是 0x27(LCM) , 一個是 0xA7(ADXL345) , 需如何設定軟體的 I2C?
    我需要將 ADX345 讀到的值,顯示在 I2C LCM 上面, 目前 I2C LCM 用在其他非I2C感測器可以正常顯示。謝謝
  • 如何設定可以參考我上面程式碼:

    int I2C_Address = 0xA7 >> 1; // ADXL345 的 I2C 地址

    Wire.beginTransmission(I2C_Address);
    Wire.write(reg); // 指定佔存器
    Wire.write(data); // 寫入資料
    Wire.endTransmission();

    黃彥霖 於 2015/04/27 17:00 回覆

  • 訪客
  • 不好意思,是否能再請教一下
    當 arduino X,Y,Z數值讀到後,我想用RS232 + Excel ,當讀到數值後做成圖表曲線。

    但是需要將:
    X 依序放到 A1,A2,A3.....An
    Y 依序放到 B1,B2,B3.....Bn
    Z依序放到 C1,C2,C3.....Cn

    第一組 A1,B1,C1
    第二組 A2,B2,C2
    ...以此類推

    目前只能做到放X,Y,Z 其中一種到excel, 不曉得Arduinio 是否有什麼指令可以讓輸入的值依序存放到所需欄位中?


    謝謝
  • 可以參考 CSV 檔案格式

    http://zh.wikipedia.org/wiki/%E9%80%97%E5%8F%B7%E5%88%86%E9%9A%94%E5%80%BC

    使用 "逗號" 與 "換行" 即可達到欄列效果

    黃彥霖 於 2015/04/30 13:07 回覆

  • 訪客
  • 請問一下XYZ的值的範圍是多少嗎?
  • 訪客
  • datasheet上寫說CS腳要接在高電位,SDO接法不同地址也會不同,
    請問你問甚麼都沒接?
  • 有接喔 ! 在第一張圖你可以發現有兩顆 10K 上拉電阻

    不過不論怎麼接,地址都不會變吧...

    黃彥霖 於 2015/05/22 11:04 回覆

  • 訪客
  • 請問一下 如果輸出 x,y,z怎麼動都是-1 也確認沒接錯 怎麼辦@_@
  • 有可能是 I2C_Address 地址設錯...或連不到....

    最壞的情況是模組壞了...

    黃彥霖 於 2015/05/28 02:49 回覆

  • lipasn
  • 你好:
    我最近看過很多的範例,CS腳有接高電位,可是你的圖ADXL345上的CS接腳是空的,但我把有接跟沒接(CS)去試結果都一樣,這是為什麼,有關係嗎。以上請教,謝謝!
  • CS 是給 SPI 使用的,本範例是使用 i2c 所以不需要用到 CS 腳位

    i2c 一定要接上拉電阻喔,不然會讀不到

    如果都確定線路沒問題...那可就能是板子的問題...

    詳細可以參考這邊

    http://www.analog.com/media/en/technical-documentation/data-sheets/ADXL345.pdf

    黃彥霖 於 2015/08/01 14:23 回覆

  • inixer
  • 想請問, ADXL345 需要校正嗎?因為看起來你的加速計不動的時候 , X Y 都很趨近 0 , 但小弟的數值偏差就比較大:X= -0.41 Y= -0.94 Z= 6.66 ...
  • 是可以校正,不過....這誤差有點大呢...

    黃彥霖 於 2015/09/11 20:01 回覆

  • 訪客
  • 你好我是新手
    有問題想請教一下
    請問如果要設定三軸模組 移動到指定角度時,回傳指定的角度到網頁上
    我應該要寫在哪一段才好呢?
  • 這種做法很多呢

    例如走 UART → Java/C/C++/C#/Python ... → Apache / IIS / Tomcat
    或是接 Webduino 也可以

    黃彥霖 於 2015/09/22 13:24 回覆

  • 訪客
  • 轉動數值會改變 但是水平移動數值怎麼不會變@_@
  • 訪客
  • 想請問一下
    如果編譯完出現
    "Low memory available, stability problems may occur."
    請問我要怎麼改善這個問題呢~?
  • lipasn
  • 你好,再次請教您。
    最近試了好幾塊adxl345,但每塊的x、y、z值都不大一樣(平放的狀態),而且有的值都高於+_256。這是不是代表模塊有問題?值應該介於230-282之間的模塊才是正常的嗎,煩請指教,謝謝!
  • 嗯,這類感測器多少會這樣

    可換別種試試看

    例如 ADXL340 或 LSM303DLH

    黃彥霖 於 2015/10/05 21:23 回覆

  • Allen
  • 老師您好: 我想問說 如何把XYZ軸的值轉成角度?
  • 量角度需要使用 "陀螺儀",不是 "加速度計"

    黃彥霖 於 2015/11/05 23:19 回覆

  • Jie
  • 您好! 請教一下!
    DATA_FORMAT暫存器的FULL_RES bit 與Justify Bit設定是?
    此行 X = ((X1 << 8) + X0) / 256.0,為何要除256?
  • 訪客
  • 一個uno用i2c傳輸要如何一次讀取各別三顆adxl345的加速度值
  • 悄悄話
  • Tim
  • 你好,請教一下
    我用你的接線&程式測試我的ADXL345板
    但卻只有顯示:X= -2.00 Y= 2.00 Z= 2.00
    請問這是不是ADXL345板子壞掉了呀?
  • hugo
  • 三軸加速規取樣頻率:6.25Hz-3200Hz 加速度靈敏度0.97mg/Lsb 有哪一個晶片可以做到
  • 030/
  • 你好 感謝大大的文章讓我獲益良多
    但是我目前遇到了一個問題....
    一小時前我測試成功之後 結果很好 XYZ數值都是在 + - 1內
    但是我出門買個消夜回來之後再測試一次 XYZ數值就變成 10~100 甚至更大的數值內在飄移 請問這是為什麼阿 我程式跟接線都沒動過.......是因為板子電壓不穩嗎?
  • 劫
  • 大大您好,想請問可以利用此加速度計測速度嗎
  • 訪客
  • 請問照大大提供的資訊操作,為何減速時加速度值不會是負的 ??
  • vega
  • 不好意思, 我補充一下:
    // 初始化 I2C = 0x53
    Wire.begin(I2C_Address);

    // 暫存器 0x31 內容
    // 設定量測 Scale 範圍
    // 0x00=+-2G / 0x01 = +-4G / 0x02= +- 9G / 0x03 = +- 16G
    setReg(0x31, 0x00);

    // 暫存器 0x2D 設定 ADXL345 進入量測模式
    // 0x00 = StandBy 0x08 = 進入量測工作模式
    setReg(0x2D, 0x08);
  • alan
  • 如何將adxl345 xyz的值經由發射端nrf24l01傳出,再由接收端的nrf24l01接收解開xyz ?
  • 匿名
  • 用 c# client 連結 server ip傳送表頭 如何去修改?
    因為要偽造ip 不能改本機ip去修改 有解嗎?
  • 訪客
  • 請問一下,為什麼當X1=255時,左移8會變成-256

    x1不是int型態嗎?