SPI anomolies logging data from ADIS16405 IMU


greetings,

i'm using arduino mega log data adis16405 imu, product of analog devices.  communication uses spi protocol, , procedure is:

1. request burst of data imu
2. read data imu , convert readable numbers
3. write data serial port (logger or computer serial monitor)

there no "checksum" , way check valid data confirm makes sense.  example, supply voltage should 5 v.  if far off, know data corrupted , declare "invalid". 

the problem: every couple seconds, 2 invalid data responses.  however, interesting part how occurs affected baud rate in step 3.  example, if i'm writing data out @ 115,200 bps invalid imu data every 3 seconds.  if instead, write data @ 9600 bps, i  no invalid data @ all.  tried write @ faster speed, add delay mimic longer write time, invalid data still appeared. 

i've attached code reference below.  interestingly, here (http://forum.arduino.cc/index.php?topic=40411.msg295825#msg295825) had similar problems version of analog devices imu. 

any suggestions on how write fast, avoid invalid data?  seems odd performance connected, since 1 serial , other spi.

-hamid


code: [select]

const int reset_pin = 6;
const int chipselectpin = 7;

boolean read_flag = false;

#include <spi.h>
#include "datatype.h"

imu isense_data;

void setup(){
  serial1.begin(921600); // debugging
 
  // start spi library , setup adis 16405
  pinmode(chipselectpin, output);
  digitalwrite(chipselectpin, high); // disable device start with
  spi.setbitorder(msbfirst);
  spi.setclockdivider(spi_clock_div8);
                      // defulat on mega (16 / 4 mhz
                      // adis 16405 should <= 2 mhz
  spi.setdatamode(spi_mode3);
 
  // initializ reset pin , set 5v
  pinmode(reset_pin, output);
  digitalwrite(reset_pin, high);
 
  spi.begin();
  delay(1000);
 

}

void loop(){
  delay(10);
   
  read_imu(&isense_data);
 
 
}
 
void read_imu(struct imu *imudata_ptr ){
  // references: http://ez.analog.com/message/54453#54453

  // send register address

  digitalwrite(chipselectpin, low);
  // burst mode din sequence: 0x3e00
  spi.transfer(0x3e);
  spi.transfer(0x00);
  digitalwrite(chipselectpin, high);


  // umn uav code delay here wait imu respond, but
  // testing showed or without delay things working fine.
  // delaymicroseconds(1); // if using delay, revist delay value


  // initialize variables.  burst mode, according documentation, should
  // output 12 messages, starting supply_out , ending aux_adc.
  // however, testing (and uav code) showed 13 messages needed in order
  // last message's "nd flag" zero, indicating no more data read.
 
  const int responselength = 13*2;
  unsigned int tmp;
  int outputdata[13];
  byte response[responselength]={0};
 

  // read burst mode data
  // note: correct operation on mega, observed on/off of the
  //       chip select pin must occur inside loop.  doing otherwise causes intermittent
  //       data corruption.  reason partly unclear me.
  (int k = 0; k < responselength; k++) {
    digitalwrite(chipselectpin, low);
    response[k] = spi.transfer(0x00);  // send value of 0 read first byte returned:
    digitalwrite(chipselectpin, high);
  }

  /*
  (int k = 0; k < responselength; k++) {
    serial.print(response[k], bin);
    serial.println(" ");
  } */

 
  // inertial sensor outputs in 14-bit, twos complement format
  // combine data bytes; each regsister covers 2 bytes, uses 14 bits.
  ( int = 0; < responselength; += 2 ) {
    // 2 byte message, upper byte arrived
    // first , lower byte.  hence, combine
    // first 6 bits of upper byte lower
    // byte unsigned int.
    tmp = (response[i] & 0x3f) * 256 + response[i+1];
   
    // next, convert 14 bit unsigned int the
    // two's complement format , store (signed) int.
    // if statement that. 
    if ( tmp > 0x1fff ) {
      outputdata[i/2] = (int)(-(0x4000 - tmp));
    }
      else {
      outputdata[i/2] = (int)tmp;
    }
  }
 
 
  // set status flag if supply voltage within 4.75 5.25
if ((outputdata[0]*0.002418 > 4.25) && (outputdata[0]*0.002418 < 5.25)){

          imudata_ptr->err_type = data_valid;
  // update imupacket
  // *imp* imu axis alignment different: z=-z_body, y=-y_body
  imudata_ptr->vs = outputdata[0]*0.002418; //unit: volt
  imudata_ptr->p  = outputdata[1]*0.05; //unit: deg/s
  imudata_ptr->q  = outputdata[2]*0.05;
  imudata_ptr->r  = outputdata[3]*0.05;
  imudata_ptr->ax = outputdata[4]*0.00333; //unit: g's
  imudata_ptr->ay = outputdata[5]*0.00333;
  imudata_ptr->az = outputdata[6]*0.00333;
  imudata_ptr->hx = outputdata[7]*0.0005; //unit: gauss
  imudata_ptr->hy = outputdata[8]*0.0005;
  imudata_ptr->hz = outputdata[9]*0.0005;
  imudata_ptr->t  = 25.0 + outputdata[10]*0.14; //unit: degrees celcius
  imudata_ptr->adc = outputdata[11]*0.000806; //unit: volt
 
       
        //serial.print("time: ");
        serial1.print(millis());
        serial1.print("\t");
       
        //serial1.print("supply voltage: ");
        serial1.print(imudata_ptr->vs);
        serial1.print("\t");
       
        //print accelerometer outputs
       
        serial1.print(imudata_ptr->ax);
        serial1.print("\t");
        serial1.print(imudata_ptr->ay);
        serial1.print("\t");
        serial1.print(imudata_ptr->az);
        serial1.print("\t");
       
        serial1.print(imudata_ptr->p);
        serial1.print("\t");
        serial1.print(imudata_ptr->q);
        serial1.print("\t");
        serial1.print(imudata_ptr->r);
        serial1.print("\n");
       
        } else {
        unsigned long t = millis();
        serial1.print("#-- invalid -- ");
        serial1.println(t);
       
        }
        //delay(50);

}
 
 



Arduino Forum > Using Arduino > Networking, Protocols, and Devices (Moderator: fabioc84) > SPI anomolies logging data from ADIS16405 IMU


arduino

Comments

Popular posts from this blog

Convierte tu Raspberry en un NAS. Firmware fvdw-sl 15.3 - Raspberry Pi Forums

How to format a Get Request

avrdude: verification error, first mismatch at byte 0x0000 0x0c != 0x62