Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
9 years, 2 months ago.
ADXL313 erronneous data related to Z axis
Hi,
I have written code for the Nucleo-F401RE to read from the ADXL313 accelerometer and print it to a PC via serial. I initially did this with I2C which worked fine, however in my strive for extra speed I have moved to SPI, this is where the issues arise.
At times the data reads normally as can be seen in in the following example:
- -0.070,-0.383,0.499,1
- -0.066,-0.381,0.499,1
- -0.064,-0.381,0.499,1
- -0.072,-0.377,0.499,1
- -0.070,-0.400,0.499,1
However at times (it seems when the z axis reading near 0) it will change and give readings of -0.001 on all axis like following:
- -0.001,-0.001,-0.001,1
- -0.001,-0.001,-0.001,1
- -0.001,-0.001,-0.001,1
- -0.001,-0.001,-0.001,1
- -0.001,-0.001,-0.001,1
and then at what seems like random; in certain positions it will read -0.503 which is out of bounds of the reading so I have no idea how it gets that?:
- -0.503,-0.503,-0.503,1
- -0.503,-0.503,-0.503,1
- -0.503,-0.503,-0.503,1
- -0.503,-0.503,-0.503,1
- -0.503,-0.503,-0.503,1
the limits are 0.5g each way (saturates 0.499 on the positive) Does anyone have any idea what my problem could be related to?
Below I have included a trimmed down version of my code if that helps?
main.cpp mbed code cut down for simplicity
#include "myheader.h"
SPI device(SPI_MOSI, SPI_MISO, SPI_SCK);
DigitalOut CS(SPI_CS);
Serial pc(SERIAL_TX, SERIAL_RX);
char data_read[6];
char data_write[2];
int count = 0;
int flag = 0;
void readSlowAccelero(){
// Read raw data
CS = 0;
device.write(0x80|0x40|DATA_X0);
for (int i = 0; i<=5; i++){
data_read[i]=device.write(0x00); // read back 6 data bytes
}
CS = 1;
float X = bytes2val(data_read[1], data_read[0]); //combine the 2 bytes and convert to units of 'g'
float Y = bytes2val(data_read[3], data_read[2]);
float Z = bytes2val(data_read[5], data_read[4]);
pc.printf("%.3f,%.3f,%.3f,%d\r\n", X, Y, Z, flag);
}
int main()
{
t.start();
pc.baud(460800);
CS = 1;
device.format(8,3); // 8 bit data, Mode 3
device.frequency(1000000); // 1MHz clock rate
softReset();
whoisAccelero(); // Read ID, version and serial numbers
startAccelerometer(); // Configure the accelerometer sensor device ADXL313
while(1){
readSlowAccelero();
}
}
Function file
#include "myheader.h"
// Function to write a byte (data) to a register (reg)
void write(int reg, int data){
CS = 0;
device.write(reg);
device.write(data);
CS = 1;;
}
// Reads a register (regi) and prints it to pc serial with a name (regLabel)
void printRegister(int regi, char* regLabel){
CS = 0;
device.write(0x80|regi);
data_read[0] = device.write(0x00);
CS = 1;
pc.printf("%s = %#X\r\n", regLabel, data_read[0]);
}
// Performs a soft reset and reports it to PC serial
void softReset(){
write(SOFT_RESET, RESET_VALUE);
pc.printf("-----System Reset----- \r\n");
}
// Initialises the accelerometer after this it is in full speed read mode
void startAccelerometer(){
write(DATA_FORMAT, 0b00000000);
write(BW_RATE, 0b00001110);
// write(OFS_Z, 0x80);
write(POWER_CTL, 0b01001000);
pc.printf("Accelerometer enabled, testing serial ... \r\n");
printRegister(XID, "Serial Number");
}
// Returns the 5 ID registers of the accelero as a kind of POST,
// NOTE: Serial number will only take a value after startAccelerometer() is run
void whoisAccelero(){
printRegister(DEVID_0, "Device ID 0");
printRegister(DEVID_1, "Device ID 1");
printRegister(PARTID, "Part ID");
printRegister(REVID, "Silicon Revision");
printRegister(XID, "Serial Number");
}
// takes the 2 bytes from reading the data registers and combines them before
// converting into units of "g" - reg0 holds the LSB
float bytes2val(char reg1, char reg0){
int16_t temporaryX = (reg1 << 8) + reg0;
return (float)temporaryX / 1024;
}
and for completion here is the header too:
myheader.h
#ifndef FLAGS_H #define FLAGS_H #include "mbed.h" // Variables static const int RESET_VALUE = 0x52; // Value to soft reset device // DEVICE ADDRESS static const int ALT_WRITE_REG = 0xA6; // Alternative address + Write static const int ALT_READ_REG = 0xA7; // Alternative address + Read // REGISTER ADDRESS VALUES static const int DEVID_0 = 0x00; // Device Analog Devie ID (Read) static const int DEVID_1 = 0x01; // Device ADXL313 ID (Read) static const int PARTID = 0x02; // Part ID (Read) static const int REVID = 0x03; // Silicon revision (Read) static const int XID = 0x04; // Semiunique serial number (Read) static const int SOFT_RESET = 0x18; // Soft reset (R/W) // OFFSET REGISTERS (R/W) static const int OFS_Z = 0x20; // z-axis offset register // DATA REGISTERS (Read) static const int DATA_X0 = 0x32; // REGISTERS static const int POWER_CTL = 0x2D; static const int BW_RATE = 0x2C; static const int DATA_FORMAT = 0x31; extern SPI device; extern Serial pc; extern DigitalOut myled; extern DigitalOut CS; extern char data_read[]; extern char data_write[]; void write(int reg, int data); void printRegister(int regi, char* regLabel); void softReset(); void startAccelerometer(); void whoisAccelero(); float bytes2val(char reg1, char reg2); #endif