AnsweredAssumed Answered

ADIS 16405 Output Problems Using Raspberry Pi

Question asked by aliounis on Apr 22, 2014
Latest reply on Jun 4, 2014 by NevadaMark
Branched to a new discussion

Hello everyone,


I am trying to set up an ADIS 16405 imu using a raspberry pi as the master spi controller, using the GPIO pins on the pi as SPI pins.  I have successfully set up and attached the imu to the pi; however I am getting some weird outputs when I try to read anything from the imu.  I am using the bcm2835 driver (found here) to control the gpio pins on the pi with the following c++ code:


#include <bcm2835.h>
#include <iostream>
#include <cstdint>
#include <cstdio>
#include <cmath>
#include <bitset>
#include <stdlib.h>

using std::cout;
using std::hex;
using std::dec;
using std::cin;
using std::endl;
using std::bitset;

int initialize(void){
     if (!bcm2835_init()){
     return -1;
     bcm2835_spi_begin();  //initializing spi mode on rpi
     bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST); //setting MSB read/write first
     bcm2835_spi_setDataMode(BCM2835_SPI_MODE3); //setting CPOL=1; CPHA=1.
     bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_256); //Setting the clock frequency to 976khz
     bcm2835_spi_chipSelect(BCM2835_SPI_CS0);  //selecting which pin to use for cs line
     bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0,LOW); //setting chip select pin to be active on low signal
     return 0;

int main(int argc, char **argv){
     int suc=initialize();
     if (suc!=0){ //checking to see if the settings were successfully applied
          return -1;

     char buf1[] ={0xBE, 0x80}; //Command to software reset
     bcm2835_spi_transfern(buf1,sizeof(buf1));  //Sending command to ADIS 16405 and receiving output (0's)
     sleep(1);  //pausing system to allow ADIS16405 to fully restart

     char buf[]={0x0E, 0x00, 0x00, 0x00, 0x00};  //Command to read Z axis Accelerometer with space to receive output
     bcm2835_spi_transfern(buf,sizeof(buf));  //Sending command to read ZACCL and receiving output
     printf("The output is: %02x %02x %02x %02x %02x. \n", buf[0], buf[1], buf[2], buf[3], buf[4]);  //printing raw read from device
     uint16_t temp=((uint16_t)buf[3]<<8)+(uint16_t)buf[4];  //extracting data from buffer
     int16_t output2=((int16_t)(temp<<2)>>2);  //extracting twos complement from data
     output2=output2/100;  //converting from lsb to g

     cout<<dec<<output2<<endl;  //outputting final value

     bcm2835_spi_end();  //termining spi mode on rpi
return 0;


The first problem I am having is that the output seems to be shifted by one byte (which is why I have the extra bytes in the buffers above.  As you can see, the output from the ADIS 16405 is not being recorded until the 4th and 5th read bytes (2nd and third bytes read after the read command has bee issued).  Based on my understanding or the operation of this device, this data should be read immediately after the read command has been sent. Overall this is not a large problem, as I can easily work with it but I figured I would throw it in to see if anyone knows anything about it.  I suspect it is just a timing error and that is why it is offsetting.


My next problem is much more of a problem.  The output from the Z axis accelerometer seems to be off by a factor of 3.  I ran this code while the ADIS 16405 was sitting on a counter in an upright position(z axis positive upwards) and received an output of -3 g.  This is obviously not right as it should be reading only 1 g not 3. 


In an attempt at trouble shooting I checked to be sure the output was actually from the axis accelerometer.  To do this i simply adjusted the orientation of the imu and read the results.  When I flipped the imu the result flipped (instead of getting -3g I got 3 g) and when I moved the imu onto its side I got noise(.02-.06 g).  Since these outputs made intuitive sense with the way I was moving the device i do believe this output is coming from the Z axis accelerometer, but I still do not know why it seems to be multiplied by a factor of 3.


Does anyone have any ideas as to why the scale is so far off and some way I can fix it?  I've been pulling my hair out for the last week trying to figure it out.  (It also doesn't help that I am learning everything about spi and c++ programming on the fly).


Thanks so much,