Hello i'm having issues interfacing with an adxl 314 using my arduino, here is my code (sorry for the mess)
//Add the SPI library to communicate with the ADXL314 sensor
#include <SPI.h>
//Assign the Chip Select signal to pin 10.
const int CS=10;
//This is a list of some of the registers available on the ADXL314.
//To learn more about these and the rest of the registers on the ADXL314
char POWER_CTL = 0x2D; //Power Control Register
char DATA_FORMAT = 0x31; // selects data format 3 wire or 4 wire
char INT_EN = 0x2E;// Enables DATA_INTERRUPT
char INT_SOURCE = 0x30; //interrupt source read only
char DEVID = 0x00;
char BW_RATE = 0x2C;
char FIFO_CTL = 0x38;
//notes: maybe change the 3 to Bs on register adress
char DATAx0 = 0x02;
char DATAx1 = 0x03;
char DATAy0 = 0x04;
char DATAy1 = 0x05;
char DATAz0 = 0x06;
char DATAz1 = 0x07;
//where values are stored
unsigned char values[10] = {0,0,0,0,0,0,0,0,0,0} ;
//These variables will be used to hold the x,y and z axis accelerometer values.
int x,y,z = 0;
//used to hold the XYZ sums
signed long sumX, sumY, sumZ;
//used to hold the XYZ rms
unsigned long rmsX, rmsY, rmsZ;
//min and max values
signed long Xmin, Xmax, Ymin, Ymax, Zmin, Zmax = 0;
void setup(){
//Initiate an SPI communication instance.
Serial.begin(9600);
::sumX = 0;
::sumY = 0;
::sumZ = 0;
//Set up the Chip Select pin to be an output from the Arduino.
pinMode(CS, OUTPUT);
pinMode(9, OUTPUT);
//Before communication starts, the Chip Select pin needs to be set high.
digitalWrite(9, HIGH);
digitalWrite(CS, HIGH);
delay(110);
//Create a serial connection to display the data on the terminal.
SPI.begin();
//Configure the SPI connection for the ADXL314.
SPI.beginTransaction(SPISettings(5000000, MSBFIRST, SPI_MODE3));
//for 3 wire SPI: 01101111
//for 4 wire SPI: 00101111
//bit 2 is the justify bit, 1 = MSB, 0 = LSB
// maybe write data format into 0x01
WriteRegister(DATA_FORMAT, 0x0B);
WriteRegister(DATA_FORMAT,0x0B);//0F
WriteRegister(POWER_CTL,0x00);
//bypassing and setting up FIFO mode
//WriteRegister(FIFO_CTL, 0x00);
//set up preffered interrupt (source)
//activity enable
//WriteRegister(0x27, 0x00);
//Enables interrupts
WriteRegister(INT_EN, 0x80);
//wakes up device and starts reading mode
WriteRegister(POWER_CTL,0x08);
//Data rate set to 3200 max?
WriteRegister(BW_RATE, 0x09);
Serial.println("DATAFORMAT");
ReadRegister(POWER_CTL, 8);
Serial.println(values[8]);
Serial.println("DEVID");
ReadRegister(DEVID, 6);
Serial.println(values[6]);
if (values[6] != 0xE5){
Serial.println("Sucks to suck");
}
}
//
void loop(){
//
//
// while (values[6] == 0xE5){
// Doshit5200();
// //RMS Calculation
// rmsX = sqrt(sumX / 5200);
// rmsY = sqrt(sumY / 5200);
// rmsZ = sqrt(sumZ / 5200);
//
//
// Serial.print("X rms: ");
// Serial.println(rmsX);
// Serial.print("Y rms: ");
// Serial.println(rmsY);
// Serial.print("Z rms: ");
// Serial.println(rmsZ);
// Serial.print("x max: ");
// Serial.println(Xmax);
// Serial.print("y max: ");
// Serial.println(Ymax);
// Serial.print("z max: ");
// Serial.println(Zmax);
// Serial.print("x min: ");
// Serial.println(Xmin);
// Serial.print("y min: ");
// Serial.println(Ymin);
// Serial.print("z min: ");
// Serial.println(Zmin);
//
// }
ReadData();
Serial.println(x);
Serial.println(y);
Serial.println(z);
}
void WriteRegister(char registerAddress, char value){
//Set Chip Select pin low to signal the beginning of an SPI packet.
digitalWrite(CS, LOW);
//Transfer the register address over SPI.
SPI.transfer(registerAddress & 0x7F);
//Transfer the desired register value over SPI.
SPI.transfer(value);
//Set the Chip Select pin high to signal the end of an SPI packet.
digitalWrite(CS, HIGH);
delay(50);
}
char ReadRegister(char registerAddress, int BufferAddress){
digitalWrite(CS,LOW);
SPI.transfer(registerAddress);
//SPI.transfer(registerAddress | 0x80);
SPI.transfer(0x80 | registerAddress); // Send the address with read bit set
values[BufferAddress] = SPI.transfer(0x00);
digitalWrite(CS, HIGH);
delay(5);
}
//This function will read a certain number of registers starting from a specified address and store their values in a buffer.
//Parameters:
// char registerAddress - The register address to start the read sequence from.
// int numBytes - The number of registers that should be read.
// char * values - A pointer to a buffer where the results of the operation should be stored.
void readRegisters(char registerAddress, int numBytes){
//Since we're performing a read operation, the most significant bit of the register address should be set.
char address = 0x80 | registerAddress;
//If we're doing a multi-byte read, bit 6 needs to be set as well.
address = address | 0x40;
//Set the Chip select pin low to start an SPI packet.
digitalWrite(CS, LOW);
//Transfer the starting register address that needs to be read.
SPI.transfer(address);
//Continue to read registers until we've read the number specified, storing the results to the input buffer.
for(int i=0; i<numBytes; i++){
values[i] = SPI.transfer(0x00);
}
//Set the Chips Select pin high to end the SPI packet.
digitalWrite(CS, HIGH);
delay(5);
}
// Function to check if a specific bit is set (1) or not (0)
//value is the value you wanna check like a value read from a register
//bit position is the position of the bit you wanna check 0 as LSB
bool isBitSet(uint16_t value, int bitPosition) {
return (value & (1 << bitPosition)) != 0;
}
//Test function
void ReadData(){
delay(5);
//check DEV ID
ReadRegister(0x00, 6);
// read from INT_SOURCE
ReadRegister(INT_SOURCE, 7);
// see if bit 7 is set, then read data
if (isBitSet(values[7],7)){
Serial.println("New Data Ready!");
//readRegisters(DATAx0, 6);
//The ADXL314 gives 13-bit acceleration values, but they are stored as bytes (8-bits). To get the full value, two bytes must be combined for each axis.
//The X value is stored in values[0] and values[1].
x = values[1] <<8 | values[0];
//The Y value is stored in values[2] and values[3].
y = values[3] <<8 | values[2];
//The Z value is stored in values[4] and values[5].
z = values[5] <<8 | values[4];
//maybe add (int) before values
x = (twosComplementToSignedInt(x, 13)*0.049);// gives values in grams per LSB
y = (twosComplementToSignedInt(y, 13)*0.049);
z = (twosComplementToSignedInt(z, 13)*0.049);
}else{
Serial.println("waiting for new data");
}
}
//function to be performed 5200 times
void Doshit5200(){
for (int i = 0; i < 3200; i++) {
ReadRegister(0x00, 6);
ReadData();
// ReadRegister(DATAx0, 0);
// ReadRegister(DATAx1, 1);
// ReadRegister(DATAy0, 2);
// ReadRegister(DATAy1, 3);
// ReadRegister(DATAz0, 4);
// ReadRegister(DATAz1, 5);
//The ADXL314 gives 13-bit acceleration values, but they are stored as bytes (8-bits). To get the full value, two bytes must be combined for each axis.
//The X value is stored in values[0] and values[1].
x = (((int)values[1]) <<8) | (int)values[0];
//The Y value is stored in values[2] and values[3].
y = (((int)values[3]) <<8) | (int)values[2];
//The Z value is stored in values[4] and values[5].
z = (((int)values[5]) <<8) | (int)values[4];
//maybe add (int) before values
twosComplementToSignedInt(x, 16);
twosComplementToSignedInt(y, 16);
twosComplementToSignedInt(z, 16);
x = (x/20.48)*48.83; //mg/LSB scale factor.)
y = (y/20.48)*48.83;
z = (z/20.48)*48.83;
if (::Xmax < x){
::Xmax = x;
}
if (::Xmin > x){
::Xmin = x;
}
if (::Ymax < y){
::Ymax = y;
}
if (::Ymin > y){
::Ymin = y;
}
if (::Zmax < z){
::Zmax = z;
}
if (::Zmin > z){
::Zmin = z;
}
::sumX += sq(x);
::sumY += sq(y);
::sumZ += sq(z);
}
}
// Function to convert two's complement to signed integer
int twosComplementToSignedInt(uint16_t value, int numBits) {
if (value & (1 << (numBits - 1))) { // If the most significant bit is set (indicating negative number)
value |= ~((1 << numBits) - 1); // Perform two's complement operation
}
return static_cast<int>(value); // Cast the result to signed integer
}
And this is the board im interfacing with, any ideas?
