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.
8 years, 4 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