Check my pololu mini 9 IMU code


ive been trying create libraryless arduino program interface pololu miniimu9(http://www.pololu.com/catalog/product/1265) in attempt learn more spi/imus. has l3g4200d(gyro) datasheet , lsm303dlm(acc+mag). can on it? thanks!

code: [select]
#include <wire.h>

#define acc_adr 0b1100000 //(0x30 >> 1), 0x60
#define mag_adr 0b11110 //(0x3c >> 1), 0x1e
#define gyro_adr 0b1101001 //(0d2 >> 1), 0x69

#define acc_en 0x27 //enable acc, normal power mode, axes enabled
#define gyro_en 0x0f //enable gyro
#define mag_en 0x00 //enable mag, continuous conversion mode

//acc registers:
#define acc_ctrl_reg1 0x20
#define lsm303_out_x_l_a 0x28
int accx;
int accy;
int accz;
//bias
int baccx;
int baccy;
int baccz;

//gyro reg
#define l3g4200d_ctrl_reg1 0x20
#define l3g4200d_out_x_l 0x28
int gyrox;
int gyroy;
int gyroz;
//bias
int bgyrox;
int bgyroy;
int bgyroz;

//mag regs
#define mag_reg 0x02
#define lsm303_out_x_h_m 0x03
int magx;
int magy;
int magz;

//yaw
int xmagmax;
int ymagmax;
int zmagmax;
int xmagmin;
int ymagmin;
int zmagmin;
float xmagmap;
float ymagmap;
float zmagmap;

//final values
int pitchaccel;
int pitchgyro;
int rollaccel;
int rollgyro;
float yawraw=0;
float yawu;

void setup() {
 // put setup code here, run once:
 writereg(gyro_adr, l3g4200d_ctrl_reg1, gyro_en); //enable gyro
 writereg(acc_adr, acc_ctrl_reg1, acc_en); //enable acc
 writereg(mag_adr, mag_reg, mag_en); //enable mag

 setupaccel();
}

void loop() {
 // put main code here, run repeatedly:  
 readacc();
 readgyro();
 readmag();
 calculations();
}

void writereg(byte adr, byte reg, byte value)
{
 wire.begintransmission(adr);
 wire.write(reg);
 wire.write(value);
 wire.endtransmission();
}

void readmag()
{
 wire.begintransmission(mag_adr);
 wire.write(lsm303_out_x_h_m);
 wire.endtransmission();
 wire.requestfrom(mag_adr, 6);

 while (wire.available() < 6);

 byte xhm = wire.read();
 byte xlm = wire.read();
 byte zhm = wire.read();
 byte zlm = wire.read();
 byte yhm = wire.read();
 byte ylm = wire.read();

 magx = (xhm << 8 | xlm);
 magy = (yhm << 8 | ylm);
 magz = (zhm << 8 | zlm);
}

void readacc()
{
 wire.begintransmission(acc_adr);
 // assert msb of address accelerometer
 // slave-transmit subaddress updating.
 wire.write(lsm303_out_x_l_a | (1 << 7));
 wire.endtransmission();
 wire.requestfrom(acc_adr, 6);

 while (wire.available() < 6);

 byte xla = wire.read();
 byte xha = wire.read();
 byte yla = wire.read();
 byte yha = wire.read();
 byte zla = wire.read();
 byte zha = wire.read();

 accx = (xha << 8 | xla) >> 4;
 accy = (yha << 8 | yla) >> 4;
 accz = (zha << 8 | zla) >> 4;
}

void readgyro()
{
 wire.begintransmission(gyro_adr);
 // assert msb of address gyro
 // slave-transmit subaddress updating.
 wire.write(l3g4200d_out_x_l | (1 << 7));
 wire.endtransmission();
 wire.requestfrom(gyro_adr, 6);

 while (wire.available() < 6);

 byte xla = wire.read();
 byte xha = wire.read();
 byte yla = wire.read();
 byte yha = wire.read();
 byte zla = wire.read();
 byte zha = wire.read();

 gyrox = xha << 8 | xla;
 gyroy = yha << 8 | yla;
 gyroz = zha << 8 | zla;
}

void setupaccel()
{
 //temporary total holders
 int tgyrox;
 int tgyroy;
 int tgyroz;

 int taccx;
 int taccy;
 int taccz;

 delay(100); //wait stable values
 for(int = 0; i<50; i++) //get values fifty times
 {
   readacc();
   readmag();
   readgyro();

   tgyrox += gyrox; //total gyrox value += current reading
   tgyroy += gyroy;
   tgyroz += gyroz;

   taccx += accx;
   taccy += accy;
   taccz += accz;
 }

 bgyrox = tgyrox / 50; //bias in gyro x = total gyro x/50
 bgyroy = tgyroy / 50;
 bgyroz = tgyroz / 50;

 baccx = taccx / 50;
 baccy = taccy / 50;
 baccz = (taccz / 50) - 256; //don't compensate gravity away! (float)!
}


void calculations()
{
 //calculate pitch in degrees measured accelerometers. note 8g 11 bits gives 256 bits/g
 pitchaccel = atan2((accy - baccy) / 256, (accz - baccz) / 256) * 360.0 / (2*pi);
 //calculate pitch in degrees measured gyros, angle = angle + gyro reading * time step.
 pitchgyro = pitchgyro + ((gyrox - bgyrox) / 70) * 0.02; //0.02 = gyro angle/sec
 //ditto roll
 rollaccel = atan2((accx - baccx) / 256, (accz - baccz) / 256) * 360.0 / (2*pi);
 rollgyro = rollgyro - ((gyroy - bgyroy) / 70) * 0.02; //0.02 = gyro angle/sec

 //yaw!
 //this part required normalize magnetic vector
 //get min , max reading magic axis
 if (magx>xmagmax) {xmagmax = magx;}
 if (magy>ymagmax) {ymagmax = magy;}
 if (magz>zmagmax) {zmagmax = magz;}
 
 if (magx<xmagmin) {xmagmin = magx;}
 if (magy<ymagmin) {ymagmin = magy;}
 if (magz<zmagmin) {zmagmin = magz;}

 //map incoming data -1 1
 xmagmap = float(map(magx, xmagmin, xmagmax, -30000, 30000))/30000.0;
 ymagmap = float(map(magy, ymagmin, ymagmax, -30000, 30000))/30000.0;
 zmagmap = float(map(magz, zmagmin, zmagmax, -30000, 30000))/30000.0;

 //normalize magnetic vector
 float norm = sqrt( sq(xmagmap) + sq(ymagmap) + sq(zmagmap));
 xmagmap /=norm;
 ymagmap /=norm;
 zmagmap /=norm;

 float pitch = (pitchaccel+pitchgyro)/2;
 float roll = (rollaccel+rollgyro)/2;

 //compare "applications of magic sensors low cost compass systems" michael j. caruso
 //for compensated yaw equations...
 //http://www.ssec.honeywell.com/magnetic/datasheets/lowcost.pdf
 yawraw=atan2( (-ymagmap*cos(roll) + zmagmap*sin(roll) ), (xmagmap*cos(pitch) + ymagmap*sin(pitch)*sin(roll)+ zmagmap*sin(pitch)*cos(roll)) ) *180/pi;
 yawu=atan2(-ymagmap, xmagmap) *180/pi;
}



Arduino Forum > Using Arduino > Programming Questions > Check my pololu mini 9 IMU code


arduino

Comments

Popular posts from this blog

Thread: PKI Client 5.00 install (for eToken Pro)

ATmega2560-Arduino Pin Mapping

Crossfader Arduino Tutorial