[請教] Arduino MMA7455L 3-Axis Accelometer

本帖最後由 modbook 於 2011-6-12 18:13 編輯

Arduino 新手, 剛買了Ardunio UNO, 淘寶入手了塊 MMA7455L sensor "龙丘 MMA7455 模块V1.0"

Pin 的接駁:
  CLK --> Pin 13  (SPI library 話的)
  MOSI --> Pin11  (SPI library 話的)
  MISO --> +R2.2K --> Pin 12 (說明書話的)
  Data ready --> Pin 7   (隨意)
  CS --> Pin 10   (SPI library 話的)

無法讀取到 MMA7455L 的數據, 以下是我寫的code:

#include <SPI.h>                                      // include the SPI library

const byte mode = 0x16;                       // Mode Control Register is $16
const byte measure = 0b00000101;    // 1st 01 set to 2g, 2nd 01 set to measure mode
const byte xout = 0x06;                          // X-Axis value register is $06
const byte yout = 0x07;                         // Y-Axis value register is $07
const byte zout = 0x08;                        // Z-Axis value register is $08

const int pinReady = 7;                         // Data Ready Pin
const int pinCS = 10;                             // CS pin of MMA board

void setup() {
  Serial.begin(9600);                            // open serial port  
  SPI.begin();                                         // start the SPI library
  pinMode(pinReady, INPUT);        // initalize the pins
  pinMode(pinCS, OUTPUT);          // initalize the pins

  // Configure MMA7455 into 2g sensitivies and measure mode
  digitalWrite(pinCS, LOW);      // select the sensor
  SPI.transfer(mode);                 // Send register location
  SPI.transfer(measure);            // Send value into that register
  digitalWrite(pinCS, HIGH);   // de-select the sensor
  delay(100);                              // give the sensor time to set up
}

void loop() {
  if (digitalRead(pinReady == HIGH)) {
    digitalWrite(pinCS, LOW);    // select the sensor
    byte valueX = SPI.transfer(xout);
    byte valueY = SPI.transfer(yout);
    byte valueZ = SPI.transfer(zout);
    digitalWrite(pinCS, HIGH);   // de-select the sensor  

    Serial.print("X:  ");
    Serial.print((int) valueX);
    Serial.print("  Y:  ");
    Serial.print((int) valueY);
    Serial.print("  Z:  ");
    Serial.println((int) valueZ);
  }
  delay(1000);
}

開了個serial monitor之後, 所有data output 都是 0 :
X:  0  Y:  0  Z:  0
X:  0  Y:  0  Z:  0
X:  0  Y:  0  Z:  0
X:  0  Y:  0  Z:  0
......

我的問題:

const byte measure = 0b00000101;  那一句, 其實我只須send 最尾的0101. 我試過改佢為 0x05 都係唔唔得

說明晝有提到CS pin 接高電平為IIC, 低電平為SPI. 我有試過長期將 CS Pin 落地, 省去所有output CS pin  to LOW (to select) 及 HIGH (de-select) 的code.  output依然係 0,0,0.

MMA7455L 的 datasheet 亦有提過:

A SPI read transfer consists of a 1-bit Read/Write signal, a 6-bit address, and 1-bit don't care bit. (1-bit R/W=0 + 6-bits address + 1-bit don't care). The data to read is sent by the SPI interface during the next transfer.

In order to write to one of the 8-bit registers, an 8-bit write command must be sent to the MMA7455L. The write command consists of an MSB (0=read, 1=write) to indicate writing to the MMA7455L register, followed by a 6-bit address and 1 don't care bit.

我唔識理解以上所講的要點改我段code.

希望大家可以幫到我. 萬謝

本帖最後由 KSC 於 2011-6-13 00:54 編輯

最低限度,你都比比你個sersor的資料吧.....
http://pdf1.alldatasheet.com/dat ... SCALE/MMA7450L.html
你的問題表現出你未看清楚protocol,先溫下書
你又唔貼埋SPI.transfer(),唔知你有無錯
就咁看,你都無講果個data 係read定write....都應該係無=.=
http://arduino.cc/en/Reference/SPITransfer
如果你用這個lib,它只係8bit.....你要收data的話,要有兩個byte wor....
未命名.jpg
看圖片應該明了吧

if (digitalRead(pinReady == HIGH))<==錯,這句讀出來會係
if (digitalRead(6 == HIGH))==>if (digitalRead(1))==>如果pin1係1就做....
應該係digitalRead(pinReady)會讀果個pin
所以你要做的應該係
if (digitalRead(pinReady) == HIGH)
當然,我個人覺得你做個temp會更好

Serial.print((int) valueX);<===一般應該是用Serial.print(valuex,DEC);
但你仲意la~

TOP

回復 2# KSC

謝謝你的回覆, 正在上班不能立即測試, 但我真係搞不懂怎樣處理那個protocol.

以下是我遇到的問題:
Mode control register 是 $16, 我需要在這個mode register寫入 00000101 (0x05)這個數值
datasheet提到要寫入data, 需要 "1" (write) + "6-bit address" + "1 bit don't care"

那我在SPI.transfer()應該怎麼改那個 0x16 才能變成 "write"?
我試過將$16轉為 "10110", 然後再加 "1"在最前及"0"在最後, 變成 "10101100", 才轉為 0xAC. 成句變成:

SPI.transfer(0xAC);
SPI.transfer(0x05);

我估以上做法是不對的, 請問應怎樣寫?

同一情況

我想讀 Xout($06), Yout($07), Zout($08)這3個數值, 我試過將$06,$07,$08前及後加零(0=read), 轉為:

$06 = 0110 -> 00001100 -> $0C
$07 = 0111 -> 00001110 -> $0E
$08 = 1000 -> 00010000 -> $10

然後寫成:

byte valueX = SPI.transfer(0x0C);
byte valueY = SPI.transfer(0x0E);
byte valueZ = SPI.transfer(0x10);

之前試過, 也是失敗.


Serial.print((int) valueX);<===一般應該是用Serial.print(valuex,DEC);
但你仲意la~


謝謝, 我不太懂寫program, 我只是上網見野就抄.... 謝謝你的更正.

TOP

本帖最後由 KSC 於 2011-6-13 18:07 編輯

13-6-2011 17-48-00.jpg
目的:送出"寫,$16位置",並輸出其數值 0x05
按Datasheet和上圖,請以"1"、"0"、"N(不在意其值)"或"X(不明)"填寫時序中 R/W, A[5~0], D[7~0]的值

13-6-2011 17-48-20.jpg
承上題
目的:送出"讀,$16位置",並讀回其數值
按Datasheet和上圖,請以"1"、"0"或"X(不明)"填寫時序中 R/W, A[5~0], D[7~0]的值


SPI.transfer()
Description
Transfers one byte over the SPI bus, both sending and receiving.
Syntax
SPI.transfer(val)
Parameters
val: the byte to send out over the bus
Returns
the byte read from the bus
按以上說明,寫出上兩題應該如個送出並接收指令及數據

TOP

結果如何?出來報告下

TOP

唔好意思, 遲了回覆, 試過限多setting, 去過唔同forum參巧過都失敗. 可能我的programming 未夠班去用SPI, 可能塊sensor有問題 (同一段code, 唔同日子居然有 唔同reading). 唯有放棄, 己訂了另一塊analog的accelerometer. 相信個project會唔夠analog pin, 正在找74HC Mux....

TOP

唔好意思, 遲了回覆, 試過限多setting, 去過唔同forum參巧過都失敗. 可能我的programming 未夠班去用SPI,  ...
modbook 發表於 2011-6-16 09:27


你唔介意的話可以借/平賣比我去試下

4052,應該找到ge,我屋企都有D,但要星期6先確認到
http://www.farnell.com/datasheets/308786.pdf

TOP

借來借去就唔好喇, 我送畀你啦, 唔介意嘅你PM個收貨地址給我, 我最快要星期一才可以郵寄給你.
但如果你成功, 你可唔可以post番個接駁同complete code係呢度? 等我可以學下我爭D乜, 亦做福其他有興趣嘅人.

BTW, 74HC在華輝有沒有得賣 PIN(breadboard) 腳? 1~2粒IC 淘寶寄仲貴, 而且好多都唔係PIN 腳, 想做咗testing先, 唔想焊死住.

TOP

ok,我星期6找下D mux sin

breadboard 腳 那個封裝是叫DIP

74HC是一個Series的名稱
你要analog mux, 4052都ok
http://www.unisonic.com.tw/datasheet/4052.pdf

ps: mux係有電阻的,如讀訊號的一方內阻低,有電流就會有誤差

TOP

我還以為所有74HC都可以做Mux, 謝謝你的提點! 你畀個郵寄地址我吧, 我星期一寄給你.

我心目中想做的project非常簡單, 只是stablize, 絕對數值的準確度並不是那麼critical. 只要它能feed back到個分別給我就可以了.

TOP