Hi all,
I've been stuck troubleshooting code for an ADXL373 accelerometer communicating through SPI. I get 0 for the acceleration on all 3 axis so I went back to confirming reads from static registers first.
The issue is I always read 0 from those static registers. However, if I switch SPI mode from 0 to 2 or 3, I read non-zero. Those nonzero values though are not the correct reports for the respective registers. (e.g. for the register DEVID_MST, SPI Mode 2 reads 0x0C and Mode 3 reads 0x18 instead of the correct 0x1D). The ADXL373 is supposed to be SPI Mode 0 (CPOL = 0, clock idle low, CPHA = 0, data read on rising edge).
My code is follows the examples from Arduino the Barometric Pressure Sensor and ADXL345, so I'm stumped why I can't establish this simple communication. Is there some configuration or setup step I've overlooked?
ADXL373 Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/adxl373.pdf
// Circuit:
// 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 AD_ID = 0X00; // Register containing Analog Device ID
byte MEMS_ID = 0x01; // Register containing Analog Device's MEMS ID
byte PART_ID = 0x02; // Register containing Analog Device's Product ID
byte REV_ID = 0x03; // Register containing Analog Device's Revision ID
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;
int Offset = 0;
void setup()
{
SPI.begin(); // Initialize SPI
SPI.setDataMode(SPI_MODE0); // CPOL = 0, clock idles low, CPHA = 0, data is clocked on rising edge
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
byte ID_Check = readRegister(0x02);
Serial.println("Binary Read: ");
Serial.println(ID_Check, BIN);
Serial.println("Hex Read: ");
Serial.println(ID_Check, HEX);
digitalWrite(CS, HIGH);
delay(1);
}
void loop()
{
//Serial.print(" x = "); Commented out until static register read resolved
//Serial.print(getValue(x_axis));
//Serial.print(" y = ");
//Serial.print(getValue(y_axis));
//Serial.print(" z = ");
//Serial.println(getValue(z_axis));
//delay(2000);
}
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);
}
unsigned int 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
Serial.println("Merged Register w/ READ: ");
Serial.println(dataToSend, BIN);
digitalWrite(CS, LOW); //Set the Chip Select pin low to start an SPI packet
SPI.transfer(dataToSend); // Tell device register to read from
result = SPI.transfer(0x00); // Binary word read
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
digitalWrite(CS,LOW); //Set CS pin low to signal SPI packet start
SPI.transfer(dataWrite); // Transfer the register address, RW
SPI.transfer(thisValue); // Transfer the value to write
digitalWrite(CS,HIGH); //Set the Chip Select pin high to signal the end of an SPI packet.
}