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
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
Post a Comment