CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

IMU 3000 I2C Question
Goto page Previous  1, 2, 3, 4  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
dorinm



Joined: 07 Jan 2006
Posts: 38

View user's profile Send private message

PostPosted: Fri Nov 29, 2013 4:33 pm     Reply with quote

ths is a quick'n'dirty port from here http://www.hobbytronics.co.uk/arduino-adxl345-imu3000 , so it might work or it might not, check it out;
...as I understand, you must first configure the IMU3000 to know on which address is your ADXL, so that it is "aware" of it, because ADXL is a slave to imu3000, not to your bus

Code:

#define IMU3000_WR 0xD0
#define IMU3000_RD 0xD1

#define IMU3000_REG_X 0x1D //GYRO_XOUT_H address

#define ADXL_POWER_CTL 0x2D
#define IMU_ADXL_WR 0x53 //beware!!! it is the real address!!!
#define I2C_ADXL_WR 0xA6 //by PIC, 8 bits, lsb 0

void sensors_init()
{
   //Sample Rate 1kHz, Filter Bandwidth 42Hz, Gyro Range 500 d/s
   i2c_start(IC1);
   i2c_write(IC1,IMU3000_WR);
   i2c_write(IC1,0x16);
   i2c_write(IC1,0x0B);
   i2c_stop(IC1);
   delay_ms(5);
   
   //set accel register data address
   i2c_start(IC1);
   i2c_write(IC1,IMU3000_WR);
   i2c_write(IC1,0x18);
   i2c_write(IC1,0x32);
   i2c_stop(IC1);
   delay_ms(5);
   
   //set accel i2c slave address
   //AUX_ID, the 7-bit accelerometer slave address, is used
   //to access the accelerometer so that its sensor reading
   //can be automatically read during each sample period at the same time as the gyro sensors.
   //...
   //When reading the external accelerometer registers,
   //the IMU-3000 takes over the secondary I2C bus,
   //as a master to the accel, performing a burst read of the sensor registers.
   //For this interface to be active, the AUX_IF_EN flag in the User Control register (61) must be set (set to 1).
   i2c_start(IC1);
   i2c_write(IC1,IMU3000_WR);
   i2c_write(IC1,0x14); //Register 20 – AUX (Accel) Slave Address
   i2c_write(IC1,IMU_ADXL_WR);
   i2c_stop(IC1);
   delay_ms(5);
   
   //of what is next, i'm not sure, but as far as I understand from the IMU3000 register map
   //you also need to configure the ADXL starting address, for reading, 0x32
   //...
   ///This register configures the burst-mode-read starting address for an
   //accelerometer attached to the secondary I2C bus of the IMU-3000,
   //and determines the I/O logic levels of the secondary I2C bus clock and data lines (AUX_CL, AUX_DA).
   i2c_start(IC1);
   i2c_write(IC1,IMU3000_WR);
   i2c_write(IC1,0x18); //AUX (Accel) Burst Read Address / Secondary I2C Bus I/O Level
   i2c_write(IC1,0x32);
   i2c_stop(IC1);
   delay_ms(5);

   //Set passthrough mode to Accel so we can turn it on
   i2c_start(IC1);
   i2c_write(IC1,IMU3000_WR);
   i2c_write(IC1,0x3D); //Register 61 – User Control
   i2c_write(IC1,0x08); //Set the AUX interface active and also reset the AUX interface
   i2c_stop(IC1);
   delay_ms(5);
   
   //here might be the catch, as imu3000 knows 7bit i2c addres yet
   //PIC is using 8bit addres
   //so let's teach IMU of the real "philips" addres and hope
   //it'll not bother us when we'll try to configure
   //the ADXL using PIC address   
   
   //set accel power control to 'measure'
   i2c_start(IC1);
   i2c_write(IC1,PIC_ADXL_WR);
   i2c_write(IC1,ADXL_POWER_CTL);
   i2c_write(IC1,0x08);
   i2c_stop(IC1);
   delay_ms(5);
   // here we may also setup other ADXL345 parameters, like filtering
   /*
   
   //data format, by default it is in 10bit mode (0x00)
   // we can set it to FULL RESOLUTION
   i2c_start(IC1);
   i2c_write(IC1,ADXL_WR);
   i2c_write(IC1,0x31);
   i2c_write(IC1,0x28); //FULL_RES
   i2c_stop(IC1);
   delay_ms(5);
 
   //data rate, we keep it@ 50Hz as by default
   i2c_start(IC1);
   i2c_write(IC1,ADXL_WR);
   i2c_write(IC1,0x2C);
   i2c_write(IC1,0x09); //50HZ, 0x0A for 100Hz
   i2c_stop(IC1);
   delay_ms(5);
   */
   
   //cancel pass through to accel, gyro will now read accel for us
   i2c_start(IC1);
   i2c_write(IC1,IMU3000_WR);
   i2c_write(IC1,0x3D);
   i2c_write(IC1,0x08);
   i2c_stop(IC1);
   delay_ms(5);
   

}


//this might be called from a loop, we assume that we've using
//acc_x, acc_y, acc_z, gy_x, gy_y, gy_z variables of int16 type
void sensors_read()
{
   int8 i;
   int8 buff[12];
   
   i2c_start(IC1);
   i2c_write(IC1,IMU3000_WR);
   //Register Address GYRO_XOUT_H,
   //meaning we'll start reading from there 12bytes of G_XYZ and ACC_XYZ, in pairs
   i2c_write(IC1,IMU3000_REG_X);
   i2c_stop(IC1);
   
   i2c_start(IC1);
   i2c_write(IC1,IMU3000_RD);
   i2c_write(IC1,12); //we're requesting 12bytes of data
   
   buff[ 0]=i2c_read(IC1,1);
   buff[ 1]=i2c_read(IC1,1);
   buff[ 2]=i2c_read(IC1,1);
   buff[ 3]=i2c_read(IC1,1);
   buff[ 4]=i2c_read(IC1,1);
   buff[ 5]=i2c_read(IC1,1);
   buff[ 6]=i2c_read(IC1,1);
   buff[ 7]=i2c_read(IC1,1);
   buff[ 8]=i2c_read(IC1,1);
   buff[ 9]=i2c_read(IC1,1);
   buff[10]=i2c_read(IC1,1);
   buff[11]=i2c_read(IC1,0);
   
   i2c_stop(IC1);
   
   gy_x=(signed int16)make16(buff[0],buff[1]);
   gy_y=(signed int16)make16(buff[2],buff[3]);
   gy_z=(signed int16)make16(buff[4],buff[5]);
   
   // Accel is LSB first. Also because of orientation of chips
   // accel y output is in same orientation as gyro x
   // and accel x is gyro -y, so you have to check the values!!!
   acc_x=(signed int16)make16(buff[ 7],buff[ 6]);
   acc_y=(signed int16)make16(buff[ 9],buff[ 8]);
   acc_z=(signed int16)make16(buff[11],buff[10]);

}




edit: forgot to mention
#use I2C( SCL=PIN_C3, SDA=PIN_C4, MASTER, FAST=400000, STREAM=IC1)
...modify by your needs


Last edited by dorinm on Fri Nov 29, 2013 5:31 pm; edited 4 times in total
Zdetier



Joined: 28 Nov 2013
Posts: 28
Location: Stillwater, OK

View user's profile Send private message

PostPosted: Fri Nov 29, 2013 4:53 pm     Reply with quote

dorinm, Thank you so much for putting some input in, unfortunately that is the arduino version of the code I had a similar version of my earlier code, the output is always

0,0,0,0,0,0 the registers in the gyro are all zero, not sure why this is!
dorinm



Joined: 07 Jan 2006
Posts: 38

View user's profile Send private message

PostPosted: Fri Nov 29, 2013 5:18 pm     Reply with quote

..aaand , the other solution:
to read directly the ADXL , THRU' the IMU3000



Code:

#define IMU3000_WR 0xD0
#define IMU3000_RD 0xD1

#define IMU3000_REG_X 0x1D //GYRO_XOUT_H address

#define ADXL_POWER_CTL 0x2D
#define IMU_ADXL_WR 0x53 //beware!!! it is the real address!!!

#define PIC_ADXL_WR 0xA6 //by PIC, 8 bits, lsb 0
#define PIC_ADXL_RD 0xA7 //by PIC, 8 bits, lsb 0

void sensors_init()
{
   //Sample Rate 1kHz, Filter Bandwidth 42Hz, Gyro Range 500 d/s
   i2c_start(IC1);
   i2c_write(IC1,IMU3000_WR);
   i2c_write(IC1,0x16);
   i2c_write(IC1,0x0B);
   i2c_stop(IC1);
   delay_ms(5);
   
 
   //set accel i2c slave address
   i2c_start(IC1);
   i2c_write(IC1,IMU3000_WR);
   i2c_write(IC1,0x14); //Register 20 – AUX (Accel) Slave Address
   i2c_write(IC1,IMU_ADXL_WR);
   i2c_stop(IC1);
   delay_ms(5);
   
   //Set passthrough mode to Accel so we can turn it on
   i2c_start(IC1);
   i2c_write(IC1,IMU3000_WR);
   i2c_write(IC1,0x3D); //Register 61 – User Control
   i2c_write(IC1,0x08); //Set the AUX interface active and also reset the AUX interface
   i2c_stop(IC1);
   delay_ms(5);
   
   //here might be the catch, as imu3000 knows 7bit i2c addres yet
   //PIC is using 8bit addres
   //so let's teach IMU of the real "philips" addres and hope
   //it'll not bother us when we'll try to configure
   //the ADXL using PIC address   
   
   //set accel power control to 'measure'
   i2c_start(IC1);
   i2c_write(IC1,PIC_ADXL_WR);
   i2c_write(IC1,ADXL_POWER_CTL);
   i2c_write(IC1,0x08);
   i2c_stop(IC1);
   delay_ms(5);
   
   // here we may also setup other ADXL345 parameters, like filtering
   /*
   
   //data format, by default it is in 10bit mode (0x00)
   // we can set it to FULL RESOLUTION
   i2c_start(IC1);
   i2c_write(IC1,PIC_ADXL_WR);
   i2c_write(IC1,0x31);
   i2c_write(IC1,0x08); //FULL_RES
   i2c_stop(IC1);
   delay_ms(5);
 
   //data rate, we keep it@ 50Hz as by default
   i2c_start(IC1);
   i2c_write(IC1,PIC_ADXL_WR);
   i2c_write(IC1,0x2C);
   i2c_write(IC1,0x09); //50HZ, 0x0A for 100Hz
   i2c_stop(IC1);
   delay_ms(5);
   */
   
   //cancel pass through to accel
   i2c_start(IC1);
   i2c_write(IC1,IMU3000_WR);
   i2c_write(IC1,0x3D);
   i2c_write(IC1,0x28);
   i2c_stop(IC1);
   delay_ms(5);
   

}


//this might be called from a loop, we assume that we've using
//acc_x, acc_y, acc_z, gy_x, gy_y, gy_z variables of int16 type
void sensors_read()
{
   int8 i;
   int8 buff[12];
   
   i2c_start(IC1);
   i2c_write(IC1,IMU3000_WR);
   //Register Address GYRO_XOUT_H,
   //meaning we'll start reading from there 12bytes of G_XYZ and ACC_XYZ, in pairs
   i2c_write(IC1,IMU3000_REG_X);
   i2c_stop(IC1);
   
   i2c_start(IC1);
   i2c_write(IC1,IMU3000_RD);
   i2c_write(IC1,12); //we're requesting 12bytes of data
   
   buff[ 0]=i2c_read(IC1,1);
   buff[ 1]=i2c_read(IC1,1);
   buff[ 2]=i2c_read(IC1,1);
   buff[ 3]=i2c_read(IC1,1);
   buff[ 4]=i2c_read(IC1,1);
   buff[ 5]=i2c_read(IC1,0);
   i2c_stop(IC1);
   
   //ok, now read the ADXL
   //first, we have to set the AUX if to passthrough
   //Set passthrough mode to Accel so we can turn it on
   i2c_start(IC1);
   i2c_write(IC1,IMU3000_WR);
   i2c_write(IC1,0x3D); //Register 61 – User Control
   i2c_write(IC1,0x08); //Set the AUX interface active and also reset the AUX interface
   i2c_stop(IC1);

   //start reading from address 0x32 of ADXL
   i2c_start(IC1);
   i2c_write(IC1,ACC_WR);
   i2c_write(IC1,0x32);
   i2c_stop(IC1);
 
   i2c_start(IC1);
   i2c_write(IC1,ACC_RD);
   buff[ 6]=i2c_read(IC1,1);
   buff[ 7]=i2c_read(IC1,1);
   buff[ 8]=i2c_read(IC1,1);
   buff[ 9]=i2c_read(IC1,1);
   buff[10]=i2c_read(IC1,1);
   buff[11]=i2c_read(IC1,0);
   i2c_stop(IC1);
   
   
   //..and cancel pass through to accel
   i2c_start(IC1);
   i2c_write(IC1,IMU3000_WR);
   i2c_write(IC1,0x3D);
   i2c_write(IC1,0x28);
   i2c_stop(IC1);
   delay_ms(5);
   
   gy_x=(signed int16)make16(buff[0],buff[1]);
   gy_y=(signed int16)make16(buff[2],buff[3]);
   gy_z=(signed int16)make16(buff[4],buff[5]);
   
   // Accel is LSB first. Also because of orientation of chips
   // accel y output is in same orientation as gyro x
   // and accel x is gyro -y, so you have to check the values!!!
   acc_x=(signed int16)make16(buff[ 7],buff[ 6]);
   acc_y=(signed int16)make16(buff[ 9],buff[ 8]);
   acc_z=(signed int16)make16(buff[11],buff[10]);

}


...yet i'm not sure why hobbytronics tell us that setting passthru -ON is by 0x08, because that disaples the AUX interface, by the IMU3000 datasheet
...however, I'd try both versions I've posted , with the mention that you might have to fiddle with those enable/disable AUX (0X28 - 0X08)
ok, hope it helps!


later edit: ok, read a little bit carefully the register definition and yes, is 0X08 for enabling pass-through and 0x28 for disabling it, so I'v corected both versions for whoever might find the code here
Zdetier



Joined: 28 Nov 2013
Posts: 28
Location: Stillwater, OK

View user's profile Send private message

PostPosted: Fri Nov 29, 2013 6:09 pm     Reply with quote

Dorinm, I tried you're code and made a few tweaks to fit my controller. Also I took out the I2c_stops after opening the data register because in the help file in CCS C it says, the format needs to be as follows

Code:

#include <18f4520.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#fuses HS,NOLVP,NOWDT,PUT
#use delay(clock=20000000)

#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7)
#use i2c(master, sda=pin_C4, scl=pin_C3,MASTER,FAST=400000,STREAM=IC1)

#define IMU3000_WR 0xD0
#define IMU3000_RD 0xD1

#define IMU3000_REG_X 0x1D //GYRO_XOUT_H address

#define ADXL_POWER_CTL 0x2D


#define PIC_ADXL_WR 0xA6 //by PIC, 8 bits, lsb 0
#define PIC_ADXL_RD 0xA7 //by PIC, 8 bits, lsb 0
int16 acc_x, acc_y, acc_z, gy_x, gy_y, gy_z;

   
void main()
{
//Sample Rate 1kHz, Filter Bandwidth 42Hz, Gyro Range 500 d/s
   i2c_start(IC1);
   i2c_write(IC1,IMU3000_WR);
   i2c_write(IC1,0x16);
   i2c_write(IC1,0x0B);
   i2c_stop(IC1);
   delay_ms(5);
   
 
   //set accel i2c slave address
   i2c_start(IC1);
   i2c_write(IC1,IMU3000_WR);
   i2c_write(IC1,0x14); //Register 20 – AUX (Accel) Slave Address
   i2c_write(IC1,PIC_ADXL_WR);
   i2c_stop(IC1);
   delay_ms(5);
   
   //Set passthrough mode to Accel so we can turn it on
   i2c_start(IC1);
   i2c_write(IC1,IMU3000_WR);
   i2c_write(IC1,0x3D); //Register 61 – User Control
   i2c_write(IC1,0x08); //Set the AUX interface active and also reset the AUX interface
   i2c_stop(IC1);
   delay_ms(5);
   
   //here might be the catch, as imu3000 knows 7bit i2c addres yet
   //PIC is using 8bit addres
   //so let's teach IMU of the real "philips" addres and hope
   //it'll not bother us when we'll try to configure
   //the ADXL using PIC address   
   
   //set accel power control to 'measure'
   i2c_start(IC1);
   i2c_write(IC1,PIC_ADXL_WR);
   i2c_write(IC1,ADXL_POWER_CTL);
   i2c_write(IC1,0x08);
   i2c_stop(IC1);
   delay_ms(5);
   
   // here we may also setup other ADXL345 parameters, like filtering
   /*
   
   //data format, by default it is in 10bit mode (0x00)
   // we can set it to FULL RESOLUTION
   i2c_start(IC1);
   i2c_write(IC1,PIC_ADXL_WR);
   i2c_write(IC1,0x31);
   i2c_write(IC1,0x08); //FULL_RES
   i2c_stop(IC1);
   delay_ms(5);
 
   //data rate, we keep it@ 50Hz as by default
   i2c_start(IC1);
   i2c_write(IC1,PIC_ADXL_WR);
   i2c_write(IC1,0x2C);
   i2c_write(IC1,0x09); //50HZ, 0x0A for 100Hz
   i2c_stop(IC1);
   delay_ms(5);
   */
   
   //cancel pass through to accel
   i2c_start(IC1);
   i2c_write(IC1,IMU3000_WR);
   i2c_write(IC1,0x3D);
   i2c_write(IC1,0x28);
   i2c_stop(IC1);
   delay_ms(5);
   
//this might be called from a loop, we assume that we've using
//acc_x, acc_y, acc_z, gy_x, gy_y, gy_z variables of int16 type
while(true){
   int8 i;
   int8 buff[12];
   
   i2c_start(IC1);
      i2c_write(IC1,IMU3000_WR);
      //Register Address GYRO_XOUT_H,
      //meaning we'll start reading from there 12bytes of G_XYZ and ACC_XYZ, in pairs
      i2c_write(IC1,IMU3000_REG_X);
   i2c_start(IC1);
      i2c_write(IC1,IMU3000_RD);
      i2c_write(IC1,12); //we're requesting 12bytes of data
      buff[ 0]=i2c_read(IC1,1);
      buff[ 1]=i2c_read(IC1,1);
      buff[ 2]=i2c_read(IC1,1);
      buff[ 3]=i2c_read(IC1,1);
      buff[ 4]=i2c_read(IC1,1);
      buff[ 5]=i2c_read(IC1,0);
   i2c_stop(IC1);
   
   //ok, now read the ADXL
   //first, we have to set the AUX if to passthrough
   //Set passthrough mode to Accel so we can turn it on
   i2c_start(IC1);
   i2c_write(IC1,IMU3000_WR);
   i2c_write(IC1,0x3D); //Register 61 – User Control
   i2c_write(IC1,0x08); //Set the AUX interface active and also reset the AUX interface
   i2c_stop(IC1);

   //start reading from address 0x32 of ADXL
   i2c_start(IC1);
   i2c_write(IC1,PIC_ADXL_WR);
   i2c_write(IC1,0x32);
 
   i2c_start(IC1);
   i2c_write(IC1,PIC_ADXL_RD);
   buff[ 6]=i2c_read(IC1,1);
   buff[ 7]=i2c_read(IC1,1);
   buff[ 8]=i2c_read(IC1,1);
   buff[ 9]=i2c_read(IC1,1);
   buff[10]=i2c_read(IC1,1);
   buff[11]=i2c_read(IC1,0);
   i2c_stop(IC1);
   
   
   //..and cancel pass through to accel
   i2c_start(IC1);
   i2c_write(IC1,IMU3000_WR);
   i2c_write(IC1,0x3D);
   i2c_write(IC1,0x28);
   i2c_stop(IC1);
   delay_ms(5);
   
   gy_x=(signed int16)make16(buff[0],buff[1]);
   gy_y=(signed int16)make16(buff[2],buff[3]);
   gy_z=(signed int16)make16(buff[4],buff[5]);
   
   // Accel is LSB first. Also because of orientation of chips
   // accel y output is in same orientation as gyro x
   // and accel x is gyro -y, so you have to check the values!!!
   acc_x=(signed int16)make16(buff[ 7],buff[ 6]);
   acc_y=(signed int16)make16(buff[ 9],buff[ 8]);
   acc_z=(signed int16)make16(buff[11],buff[10]);
     
      printf("%ld",gy_x);
      printf(",");
      printf("%ld",gy_y);
      printf(",");
      printf("%ld",gy_z);
      printf(",");
      printf("%ld",acc_x);
      printf(",");
      printf("%ld",acc_y);
      printf(",");
      printf("%ld",acc_z);
      printf("\n\r");
      delay_ms(100);
}
}


Still no Cigar though, the accelerometer is working, but the gyros still read zero.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Nov 29, 2013 8:37 pm     Reply with quote

The basic problem is the Gyro. I think we should cut out all code that
talks to or sets up the ADXL345.

Then, try to read the WHO_AM_I register of the Gyro. Don't try to read
12 bytes out of the fifo. Just read that register. I will investigate how
to do this now.
Zdetier



Joined: 28 Nov 2013
Posts: 28
Location: Stillwater, OK

View user's profile Send private message

PostPosted: Fri Nov 29, 2013 8:52 pm     Reply with quote

I agree, I think there is definitely something very fishy as to what is "actually" being read from the gyro!
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Nov 29, 2013 9:22 pm     Reply with quote

Here is my proposed test program to read the WHO_AM_I register.
I'm trying to be very cautious and so I'm doing the register read as two
separate i2c operations and I don't do a re-start. I do a stop at the end
of each part of the read operation. You'll see that below.
Code:

#include <18F4520.h>
#fuses INTRC_IO, BROWNOUT, PUT, NOWDT
#use delay(clock=4M)
#use rs232(baud=9600, UART1, ERRORS)
#use i2c(master, sda=pin_C4, scl=pin_C3)

#define IMU3000_I2C_WRT_ADDR   0xD0
#define IMU3000_I2C_READ_ADDR  0xD1

#define WHO_AM_I_REG_ADDR      0x00

//===================================
void main()
{
int8 result = 0;

delay_ms(120);

i2c_start();
i2c_write(IMU3000_I2C_WRT_ADDR);
i2c_write(WHO_AM_I_REG_ADDR);
i2c_stop();

i2c_start();
i2c_write(IMU3000_I2C_READ_ADDR);
result = i2c_read(0);
i2c_stop();

printf("Read from WHO_AM_I: %x \n\r", result);

while(1);

}
Zdetier



Joined: 28 Nov 2013
Posts: 28
Location: Stillwater, OK

View user's profile Send private message

PostPosted: Fri Nov 29, 2013 9:28 pm     Reply with quote

PCM,

Compiled the code, and the output was as follows,

Code:
Read from WHO_AM_I: 68 


This looks to be the correct value for the ID bits inside the who am I register, so that is progress!
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Nov 29, 2013 9:36 pm     Reply with quote

Good, let's try it with a re-start. Use this main() code. I've deleted
the first i2c_stop(). See if this also works.
Code:

void main()
{
int8 result;

delay_ms(120);

i2c_start();
i2c_write(IMU3000_I2C_WRT_ADDR);
i2c_write(WHO_AM_I_REG_ADDR);
i2c_start();
i2c_write(IMU3000_I2C_READ_ADDR);
result = i2c_read(0);
i2c_stop();

printf("Read from WHO_AM_I: %x \n\r", result);

while(1);

}
Zdetier



Joined: 28 Nov 2013
Posts: 28
Location: Stillwater, OK

View user's profile Send private message

PostPosted: Fri Nov 29, 2013 9:40 pm     Reply with quote

That also results with the correct ID value of 68
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Nov 29, 2013 9:57 pm     Reply with quote

Next let's try to read the gyro registers. Some might consider this
program a little bit overkill on the tedious function names, #defines,
and just overall, but I'm trying to be methodical. See what you get
from this program:
Code:

#include <18F4520.h>
#fuses INTRC_IO, BROWNOUT, PUT, NOWDT
#use delay(clock=4M)
#use rs232(baud=9600, UART1, ERRORS)
#use i2c(master, sda=pin_C4, scl=pin_C3)

#define IMU3000_I2C_WRT_ADDR   0xD0
#define IMU3000_I2C_READ_ADDR  0xD1

#define WHO_AM_I_REG_ADDR      0x00

#define GYRO_XOUT_H_REG_ADDR 0x1D
#define GYRO_XOUT_L_REG_ADDR 0x1E
#define GYRO_YOUT_H_REG_ADDR 0x1F
#define GYRO_YOUT_L_REG_ADDR 0x20
#define GYRO_ZOUT_H_REG_ADDR 0x21
#define GYRO_ZOUT_L_REG_ADDR 0x22


int8 imu3000_read_reg(int8 reg_addr)
{
int8 result;

i2c_start();
i2c_write(IMU3000_I2C_WRT_ADDR);
i2c_write(reg_addr);
i2c_start();
i2c_write(IMU3000_I2C_READ_ADDR);
result = i2c_read(0);
i2c_stop();

return(result);
}

//------------------------------------
signed int16 imu3000_read_16bit_reg(int8 reg_addr_msb, int8 reg_addr_lsb)
{
signed int16 retval;
int8 lsb, msb;

msb = imu3000_read_reg(reg_addr_msb);
lsb = imu3000_read_reg(reg_addr_lsb);

retval = make16(msb, lsb);
return(retval);
}


//===================================
void main()
{
int8 result;
int8 msb, lsb;
signed int16 gyro_x, gyro_y, gyro_z;

delay_ms(120);

printf("Read from WHO_AM_I: %x \n\r", result);

gyro_x = imu3000_read_16bit_reg(GYRO_XOUT_H_REG_ADDR, GYRO_XOUT_L_REG_ADDR);
gyro_y = imu3000_read_16bit_reg(GYRO_YOUT_H_REG_ADDR, GYRO_YOUT_L_REG_ADDR);
gyro_z = imu3000_read_16bit_reg(GYRO_ZOUT_H_REG_ADDR, GYRO_ZOUT_L_REG_ADDR);

printf("gyro x,y,z = %ld, %ld, %ld \n\r", gyro_x, gyro_y, gyro_z);

while(1);
}
Zdetier



Joined: 28 Nov 2013
Posts: 28
Location: Stillwater, OK

View user's profile Send private message

PostPosted: Fri Nov 29, 2013 10:04 pm     Reply with quote

That code created the following output:

Code:
Read from WHO_AM_I: 68                                                                                                   
gyro x,y,z = 0, 0, 0


It seems like the gyros are asleep or something, I was reading in the datasheet earlier

http://www.invensense.com/mems/gyro/documents/RM-IMU-3000A.pdf

today and I noticed on page 15 underneath the table it says that "*Default Value applies if sensor is disabled." which is 0x00, but I couldn't ever figure out how to turn the sensor "on" if this was what was the problem.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Nov 29, 2013 10:10 pm     Reply with quote

I'm going to look at the IMU3000 Register Map, and see if it has any clues:
http://www.invensense.com/mems/gyro/documents/RM-IMU-3000A.pdf
Zdetier



Joined: 28 Nov 2013
Posts: 28
Location: Stillwater, OK

View user's profile Send private message

PostPosted: Fri Nov 29, 2013 10:36 pm     Reply with quote

Yeah I've been looking through it and there is some sleep functions and sensor control switches, but I'm not sure because from what I've read most of the sleep phases and switches should be 0x00 when starting.
dyeatman



Joined: 06 Sep 2003
Posts: 1934
Location: Norman, OK

View user's profile Send private message

PostPosted: Fri Nov 29, 2013 10:37 pm     Reply with quote

...
_________________
Google and Forum Search are some of your best tools!!!!


Last edited by dyeatman on Fri Nov 29, 2013 10:49 pm; edited 1 time in total
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2, 3, 4  Next
Page 3 of 4

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group