[Solved] Sensor registers seemingly inverting themselves

Hi,

I was messing around with a gyroscope and accelerometer (MPU 6050) and stumbled on a weird issue…
Here’s the code that reads the data from the sensor : (that void is read in a loop with nothing but “getSensorData();” in).

 void getSensorData() {

// MPU-6050 data registers :
// 0x3B (ACCEL_XOUT_H) and 0x3C (ACCEL_XOUT_L)
// 0x3D (ACCEL_YOUT_H) and 0x3E (ACCEL_YOUT_L)
// 0x3F (ACCEL_ZOUT_H) and 0x40 (ACCEL_ZOUT_L)
// 0x41 (TEMP_OUT_H) and 0x42 (TEMP_OUT_L)
// 0x43 (GYRO_XOUT_H) and 0x44 (GYRO_XOUT_L)
// 0x45 (GYRO_YOUT_H) and 0x46 (GYRO_YOUT_L)
// 0x47 (GYRO_ZOUT_H) and 0x48 (GYRO_ZOUT_L)

  // Gyroscope Data
  Wire.beginTransmission(MPU);
  Wire.write(0x43);
  Wire.requestFrom(MPU, 3*2, true);
  Wire.endTransmission(false);

  time = (micros()-clock) / (float) 1000000;
  clock = micros();

  gyro_x = Wire.read()<<8 | Wire.read();
  gyro_y = Wire.read()<<8 | Wire.read();
  gyro_z = Wire.read()<<8 | Wire.read();

  Wire.endTransmission(true);

  Serial.print("\n[Gyro X : "), Serial.print(gyro_x), Serial.print(" ]");
  Serial.print("\n[Gyro Y : "), Serial.print(gyro_y), Serial.print(" ]");
  Serial.print("\n[Gyro Z : "), Serial.print(gyro_z), Serial.print(" ]");

  

  // Accelerometer Data
  Wire.beginTransmission(MPU);
  Wire.write(0x3B);
  Wire.requestFrom(MPU, 3*2, true);
  Wire.endTransmission(false);

  acc_x = Wire.read()<<8 | Wire.read();
  acc_y = Wire.read()<<8 | Wire.read();
  acc_z = Wire.read()<<8 | Wire.read();

  Wire.endTransmission(true);

  Serial.print("\n[Acc X : "), Serial.print(acc_x), Serial.print(" ]");
  Serial.print("\n[Acc Y : "), Serial.print(acc_y), Serial.print(" ]");
  Serial.print("\n[Acc Z : "), Serial.print(acc_z), Serial.print(" ]");

}

The first gyro register is 0x43 and the first accel register is 0x3B.
You tell both data appart as the gyroscope data should read around 500 on the x axis and the accelerometer’s should read around 17000 on its z axis.

My issue is that the data prints out inverted : the accel data is printed in the gyro variables, etc… (I have a screenshot attached)

The variables and registers are attributed to the correct data and printed as they should be.
Everything seems like the code is executing properly but that the gyroscope register became the accelerometer register and vice versa.

The funny part is that if I delete or comment out either the accelerometer part or the gyroscope, as following, the results change drastically :

void getSensorData() {

  // Gyroscope Data
  Wire.beginTransmission(MPU);
  Wire.write(0x43);
  Wire.requestFrom(MPU, 3*2, true);
  Wire.endTransmission(false);

  time = (micros()-clock) / (float) 1000000;
  clock = micros();

  gyro_x = Wire.read()<<8 | Wire.read();
  gyro_y = Wire.read()<<8 | Wire.read();
  gyro_z = Wire.read()<<8 | Wire.read();

  Wire.endTransmission(true);

  Serial.print("\n[Gyro X : "), Serial.print(gyro_x), Serial.print(" ]");
  Serial.print("\n[Gyro Y : "), Serial.print(gyro_y), Serial.print(" ]");
  Serial.print("\n[Gyro Z : "), Serial.print(gyro_z), Serial.print(" ]");

  

//  // Accelerometer Data
//  Wire.beginTransmission(MPU);
//  Wire.write(0x3B);
//  Wire.requestFrom(MPU, 3*2, true);
//  Wire.endTransmission(false);
//
//  acc_x = Wire.read()<<8 | Wire.read();
//  acc_y = Wire.read()<<8 | Wire.read();
//  acc_z = Wire.read()<<8 | Wire.read();
//
//  Wire.endTransmission(true);
//
//  Serial.print("\n[Acc X : "), Serial.print(acc_x), Serial.print(" ]");
//  Serial.print("\n[Acc Y : "), Serial.print(acc_y), Serial.print(" ]");
//  Serial.print("\n[Acc Z : "), Serial.print(acc_z), Serial.print(" ]");

}

I attached a screenshot : I didn’t even touch the gyroscope code but it now prints the correct value !
It does the same if I remove the gyroscope code instead : the accelerometer prints the correct value.
They are interacting with eachother, but I can’t what is doing that…

The only way I can successfully get the data I want, where I want, is if I invert the registers myself and consider the register 0x3B to actually be the gyroscope and the register 0x43 to actually be the accelerometer.

I’m sure it’s a dumb mistake on my part, but I really can’t tell why this is happening…

Accelerometer code deleted.PNG

Thanks for using code tags, but please edit your post to include ALL the code.

The snippet is useless as it does not tell us how the variables are typed.

Hint: the "void" keyword before a function name indicates that the function does not return a value.

Here’s everything :

// MPU-6050 data registers :
// 0x3B (ACCEL_XOUT_H) and 0x3C (ACCEL_XOUT_L)
// 0x3D (ACCEL_YOUT_H) and 0x3E (ACCEL_YOUT_L)
// 0x3F (ACCEL_ZOUT_H) and 0x40 (ACCEL_ZOUT_L)
// 0x41 (TEMP_OUT_H) and 0x42 (TEMP_OUT_L)
// 0x43 (GYRO_XOUT_H) and 0x44 (GYRO_XOUT_L)
// 0x45 (GYRO_YOUT_H) and 0x46 (GYRO_YOUT_L)
// 0x47 (GYRO_ZOUT_H) and 0x48 (GYRO_ZOUT_L)

#include "Wire.h"

const int MPU = 0x68;
int16_t acc_x, acc_y, acc_z;
int16_t gyro_x, gyro_y, gyro_z;
int32_t clock = 0;
float time = 0;




void setup() {

  // Gyroscope and accelerometer start up
  delay(750);
  Serial.begin(115200);
  Wire.begin();
  Wire.beginTransmission(MPU);
  Wire.write(0x6B);
  Wire.write(0);
  Wire.endTransmission(true);

  // Gyroscope sensitivity setup.
  Wire.beginTransmission(MPU);
  Wire.write(0x1B);
  Wire.write(0);
  Wire.endTransmission(true);
  delay(30);

  // Accelerometer sensitivity setup.
  Wire.beginTransmission(MPU);
  Wire.write(0x1C);
  Wire.write(0);
  Wire.endTransmission(true);

}

void loop() {

 getSensorData();

}

void getSensorData() {

  // Gyroscope Data
  Wire.beginTransmission(MPU);
  Wire.write(0x43);
  Wire.requestFrom(MPU, 3*2, true);
  Wire.endTransmission(false);

  time = (micros()-clock) / (float) 1000000;
  clock = micros();

  gyro_x = Wire.read()<<8 | Wire.read();
  gyro_y = Wire.read()<<8 | Wire.read();
  gyro_z = Wire.read()<<8 | Wire.read();

  Wire.endTransmission(true);

  Serial.print("\n[Gyro X : "), Serial.print(gyro_x), Serial.print(" ]");
  Serial.print("\n[Gyro Y : "), Serial.print(gyro_y), Serial.print(" ]");
  Serial.print("\n[Gyro Z : "), Serial.print(gyro_z), Serial.print(" ]");

  

  // Accelerometer Data
  Wire.beginTransmission(MPU);
  Wire.write(0x3B);
  Wire.requestFrom(MPU, 3*2, true);
  Wire.endTransmission(false);

  acc_x = Wire.read()<<8 | Wire.read();
  acc_y = Wire.read()<<8 | Wire.read();
  acc_z = Wire.read()<<8 | Wire.read();

  Wire.endTransmission(true);

  Serial.print("\n[Acc X : "), Serial.print(acc_x), Serial.print(" ]");
  Serial.print("\n[Acc Y : "), Serial.print(acc_y), Serial.print(" ]");
  Serial.print("\n[Acc Z : "), Serial.print(acc_z), Serial.print(" ]");

}

I was using a void instead of putting everything in the loop to see if I could then use it multiple times wihtout having to write all the code again and again.

that void is read in a loop with nothing but "getSensorData();" in

Why do people persistently refer to functions that do not return any data as "voids" ?

The data type before the name of a function definition indicates the type of data that it will return, if any. If no data is to be returned by the function then that data type is void

If the function returned an int then would you refer to it as an int ?

Why do people persistently refer to functions that do not return any data as "voids" ?

Because they don't know what the word means, and don't care enough to look it up.

"NO_VALUE" or similar might have been a better choice, so long ago.

Because they don’t know what the word means, and don’t care enough to look it up.

I get that, but I have never seen anyone refer to a function that returns a value by the name of that data type.

EDIT : corrected gibberish English

You are using the Wire library incorrectly, with function calls in the wrong order.

Study this correctly working example carefully to see the problem:

   // MPU-6050 Short Example Sketch
    // By Arduino User JohnChi
    // August 17, 2014
    // Public Domain
    #include<Wire.h>
    const int MPU_addr=0x68;  // I2C address of the MPU-6050
    int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;
    void setup(){
      Wire.begin();
      Wire.beginTransmission(MPU_addr);
      Wire.write(0x6B);  // PWR_MGMT_1 register
      Wire.write(0);     // set to zero (wakes up the MPU-6050)
      Wire.endTransmission(true);
      Serial.begin(9600);
    }
    void loop(){
      Wire.beginTransmission(MPU_addr);
      Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
      Wire.endTransmission(false);
      Wire.requestFrom(MPU_addr,14,true);  // request a total of 14 registers
      AcX=Wire.read()<<8|Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)    
      AcY=Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
      AcZ=Wire.read()<<8|Wire.read();  // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
      Tmp=Wire.read()<<8|Wire.read();  // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
      GyX=Wire.read()<<8|Wire.read();  // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
      GyY=Wire.read()<<8|Wire.read();  // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
      GyZ=Wire.read()<<8|Wire.read();  // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)
      Serial.print("AcX = "); Serial.print(AcX);
      Serial.print(" | AcY = "); Serial.print(AcY);
      Serial.print(" | AcZ = "); Serial.print(AcZ);
      Serial.print(" | Tmp = "); Serial.print(Tmp/340.00+36.53);  //equation for temperature in degrees C from datasheet
      Serial.print(" | GyX = "); Serial.print(GyX);
      Serial.print(" | GyY = "); Serial.print(GyY);
      Serial.print(" | GyZ = "); Serial.println(GyZ);
      delay(333);
    }

they still used “void” to refer pretty exactly what I wrote

People who refer to functions as “voids” are beginners, and their advice should be taken with a tablespoon of salt, or more.

Thank you.
"Wire.endTransmission(false);" is supposed to be before " Wire.requestFrom(MPU, 3*2, true);" and moving it fixed the issue.
As it was working when only one request was made, I didn't think it would be that :confused:
Thanks again !

UKHeliBob:
Why do people persistently refer to functions that do not return any data as "voids" ?

The data type before the name of a function definition indicates the type of data that it will return, if any. If no data is to be returned by the function then that data type is void

If the function returned an int then would you refer to it as an int ?

I deleted the previous answer as I didn't understand and replied nonsense (I'm not native). But I still don't :

"Why do people persistently refer to functions that do not return any data as "voids" ?"

So, do not call a function that doesn't return data a void.

"The data type before the name of a function definition indicates the type of data that it will return, if any. If no data is to be returned by the function then that data type is void."

So if it doesn't return any data then I should call it "void"...
Am I supposed to call it void or not ? And if not and that it doesn't return data, what am I supposed to call it ?

if not and that it doesn't return data, what am I supposed to call it ?

A function

For example, the getSensorData() function, the loop() function, the setup() function the digitalWrite() function etc, etc

Or even a “void function”.

A function that returns an int could be called, oh, I don’t know, an “int function”.

But please, not a “void” or an “int”

Am I supposed to call it void or not ?

Call it a function. Better, add the name of the function.

Example: "In the setup() function, I assign modes to digital pins".