Interfacing ADXL375 problem - Page 1
Forum section: electronics / beginners

author: Vindhyachal.takniki
author_rank: Frequent Contributor
timestamp: December 27, 2014, 04:17:55 pm
content: I have interfaced ADXL375 & I have some below. I have attached the code.1. The offset I am getting is huge.It is 1g approx on both x & y axis & 1.5g on z-axis.I don't know what could be problem. I read offset registers , they are all zero in ADXL375.I had read thread on Analog forum, someone had same problem with offset +4G on z axis.He had removed the IC & resoldered new one & problem gone.But I wan't to know what could be exact reason?2. For ODR <= 800Hz, we multiply register value with 49 to get g value i.e:g = (register_value * 49)But when OCR = 1600 or 3200Hz, what is the factor.I had read in datasheet that in this case LSB is always zero. So what will be coversion factor or it will remain same = 49.3. I had calibrated the adxl375 by placing it in z = +1g & other axis = 0.But I have seen example in which calibrate in all six axis is done:https://learn.adafruit.com/adxl345-digital-accelerometer/programmingBut how to calculate final offset from these six offset values?Or should I take there average.4. Edit: I have been able to read DEV id properly & SPi speed is 3.75Mhz.Code:#define ADXL_REG_DEV_ID (0x00)#define ADXL_VAL_DEV_ID (0xe5)#define ADXL_REG_PW_CTRL (0x2d)#define ADXL_REG_INT_EN (0x2e)#define ADXL_REG_INT_MAP (0x2f)#define ADXL_REG_DATA_FM (0x31)#define ADXL_REG_DATA_RATE (0x2c)#define ADXL_REG_DATAX0 (0x32)void main(void){configure_adxl375();while(1){//take 100 samples & averageadxl_read_offset_values(&x_val , &y_val ,&z_val);x_val *= 49;y_val *= 49;z_val *= 49;//offset for x:1274 , y: 1225 , z:1597}}void adxl_read_g_values(int16_t *x_val , int16_t *y_val , int16_t *z_val){uint8_t values;uint32_t erroradxl_read_reister(ADXL_REG_DATAX0 , 6U , &values);*x_val = (s16_t)( ((u16_t)values << 8U) | ((u16_t)values) ) ;*y_val = (s16_t)( ((u16_t)values << 8U) | ((u16_t)values) ) ;*z_val = (s16_t)( ((u16_t)values << 8U) | ((u16_t)values) ) ;}void configure_adxl375(void){uint8_t data;SPI_MODE(3);data = adxl_read(ADXL_REG_DEV_ID);if(0xe5 != data){error_trap();}/* power ctrl */adxl_write(ADXL_REG_PW_CTRL , 0x00);adxl_write_register(ADXL_REG_DATA_FM , 0x0bU);adxl_write_register(ADXL_REG_DATA_RATE , 0x0dU);adxl_write_register(ADXL_REG_PW_CTRL , 0x08U);}void adxl_write_register(uint8_t address , uint8_t value){ADXL_CS_ENABLE();adxl_spi_byte(address);adxl_spi_byte(value);ADXL_CS_DISABLE();}void adxl_read_reister(uint8_t address , uint32_t no_bytes , uint8_t *values){uint32_t cnt;uint8_t reg_add = 0x80U | address; /* msb is high fro reading */if(no_bytes > 1U) /* for multi read bit 6 is also set */{reg_add = reg_add | 0x40U;}ADXL_CS_ENABLE();/* send address */adxl_spi_byte(reg_add);/* sent bytes */for(cnt = 0U ; (cnt< no_bytes) ; cnt++ ){values = adxl_spi_byte(0xffU);}ADXL_CS_DISABLE();}

author: dgtl
author_rank: Regular Contributor
timestamp: December 27, 2014, 04:51:45 pm
content: I've had the same issues in the past using the same accelerometer. I needed to have factory calibration step during manufacturing. As the datasheet says, the offsets (probably gain, too?) depend on the soldering procedure etc, so you shall measure them after the device is manufactured. During the factory procedure, the device is flipped to each of the 8 sides and the software reads accelerometer values in each of the positions. It's best to measure multiple times in each position and wait until a number sequential samples are close to each other to avoid getting noise from vibrations etc. The gain and the offsets of the channels are then calculated and stored to the device's eeprom. During actual use, you use the constants obtained from the calibration.

author: Vindhyachal.takniki
author_rank: Frequent Contributor
timestamp: December 28, 2014, 05:18:27 pm
content: 1. Way I have done calibration now:I have take gain & offset errros into account.Took two readings in +x axis & -ve axis.Value at +x axis (1000mg) comes out to 1500mg.Value at -x axis(-1000mg) comes out to 789mg.From here I have calculated gain & offset error for x axis, by two point calibration.Similarly for other two axis.Is it correct method?2. Why so much error? Only thermal stress can produce so much error?3.For ODR <= 800Hz, we multiply register value with 49 to get g value i.e:g = (register_value * 49)But when OCR = 1600 or 3200Hz, what is the factor.

author: Vindhyachal.takniki
author_rank: Frequent Contributor
timestamp: December 31, 2014, 01:26:08 am
content: 1. If, ODR = 3200 then number of sampes I can take per sec is 1600 without aliasing right?2. What is the final g value from three axis. Is it:g = ( (x*x + y*y + z*z) ^ 0.5 ) / 33.If I configure ODR = 3200 & not able to take sample at Data ready interrupt. Then does that mean new data will overwrite older data & 3 axis data read can be corrupted or whenever I read 3 axis data it is always reliable & current data?I read 3 axis data at once.

author: Vindhyachal.takniki
author_rank: Frequent Contributor
timestamp: January 01, 2015, 04:42:48 pm
content: Correct answer o my query are:1. 3200Hz2. g = ( (x*x + y*y + z*z) ^ 0.5 )3. New data will overwrite previous data

author: Vindhyachal.takniki
author_rank: Frequent Contributor
timestamp: January 01, 2015, 04:43:13 pm
content: One more query:How to calculate actual acceleration acting on the accelerometer given by me.Like there is always 'g' acting on device due to earth gravity.Can I calculate how much acceleration I am able to give when I run with the device?

author: dgtl
author_rank: Regular Contributor
timestamp: January 01, 2015, 05:31:21 pm
content: Why are you doing it in such difficult way? Get the register values for 1g and -1g. Then you can just calculate your own constants to the linear formula g=reg_value * A + B:1 = reg(1)* A + B-1 = reg(-1)* A + BIf i did not make a mistake, it should solve to:A = 2 / (reg(1)-reg(-1))B = (reg(1)+reg(-1)) / (reg(-1)-reg(1))After calculating your values for A and B, you can easily calculate g for whatever reg value: g=reg_value * A + B.The 1g gravity is always present and adds to the rest of the acceleration. If the device is kept at the same position relative to the gravity, it can be substracted. Otherwise, it is a little more difficult. The gravity is always constant and thus can also be removed by low-pass filter. Digital filtering is a quite complex topic. You could use some FIR or IIR filters, but it would be difficult to get started without former experience. For a simpler and not so good solution you could use moving average filter and just experiment with filter window size. This low-pass filter should give you the approx gravity value and then you could remove it from your signal.Even better solution would calculate the gravity vector angle from all three acceleration components and then substracting the 1g signal at that angle. The complexity of the solution depends on how good result is needed. Also, if the data is stored, much more post-processing can be performed on PC computer; if all the filtering must be done locally, you are bound on the resouces there.