ADXL373加速度计SPI通信问​​题

发布于 2025-02-03 08:20:34 字数 4800 浏览 2 评论 0 原文

作为序言,我是Arduino和电子通信的新手。我处于基于Arduino的加速度计设置的初始阶段,以记录撞击的高加速度尖峰。我正在与单个ADXL373加速度计通过SPI启动。

我已经陷入了SPI代码上一段时间,因为它只能从所有3个轴上读取0。我期望的问题仍在编码我的读物/写作方面仍然存在。在我执行它们时,是否有什么明显的脱颖而出的?

adxl373数据表:

// ADXL373 400g Accelerometer sensor connected to Arduino 2560 Mega Board

// V5: pin 3.3V
// GND: pin GND
// MOSI: pin 51
// MISO: pin 50
// SCLK: pin 52
// CS: pin 53

// the sensor communicates using SPI, so include the library:
#include <SPI.h>

const int CS = 53; //Chip Select (Arduino Mega Pin 53)

/////////////////////////////////////////////////////////////////////////////////
///////////////////////////// Register Addresses ////////////////////////////////

byte XDATA_H = 0x08; // (0b00001000) X Data Register, High 8 MSB 
byte XDATA_L = 0x09; // (0b00001001) X Data Register, Low 4 MSB 
byte YDATA_H = 0x0A; // (0b00001010) Y Data Register, High 8 MSB 
byte YDATA_L = 0x0B; // (0b00001011) Y Data Register, Low 4 MSB 
byte ZDATA_H = 0x0C; // (0b00001100) Z Data Register, High 8 MSB 
byte ZDATA_L = 0x0D; // (0b00001101) Z Data Register, Low 4 MSB 
byte OFFSET_X = 0x20; // X Data Offset Register, Lower 4 bits
byte OFFSET_Y = 0x21; // Y Data Offset Register, Lower 4 bits
byte OFFSET_Z = 0x22; // Z Data Offset Register, Lower 4 bits
byte TIME_CTRL = 0x3D; // (0b00111101) Timing Control Register -> Select ODR (0b10000000) for 5120 Hz
byte MEASR_CTRL = 0x3E; // (0b00111110) Measurement Control -> Bandwidth set (0b00000100) for 2560 Hz
byte POWER_CTRL = 0x3F; // (0b00111111) Power Control Register -> Op. Mode and HPF off (0b00000111)
const byte WRITE = 0b11111110; // Reads with a 1, high
const byte READ = 0b00000001; // Writes with a 0, low

////////////////////////////////////////////////////////////////////////////////

// Establish variables to identify x, y, and z axis accelerations
int x_axis = 1;
int y_axis = 2;
int z_axis = 3;

void setup() 
{
  SPI.begin(); // Initialize SPI
  SPI.setDataMode(SPI_MODE0);
  SPI.setBitOrder(MSBFIRST); // Data for the device is sent MSB first, RW is last bit
  Serial.begin(115200);   // Establish a serial connection to display data through terminal
  pinMode(CS, OUTPUT);   // Set CS Pin Direction
  digitalWrite(CS, LOW);
  writeRegister(MEASR_CTRL, 0b00000100); // Set Measurement Mode to 2560Hz bandwidth (0x04)
  writeRegister(POWER_CTRL, 0b00000111); // Set full bandwidth measurement mode, HPF disabled (0x07)
  writeRegister(TIME_CTRL, 0b10000000); // Set ODR to 5120 Hz
  digitalWrite(CS, HIGH);
  delay(1);
}

void loop()
{
  Serial.print(" x = "); 
  Serial.print(getValue(x_axis));
  Serial.print(" y = "); 
  Serial.print(getValue(y_axis));
  Serial.print(" z = "); 
  Serial.println(getValue(z_axis));
  delay(0.2);
}

int getValue(int axis)
{
  int AccelData = 0;
  int Offset = 0;
  int high, low; 
  if (axis == 1)
  {
    high = readRegister(XDATA_H);
    low = readRegister(XDATA_L);
  }
  else if (axis == 2)
  {
    high = readRegister(YDATA_H);
    low = readRegister(YDATA_L);
  }
  else if (axis == 3)
  {
    high = readRegister(ZDATA_H);
    low = readRegister(ZDATA_L);
  }
  AccelData = (high << 4) | (low >> 4); // Merge 8 bits from 'high' with upper 4 of 'low' 
  AccelData = (AccelData - Offset)*200; // (Reading-Offset)*ScaleFactor --> 200mg/LSB for ADXL373
  return AccelData;
}

byte readRegister(byte thisRegister)
{
  byte result = 0;   // predeclare result to return
  // ADXL373 expects the register address in the upper 7 bits of the transmitted byte
  // Shift the register bits left by 1 to apply READ bit:
  thisRegister = thisRegister << 1;
  byte dataToSend = thisRegister | READ; // Combine register address with READ command
  digitalWrite(CS,LOW);  //Set the Chip Select pin low to start an SPI packet
  result = SPI.transfer(dataToSend);  // Tell device to read register and save response
  digitalWrite(CS, HIGH);  //Set CS high to close communcation
  return result;
}

void writeRegister(byte thisRegister, byte thisValue)
{
 // ADXL373 expects the register address in the upper 7 bits of the transmitted byte
 // Shift the register bits left by 1 bit to apply WRITE bit:
 thisRegister = thisRegister << 1;
 byte dataWrite = thisRegister & WRITE; // Combine the register address and WRITE command
 byte dataToSend = ((dataWrite << 8) | thisValue);
 digitalWrite(CS,LOW); //Set CS pin low to signal SPI packet start
 SPI.transfer(dataToSend); //Transfer the register address, RW, and desired register value over SPI
 digitalWrite(CS,HIGH); //Set the Chip Select pin high to signal the end of an SPI packet.
}

任何指导都非常感谢。

As a preface, I'm new to Arduino and electronic communication. I'm in the initial stages of an Arduino based accelerometer setup to record high acceleration spikes from impacts. I'm communicating with a single ADXL373 accelerometer to start via SPI.

I've been stuck for a while on the SPI code in that it only will read 0 from all 3 axis. The issue I expect remains with how I'm coding my reads/writes. Does anything standout as egregiously wrong in how I'm executing them?

ADXL373 Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/adxl373.pdf

// ADXL373 400g Accelerometer sensor connected to Arduino 2560 Mega Board

// V5: pin 3.3V
// GND: pin GND
// MOSI: pin 51
// MISO: pin 50
// SCLK: pin 52
// CS: pin 53

// the sensor communicates using SPI, so include the library:
#include <SPI.h>

const int CS = 53; //Chip Select (Arduino Mega Pin 53)

/////////////////////////////////////////////////////////////////////////////////
///////////////////////////// Register Addresses ////////////////////////////////

byte XDATA_H = 0x08; // (0b00001000) X Data Register, High 8 MSB 
byte XDATA_L = 0x09; // (0b00001001) X Data Register, Low 4 MSB 
byte YDATA_H = 0x0A; // (0b00001010) Y Data Register, High 8 MSB 
byte YDATA_L = 0x0B; // (0b00001011) Y Data Register, Low 4 MSB 
byte ZDATA_H = 0x0C; // (0b00001100) Z Data Register, High 8 MSB 
byte ZDATA_L = 0x0D; // (0b00001101) Z Data Register, Low 4 MSB 
byte OFFSET_X = 0x20; // X Data Offset Register, Lower 4 bits
byte OFFSET_Y = 0x21; // Y Data Offset Register, Lower 4 bits
byte OFFSET_Z = 0x22; // Z Data Offset Register, Lower 4 bits
byte TIME_CTRL = 0x3D; // (0b00111101) Timing Control Register -> Select ODR (0b10000000) for 5120 Hz
byte MEASR_CTRL = 0x3E; // (0b00111110) Measurement Control -> Bandwidth set (0b00000100) for 2560 Hz
byte POWER_CTRL = 0x3F; // (0b00111111) Power Control Register -> Op. Mode and HPF off (0b00000111)
const byte WRITE = 0b11111110; // Reads with a 1, high
const byte READ = 0b00000001; // Writes with a 0, low

////////////////////////////////////////////////////////////////////////////////

// Establish variables to identify x, y, and z axis accelerations
int x_axis = 1;
int y_axis = 2;
int z_axis = 3;

void setup() 
{
  SPI.begin(); // Initialize SPI
  SPI.setDataMode(SPI_MODE0);
  SPI.setBitOrder(MSBFIRST); // Data for the device is sent MSB first, RW is last bit
  Serial.begin(115200);   // Establish a serial connection to display data through terminal
  pinMode(CS, OUTPUT);   // Set CS Pin Direction
  digitalWrite(CS, LOW);
  writeRegister(MEASR_CTRL, 0b00000100); // Set Measurement Mode to 2560Hz bandwidth (0x04)
  writeRegister(POWER_CTRL, 0b00000111); // Set full bandwidth measurement mode, HPF disabled (0x07)
  writeRegister(TIME_CTRL, 0b10000000); // Set ODR to 5120 Hz
  digitalWrite(CS, HIGH);
  delay(1);
}

void loop()
{
  Serial.print(" x = "); 
  Serial.print(getValue(x_axis));
  Serial.print(" y = "); 
  Serial.print(getValue(y_axis));
  Serial.print(" z = "); 
  Serial.println(getValue(z_axis));
  delay(0.2);
}

int getValue(int axis)
{
  int AccelData = 0;
  int Offset = 0;
  int high, low; 
  if (axis == 1)
  {
    high = readRegister(XDATA_H);
    low = readRegister(XDATA_L);
  }
  else if (axis == 2)
  {
    high = readRegister(YDATA_H);
    low = readRegister(YDATA_L);
  }
  else if (axis == 3)
  {
    high = readRegister(ZDATA_H);
    low = readRegister(ZDATA_L);
  }
  AccelData = (high << 4) | (low >> 4); // Merge 8 bits from 'high' with upper 4 of 'low' 
  AccelData = (AccelData - Offset)*200; // (Reading-Offset)*ScaleFactor --> 200mg/LSB for ADXL373
  return AccelData;
}

byte readRegister(byte thisRegister)
{
  byte result = 0;   // predeclare result to return
  // ADXL373 expects the register address in the upper 7 bits of the transmitted byte
  // Shift the register bits left by 1 to apply READ bit:
  thisRegister = thisRegister << 1;
  byte dataToSend = thisRegister | READ; // Combine register address with READ command
  digitalWrite(CS,LOW);  //Set the Chip Select pin low to start an SPI packet
  result = SPI.transfer(dataToSend);  // Tell device to read register and save response
  digitalWrite(CS, HIGH);  //Set CS high to close communcation
  return result;
}

void writeRegister(byte thisRegister, byte thisValue)
{
 // ADXL373 expects the register address in the upper 7 bits of the transmitted byte
 // Shift the register bits left by 1 bit to apply WRITE bit:
 thisRegister = thisRegister << 1;
 byte dataWrite = thisRegister & WRITE; // Combine the register address and WRITE command
 byte dataToSend = ((dataWrite << 8) | thisValue);
 digitalWrite(CS,LOW); //Set CS pin low to signal SPI packet start
 SPI.transfer(dataToSend); //Transfer the register address, RW, and desired register value over SPI
 digitalWrite(CS,HIGH); //Set the Chip Select pin high to signal the end of an SPI packet.
}

Any guidance is greatly appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

遗心遗梦遗幸福 2025-02-10 08:20:35

您需要使用两个spi.transfer()语句,例如在用于气压传感器。请参阅第160-164行:

158   // send the device the register you want to read:
159 
160   SPI.transfer(dataToSend);
161 
162   // send a value of 0 to read the first byte returned:
163 
164   result = SPI.transfer(0x00);

第一个语句告诉传感器您要阅读的注册。第二个语句返回数据(此示例中的传感器不像您的ADXL完全工作,因此我认为您不必发送0x00才能启动读取,但是要点是相同的)。

spi.transfer()说的描述它执行“同时发送和接收”,但也可以用作发送接收。

You need to use two SPI.transfer() statements, like in the example in the Arduino SPI Tutorial for a Barometric Pressure Sensor. See lines 160 - 164:

158   // send the device the register you want to read:
159 
160   SPI.transfer(dataToSend);
161 
162   // send a value of 0 to read the first byte returned:
163 
164   result = SPI.transfer(0x00);

The first statement tells the sensor which register you want to read. The second statement returns the data (the sensor in this example does not work exactly like your ADXL, so I don't think you have to send a 0x00 to start a read, but the point is the same).

The description for SPI.transfer() says it performs a "simultaneous send and receive", but that can also be used as a send or receive.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文