Hi All!
I am trying to connect an MPU-6050(ITG/MPU breakout board) with ATmega8 (on a breadboard - non arduino) via I2C.
When I try to read one of the sensor values the TWSR values show perfect I2C communication,
like for example TWSR values for: Start, Slave+W, Address ACK, Register AddressACK, Slave+R, Data to TWDR, NACK by master, Stop, etc. all match with atmega8's data-sheet (I connected 8-pins of PORTD to 8 LEDS and set TWSR to display on this PORT every time a TWSR check operation is performed).
But the values I receive in TWDR are all constant and does not change by any movements of sensor (I tried displaying the sensed values on a 8-LEDS arrangement and also on an LCD).
I communicate on I2C in following manner:
Send Start,
Check TWSR,
Send Slave address with write bit,
Wait for N/ACK,
Check TWSR,
Send Sensor register address,
Wait for N/ACK,
Check TWSR,
Send START (repeated start)
Check TWSR,
Send Slave address with read,
Wait for N/ACK,
Check TWSR,
Copy TWDR data to an element of an Array,
Send "NACK",
Check TWSR
Stop.
I continuously monitor TWINT flag in all steps. And these steps are repeated again and again for different sensor registers.
Also I have enabled interrupt (by including sei();) but I have not put anything in the Interrupt vector.
My Question(s) is :
Why is this data constant?
Is there a problem with my I2C communication approach?
Or is the MPU operating on 3V3 and AVR on 5V killing the sensed data? (I use 4K7 pull-ups to 5V)
Or any other registers are to be configured (I tried PWR_MGMT_1, USER_CTRL, CONFIG, SMPRT_DIV, GYRO_CONFIG, ACCEL_CONFIG in this very order) before actual register addressing and data reading?
Or some other problem?
If similar experience had been discussed before or a discussion that might help, Please redirect.
Thanks.
Following is my code:
#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include "defandfunc4.c" // contains I2C functions
#include "lcdincluder.c" // contains LCD functions
#include "myheader.h" // contains definitions and prototype decl.
int main (void)
{
//------------------ Variable initialisations
unsigned char SLA_W[10], SLA_R[10], RCVD_L[10], RCVD_M[10];
int INTRMDT[10], GYRO_Z[10], MSB[10], LSB[10];
int i = 0, j = 0;
sei();
DDRD = 0XFF;
DDRB = 0XFF;
//------------------ Clear LCD
Send_a_command (0X01); // Clear screen
_delay_ms(2); // takes 1.53 ms
//------------------ Address setting
SLA_W = ((SL_ADD<<1) | 0); // Slave + Write bit (0)
SLA_R = ((SL_ADD<<1) | 1); // Slave + Read bit (1)
//------------------------ Actual TWI communication begins
TWSR = 0X00; // Set prescaler to be 0
TWBR = 0X0C; // setting bit-rate division factor to be 12
_delay_us(10);
j = 1;
for (i=0;i<10;++i)
{
start_condn(); // start condition
//------------------------ First TWI : Send Register Addr
CHECK_TWSR_FOR (START); // If status mismatches error routine is followed
clear_go(); //a prgram that glows an led for few milli sec
TWDR = SLA_W; // Load TWDR with Slave + write
charge (); // Clear TWINT
wait_for_TWINT(); // Wait for TWINT
CHECK_TWSR_FOR (MT_SLA_ACK); // check TWSR for successful TXn of slave address. If status mismatches error routine is followed
clear_go(); //a prgram that glows an led for few milli sec
TWDR = GYRO_XOUT_H; // Load TWDR with Data(register address)
charge (); // Clear TWINT
wait_for_TWINT(); // Wait for TWINT
CHECK_TWSR_FOR (MT_DATA_ACK); // check TWSR for successful TXn of Data and ACK RCVD. If status mismatches error routine is followed
clear_go(); //a prgram that glows an led for few milli sec
//------------------------ Second TWI : Read data
start_condn(); // Repeated start condition
wait_for_TWINT(); // Wait for TWINT
CHECK_TWSR_FOR (R_START); // check TWSR for successful TXn of Repeated Start, If status mismatches error routine is followed
clear_go(); //a prgram that glows an led for few milli sec
TWDR = SLA_R; // Load TWDR with Slave + read
charge (); // Clear TWINT
wait_for_TWINT(); // Wait for TWINT
CHECK_TWSR_FOR (MR_SLA_ACK); // check TWSR for successful TXn of ADDr + R, If status mismatches error routine is followed
clear_go(); //a prgram that glows an led for few milli sec
wait_for_TWINT(); // Wait for TWINT
RCVD_M[i] = TWDR;
TWCR = (1<<TWINT)|(1<<TWEN); //send NACK
wait_for_TWINT(); // Wait for TWINT
CHECK_TWSR_FOR (DATA_RCVD_NACK); // check TWSR for Data RXd NACK sent, If status mismatches error routine is followed
clear_go(); //a prgram that glows an led for few milli sec
stop_condn (); // Transmit STOP
//------------------------ Third TWI : Send Register Addr
start_condn(); // Repeated start condition
wait_for_TWINT(); // Wait for TWINT
CHECK_TWSR_FOR (START); // check value of TWSR for successful TXn of Start, If status mismatches error routine is followed
clear_go(); //a prgram that glows an led for few milli sec
TWDR = SLA_W; // Load TWDR with Slave + write
charge (); // Clear TWINT
wait_for_TWINT(); // Wait for TWINT
CHECK_TWSR_FOR (MT_SLA_ACK); // check TWSR for successful TXn of slave address, If status mismatches error routine is followed
clear_go(); //a prgram that glows an led for few milli sec
TWDR = GYRO_XOUT_L; // Load TWDR with Data(register address)
charge (); // Clear TWINT
wait_for_TWINT(); // Wait for TWINT
CHECK_TWSR_FOR (MT_DATA_ACK); // check TWSR for successful TXn of Data and ACK RCVD, If status mismatches error routine is followed
clear_go(); //a prgram that glows an led for few milli sec
PORTD = 0X00; // Switching off portD
//------------------------ Fourth TWI : Read data
start_condn(); // Repeated start condition
wait_for_TWINT(); // Wait for TWINT
CHECK_TWSR_FOR (R_START); // check TWSR for successful TXn of Repeated Start, If status mismatches error routine is followed
clear_go(); //a prgram that glows an led for few milli sec
TWDR = SLA_R; // Load TWDR with Slave + read
charge (); // Clear TWINT
wait_for_TWINT(); // Wait for TWINT
CHECK_TWSR_FOR (MR_SLA_ACK); // check TWSR for successful TXn of ADDr + R, If status mismatches error routine is followed
clear_go(); //a prgram that glows an led for few milli sec
wait_for_TWINT(); // Wait for TWINT
RCVD_L[i] = TWDR;
TWCR = (1<<TWINT)|(1<<TWEN); //send NACK
wait_for_TWINT(); // Wait for TWINT
CHECK_TWSR_FOR (DATA_RCVD_NACK); // check TWSR for Data RXd NACK sent, If status mismatches error routine is followed
clear_go(); //a prgram that glows an led for few milli sec
stop_condn (); // Transmit STOP
//------------------ Making a word
LSB[i] = 0XFF & RCVD_L[i];
MSB[i] = 0XFF & RCVD_M[i];
INTRMDT[i] = ((MSB[i] << 8) | LSB[i]);
GYRO_Z[i] = INTRMDT[i];
// On to LCD
Send_a_character (GYRO_Z[i]); // Displays it on LCD
_delay_us(50); // takes 39 micro seconds
j++;
}
//------------------------ TWI complete ------------------------//
return 0;
}
I am using following breakout board:
http://playground.arduino.cc/Main/MPU-6050
(But I am not using Arduino)
Following is the MPU-6050 product page:
http://www.invensense.com/mems/gyro/mpu6050.html
Following is a link to MPU-6050 product specification and register map, respectively:
http://www.invensense.com/mems/gyro/documents/PS-MPU-6000A-00v3.4.pdf
http://www.invensense.com/mems/gyro/documents/RM-MPU-6000A-00v4.2.pdf
Thanks!