I´m playing around with the gyro sensor MPU6050 a little but got some problems at one point.
I initialized the int variable LSB_divisor = 4096 depending on the sensitivity in my void setup() but later in the void loop() when i want to check the variable in a function it gives back zero in the serial monitor and i don´t know why.
If I´m declaring LSB_divisor = 4096 in the function directly it works fine.
I´m a little bit frustrated but maybe you guys can tell me why its printing 0 instead of 4096.
the code is here:
// Gyroscop: MPU6050
#include <Wire.h>
#ifndef F_CPU //If the clock speed is 16MHz include the next code line when compiling
#define F_CPU 16000000L //Set ClockSpeed auf 16Mhz -> Zyklus alle 0,0000000625s (0,0625µs)clock frequency, set according to clock used!
#endif //End of if statement
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Declaring global variables
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
char charBuffer[100];
int cal_int, timer, error, type , acc_sensitivity, LSB_divisor;
int address;
double acc_axis[2]; //gyro_axis[1]= Roll,gyro_axis[2] = pitch, gyro_axis[3] = yaw
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Setup routine
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup(){
address = 0x68; // MPU6050 I2C address
Serial.begin(57600); //Start the serial port.
Wire.begin(); // Wire.begin(Adresse) initialisiert die Bibliothek und meldet den Arduino mit der angegebenen Adresse am I²C-Bus an. Soll der Arduino als Busmaster angemeldet werden, entfällt die Adresse.
acc_sensitivity = 8; // Möglichkeiten: +/- 8g, +/- 4g ,+/- 2g, +/- 160g
type = 1;
if(acc_sensitivity == 2)LSB_divisor = 16384.0; // LSB Sensitivity
else if(acc_sensitivity == 4)LSB_divisor = 8192;
else if(acc_sensitivity == 8)LSB_divisor = 4096;
else if(acc_sensitivity == 16)LSB_divisor = 2048;
delay(500);
Serial.println("LSB_divisor:");
Serial.println(LSB_divisor);
delay(500);
set_gyro_registers();
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programm routine
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void loop(){
test_acc();
}
//Setup the MPU-6050: Registerübersicht unter C:\Users\James\Desktop\Mikrocontrolling\03_Bauteile und Datenblätter\02_Shields+Modules\Gyrosensor MPU6050
void set_gyro_registers(){
Serial.println(F(""));
Serial.println(F("==================================================="));
Serial.println(F("Set Gyro Registers"));
Serial.println(F("==================================================="));
//Setup the MPU-6050
if(type == 1){
Wire.beginTransmission(address); //Start communication with the address found during search.
Wire.write(0x6B); //We want to write to the PWR_MGMT_1 register (6B hex)
Wire.write(0x00); //Set the register bits as 00000000 to activate the gyro
Wire.endTransmission(); //End the transmission with the gyro.
Wire.beginTransmission(address); //Start communication with the address found during search.
Wire.write(0x1C); //We want to write to the ACCEL_CONFIG register (1A hex)
if(acc_sensitivity == 2)Wire.write(0b00000000); //Set the register bits as b00000000 (+/- 2g full scale range)
else if(acc_sensitivity == 4)Wire.write(0b00001000); //Set the register bits as b00001000 (+/- 4g full scale range)
else if(acc_sensitivity == 8)Wire.write(0b00010000); //Set the register bits as b00010000 (+/- 8g full scale range)
else if(acc_sensitivity == 16)Wire.write(0b00011000); //Set the register bits as b00011000 (+/- 16g full scale range)
Wire.endTransmission(); //End the transmission with the gyro
Wire.beginTransmission(address); //Start communication with the address found during search
Wire.write(0x1A); //We want to write to the CONFIG register (1A hex)
Wire.write(0x03); //Set the register bits as 00000011 (Set Digital Low Pass Filter to ~43Hz)
Wire.endTransmission(); //End the transmission with the gyro
}
}
void test_acc(){
Wire.beginTransmission(address);
Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H)
Wire.endTransmission(false);
Wire.requestFrom(address,6,true); // request a total of 6 registers
acc_axis[0]=(Wire.read()<<8|Wire.read())/LSB_divisor; // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
acc_axis[1]=(Wire.read()<<8|Wire.read())/LSB_divisor; // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
acc_axis[2]=(Wire.read()<<8|Wire.read())/LSB_divisor; // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
//Only for checking the values
Serial.println("");
Serial.println("LSB_divisor:");
Serial.println(LSB_divisor);
Serial.println("AccSensitivity:");
Serial.println(acc_sensitivity);
}
The strange thing is if I change the datatype of LSB_divisor from int to double it the serial monitor gives back LSB_divisor numbers like 4119.04 or 0.99.
You define a variable "type" that is not initialized, so will default to a value of zero. Then in your set_gyro_registers() function you only setup the MPU-6050 if type == 1, which will never be true.
david_2018:
You define a variable "type" that is not initialized, so will default to a value of zero. Then in your set_gyro_registers() function you only setup the MPU-6050 if type == 1, which will never be true.
You´re right I made a mistake in my example by forgetting to set the type. I corrected it in my first post.
But I´m still getting 0 values for
blh64:
That code compiles and runs just fine for me producing 4096 each time through the loop
Which type of Arduino are you using ?
Maybe I have a problem with the hardware/software. Ill install the new version of the arduino IDE and will test it with another Arduino type. But thank you for your response
Serial.println(acc_axis[0]) will return what I want because the divisor is not 0 or some nonsense number.
My question is why is the serial printed value of LSB_divisor wrong in Example 1 but not in Example 2. I thought this should be the same because I´m setting the variable on the exact same value.
I really can't see a problem with the original code you posted, unfortunately I don't have the sensor here to try with the actual hardware. It has the appearance of something overwriting the variable, but your code does not appear to do that.
Neither code snippet in your last posting will compile. Please open the actual test code you are using in the Arduino IDE, then Edit > Select All followed by Edit > Copy for Forum, then paste that into a posting here, to assure that you are not typing something incorrectly.
Maybe I have a problem with the hardware/software. Ill install the new version of the arduino IDE and will test it with another Arduino type. But thank you for your response
I compiled it on a Uno using the latest IDE. I don't actually have the sensor so nothing connected to the i2c bus, but the code continuously produced 4096.
Wire.read() returns an integer, LSB_divisor is an integer, so the division gives you an integer result, which is a whole number only with no decimal places. That number is then converted to a float and stored in acc_axis. That should not affect the value stored in LSB_divisor.
Odd that the compiler doesn't give a warning about such an obvious error, but it is also odd that the problem even shows up with your posted sketch, because acc_axis is never used except in those three equations, so the compiler removes it completely during optimization. If I add a statement to print acc_axis[2] I still get no warnings from the compiler, but LSB_divisor does get overwritten.
Odd that the compiler doesn't give a warning about such an obvious error, but it is also odd that the problem even shows up with your posted sketch, because acc_axis is never used except in those three equations, so the compiler removes it completely during optimization. If I add a statement to print acc_axis[2] I still get no warnings from the compiler, but LSB_divisor does get overwritten.
Thank you very much for your explanation .
I don´t know if i got i right. The reason is the optimization of the code
but is the usage of the array the problem ? And how can I avoid the problem is the future ?
Im a little confused because you say that acc_axis only has 2 elements but I
count three (acc_axis[0], acc_axis[1] and acc_axis[2]. Or am I thinking wrong ?
When you declare an array such as acc_axis[2] you are creating a 2-element array, which will be addressed as acc_axis[0] and acc_axis[1]
All arrays start with element 0 and count from there.
david_2018:
When you declare an array such as acc_axis[2] you are creating a 2-element array, which will be addressed as acc_axis[0] and acc_axis[1]
All arrays start with element 0 and count from there.