Example of reading an gyroscope sensor (ITG3205)

Dependencies:   mbed

ITG3205.cpp

Committer:
jose_claudiojr
Date:
2013-05-21
Revision:
0:d884c7453c85

File content as of revision 0:d884c7453c85:


#include "ITG3205.h"

ITG3205::ITG3205(PinName sda, PinName scl) : i2c(sda, scl) 
{
    char rx;
    //400kHz, fast mode.
    i2c.frequency(400000);
    //===========================================================================================================
    // Read chip_id
    //===========================================================================================================
    rx = Read(ITG3205_WHO_AM_I);
    if (rx != 0x68 && rx!= 0x69)                      // Data sheet say's "The slave address of the ITG-3205
        printf("\ninvalid chip id %d\r\n", rx);       // devices is b110100X". This could be either, 0x68 or 0x69
    //===========================================================================================================
    // Let's reset the chip to it's default configuration
    //===========================================================================================================
    // The PWR_MGM (0x3E) is composed of six parameters, to reset is necessary to set the H_RESET (bit 7)
    //  PWR_MGM Register |===============================================|
    //    bits           |    7      6      5       4       3    2  1  0 |
    //                   | H_RESET SLEEP STBY_XG STBY_YG STBY_ZG CLK_SEL |
    //                   |    1      0      0       0       0    0  0  0 |
    //                   |===============================================|
    Write(ITG3205_PWRM, 0x80);
    //==========================================================================================================
    // Let's define the low-pass filter's bandwidth to 42Hz (DLPF_CFG<2:0> -> 011) with internal sample rate of 
    // 1kHz, to reduce noise in the signal, and also, let's define the gyro's sensors (FS_SELT<4:3> -> 11) to 
    // FullScale Range (+/- 2000º/sec).
    // To set the DLPF_CFG bit, we will have to acces the DLP_FS register (0x16) 
    //==========================================================================================================
    // The DLP_FS is composed of the FS_SEL (Bit 4 and 3) and the DLPF_CFG  (Bit 1 and 0)
    //  DPL_FS Register |================================|
    //    bits          | 7   6   5  |4    3| |2   1  0| |
    //                  | X   X   X  |FS_SEL| |DLPF_CFG| |
    //                  | 0   0   0   1    1   0   1  1  | -> (0x1B) Sets the gyro to FullScale Range (+/- 2000º/sec) and Low-Pass Filter 
    //                  |================================|           with bandwidth of 42Hz and internal sample rate of 1kHz.
    Write(ITG3205_DLPFS, 0x1B);
    //Let's check
    rx = Read(ITG3205_DLPFS);                                       // procedure: readed value: i.e XXX1 1110 -> The bits that we want to check are the bits 0,1,2,3 and 4, so we have to eliminate the other bits      
    rx &= (~0xE0); //Mask                                           //                        (AND) 0001 1111 -> (~DLPFSMask)
    if(rx != 0x1B)                                                  //                              ---------
        printf("DPL_FS register has not been written: %d\r\n", rx); //                              0001 1110 -> Final value, compare with the wanted value (this one doesn't match)
    //==========================================================================================================
    // Now let's define the sample rate to 5msec. 
    // To do this, a formula is applied: Fsample = Finternal/(x+1) on wich Fsample is the inverse o our sample rate, 
    // and Finternal is equal to 1kHz, as defined in the low-pass filter's bandwidth.
    // The SMPLRT register (0x15) controls the sample rate, so we must set this register to 4, as the result of x in the
    // equation.
    //==========================================================================================================
    /*
    Write(ITG3205_SMPLRT, 0x04);
    //Let's check
    rx = Read(ITG3205_SMPLRT);                                     
    if(rx != 0x04)                                                 
        printf("SMPLRT register has not been written: %d\r\n", rx); 
    */
    //==========================================================================================================
    // Generate interrupt when device is ready or raw data ready
    //==========================================================================================================
    // The PWR_MGM is composed of six parameters, to reset is necessary to set the H_RESET (bit 7)
    //  PWR_MGM Register |==========================================================================|
    //    bits           |   7     6        5                4         3      2       1       0     |
    //                   | ACTL  OPEN  LATCH_INT_EN  INT_ANYRD_2CLEAR  0  ITG_RDY_EN  0  RAW_RDY_EN |
    //                   |   0     0        0                0         0      1       0       1     | -> 0x05
    //                   |==========================================================================|
    //Write(ITG3205_INT_CFG, 0x05);  
    Write(ITG3205_INT_CFG, 0x00);  
    //==========================================================================================================
    // Back the PWR_MGM to what it was
    //==========================================================================================================
    Write(ITG3205_PWRM, 0x00);
}



void ITG3205::Write(char reg, char data)
{
    char c_data[2];
    c_data[0] = reg;
    c_data[1] = data;
    i2c.write((ITG3205_ADDR << 1), c_data, 2); 
}

char ITG3205::Read(char data)
{
    char tx = data;
    char rx;
    
    i2c.write((ITG3205_ADDR << 1) & 0xFE, &tx, 1); // 0xFE ensure that the MSB bit is being set to zero (RW=0 -> Writing)
    i2c.read((ITG3205_ADDR << 1) | 0x01, &rx, 1);  // 0x01 ensure that the MSB bit is being set to one  (RW=1 -> Reading)
                                             // The read/write method of I2C does this automatically, so it's useless to set manually    
    return rx;
}
/*
int ITG3205::getInternalSampleRate(void){

    char tx = ITG3205_DLPFS;
    char rx;
    
    i2c_.write((ITG3200_I2C_ADDRESS << 1) & 0xFE, &tx, 1);
    
    i2c_.read((ITG3200_I2C_ADDRESS << 1) | 0x01, &rx, 1);
    
    //DLPF_CFG == 0 -> sample rate = 8kHz.
    if(rx == 0){
        return 8;
    } 
    //DLPF_CFG = 1..7 -> sample rate = 1kHz.
    else if(rx >= 1 && rx <= 7){
        return 1;
    }
    //DLPF_CFG = anything else -> something's wrong!
    else{
        return -1;
    }
    
}
*/
bool ITG3205::isRawReady()
{
    if(Read(ITG3205_INT_STATUS) == 0x01)
        return true;
    else
        return false;
        
}

float ITG3205::getGyroX(void)
{
    char lsb_byte = 0;
    signed short msb_byte;
    float acc;
    
    lsb_byte = Read(ITG3205_XMSB);
    msb_byte = lsb_byte << 8;
    msb_byte |= Read(ITG3205_XLSB);
    acc = (float)msb_byte;
    return acc;
    /*
    char tx = GYRO_XOUT_H_REG;
    char rx[2];
    
    i2c.write((ITG3205_ADDR << 1) & 0xFE, &tx, 1);
    i2c.read((ITG3205_ADDR << 1) | 0x01, rx, 2);
    
    int16_t output = ((int) rx[0] << 8) | ((int) rx[1]);
    
    return output;
    */
}

float ITG3205::getGyroY(void)
{
    char lsb_byte = 0;
    signed short msb_byte;
    float acc;
    
    lsb_byte = Read(ITG3205_YMSB);
    msb_byte = lsb_byte << 8;
    msb_byte |= Read(ITG3205_YLSB);
    acc = (float)msb_byte;
    return acc;
    /*
    char tx = GYRO_YOUT_H_REG;
    char rx[2];
    
    i2c.write((ITG3205_ADDR << 1) & 0xFE, &tx, 1);
    
    i2c.read((ITG3205_ADDR << 1) | 0x01, rx, 2);
    
    int16_t output = ((int) rx[0] << 8) | ((int) rx[1]);
    
    return output;
    */
}

float ITG3205::getGyroZ(void)
{
    char lsb_byte = 0;
    signed short msb_byte;
    float acc;
    
    lsb_byte = Read(ITG3205_ZMSB);
    msb_byte = lsb_byte << 8;
    msb_byte |= Read(ITG3205_ZLSB);
    acc = (float)msb_byte;
    return acc;
    /*
    char tx = GYRO_ZOUT_H_REG;
    char rx[2];
    
    i2c.write((ITG3205_ADDR << 1) & 0xFE, &tx, 1);
    
    i2c.read((ITG3205_ADDR << 1) | 0x01, rx, 2);
    
    int16_t output = ((int) rx[0] << 8) | ((int) rx[1]);
    
    return output;
    */
}