Teensy 4.0 i2c Help

Hey Everyone,

I am attempting to use existing code to communicated with the mpu6050 this code works perfectly on an Arduino Uno and an I2c scanner confirms that the teensy 4.0 recognizes the address of the mpu. However, the code gets stuck in the while wireAvalible < 14. I am at a loss as for what could be wrong.


#include <Wire.h> //I2C Library

int gyro_x, gyro_y, gyro_z;
long acc_x, acc_y, acc_z;
long loop_timer, loop_timer_cell,valve_timer;
void setup(){
   Serial.begin(115200);
   setup_mpu_6050_registers();
   Serial.println("Begin");
}

void loop(){
  read_mpu_6050_data();
  Serial.print("Acc_x = ");
  Serial.println(acc_x);
} 



void read_mpu_6050_data() {                                            
  Wire.beginTransmission(0x68);                                        
  Wire.write(0x3B);                                                    
  Wire.endTransmission();                                              
  Wire.requestFrom(0x68, 14);                                          
  while (Wire.available() < 14);                                      
  acc_x = Wire.read()<<8 | Wire.read();                              
  acc_y = Wire.read()<<8 | Wire.read();                               
  acc_z = Wire.read()<<8 | Wire.read();                               
  gyro_x = Wire.read()<<8 | Wire.read(); 
  gyro_y = Wire.read()<<8 | Wire.read(); 
  gyro_z = Wire.read()<<8 | Wire.read(); 
  
}



void setup_mpu_6050_registers() {
  //Activate the MPU-6050
  Wire.beginTransmission(0x68);                                        //Start communicating with the MPU-6050
  Wire.write(0x6B);                                                    //Send the requested starting register
  Wire.write(0x00);                                                    //Set the requested starting register
  Wire.endTransmission();                                              //End the transmission
  //Configure the accelerometer (+/-8g)
  Wire.beginTransmission(0x68);                                        //Start communicating with the MPU-6050
  Wire.write(0x1C);                                                    //Send the requested starting register
  Wire.write(0x10);                                                    //Set the requested starting register
  Wire.endTransmission();                                              //End the transmission
  //Configure the gyro (500dps full scale)
  Wire.beginTransmission(0x68);                                        //Start communicating with the MPU-6050
  Wire.write(0x1B);                                                    //Send the requested starting register
  Wire.write(0x08);                                                    //Set the requested starting register
  Wire.endTransmission();         
  Serial.println("done with setup");//End the transmission
}

That little sketch has a bunch of problems.

The sensor has 16-bit signed integers for the sensor values.
You should use "int16_t" for the values read from the sensor.

Remove this line: while (Wire.available() < 14); It is nonsense code.

You could add a test in setup to check if the MPU-6050 is connected, by using the return value of Wire.endTransmission().

If something is wrong when requesting data from the sensor, then you could test the return value of Wire.requestFrom() and check if that is the same as then number of bytes that is requested (14 bytes are requested, return value should be 14).

When reading 14 bytes, that is 7 sensor values, there is also a temperature with those. You can check any MPU-6050 example to see that.

The MPU-6050 is sometimes used with a repeated start. That is done with a Wire.endTransmission(false); just before the Wire.requestFrom(...).

The Teensy 4.0 is very fast, there could be a timing issue with the I2C bus or the sensor.



#include <Wire.h> //I2C Library

float acc_x;
float loop_timer;

void setup(){
   Serial.begin(115200);
   setup_mpu_6050_registers();

   loop_timer = micros();
}

void loop(){
  read_mpu_6050_data();
  acc_x = (acc_x/4096)*9.81;
  Serial.println(acc_x);
 
  
  //IMU Loop
  while(micros() - loop_timer < 4000);                                 
  loop_timer = micros();
  
} 



void read_mpu_6050_data(){                                             //Subroutine for reading the raw gyro and accelerometer data
  Wire.beginTransmission(0x68);                                        //Start communicating with the MPU-6050
  Wire.write(0x3B);                                                    //Send the requested starting register
  Wire.endTransmission();                                              //End the transmission
  Wire.endTransmission(false);
  Wire.requestFrom(0x68,2);
  Serial.print(" Bytes = ");
  Serial.println(Wire.available());
  acc_x = int16_t(Wire.read())<<8|int16_t(Wire.read());  
}

void setup_mpu_6050_registers(){
  //Activate the MPU-6050
  Wire.beginTransmission(0x68);                                        //Start communicating with the MPU-6050
  Wire.write(0x6B);                                                    //Send the requested starting register
  Wire.write(0x00);                                                    //Set the requested starting register
  Wire.endTransmission();                                              //End the transmission
  //Configure the accelerometer (+/-8g)
  Wire.beginTransmission(0x68);                                        //Start communicating with the MPU-6050
  Wire.write(0x1C);                                                    //Send the requested starting register
  Wire.write(0x10);                                                    //Set the requested starting register
  Wire.endTransmission();                                              //End the transmission
  //Configure the gyro (500dps full scale)
  Wire.beginTransmission(0x68);                                        //Start communicating with the MPU-6050
  Wire.write(0x1B);                                                    //Send the requested starting register
  Wire.write(0x08);                                                    //Set the requested starting register
  Wire.endTransmission();                                              //End the transmission
  
}

I simplified the code and attempted to implement your suggestions. I also printed out available bytes, and as expected its 0. Using the built in i2c scanner, i receive the address of the mpu6050 as 0x68 which is correct. Unsure why this code has issues, it works just fine on an Uno. As for the clock issue, how would i go about adjusting or diagnosing clock speed. I also am not sure how to implement the int16_t, just now realizing that my code probably doesn't work for that portion.

Wire.endTransmission() returns 4

Could you show a minimal sketch where Wire.endTransmission() returns 4 ?

This is without a repeated start:

Wire.beginTransmission(0x68);
Wire.write(0x3B);
Wire.endTransmission();
Wire.requestFrom(0x68,2);

This is with a repeated start:

Wire.beginTransmission(0x68);
Wire.write(0x3B);
Wire.endTransmission(false);
Wire.requestFrom(0x68,2);

The only difference is a 'false' with Wire.endTransmission(). Your code has a Wire.endTransmission() too many.

I prefer to put the data into the same kind of variables that the sensor uses.

int16_t rawACC_x = int16_t( Wire.read() ) << 8 | int16_t( Wire.read() );
float acc_x = float( rawACC_x);

That way the rawACC_x is exactly the same as the number in the sensor.
However, if nothing is available, then the data is not valid.

If you have removed that extra line with Wire.endTransmission() and it does not work, then you could try to add a delay(1) after the Wire.endTransmission().

You could meanwhile ask a question on the forum for the Teensy.
Such as here: https://forum.pjrc.com/threads/67594-not-initialize-mpu6050-Failed-to-find-MPU6050-chip?p=282335.
If you do, please add a link here to that topic and a link over there to this topic.
There are fake MPU-6050 chips, but since it works on a Uno, I assume that the sensor is okay.
Can you give a link to the MPU-6050 module that you have and how is it connected ?