I am new to this platform, so please if I do something against the regular rules please let me know so I can learn. Now my problem: I have a nodeMCU V3 connected to a MPU6050. Using my Arduino Uno I do get sensible values in the order of 0 degrees when the device is flat. Using the same code and the same setup I get very strange values in the order of 45 degrees when the device is flat. I have tried the following:
- Using the I2C scanner I do get a valid address.
- Testing with the Arduino Uno the values are correct.
- The GY 521 breakout uses 3V3 datalines with 2k2 pull ups. Datalines are short. Eg on the same breadboard.
- The GY 521 has a voltage regulator on board for 5V, so I feed the device with 5V in order to overcome a voltage drop problem.
- I have tried to stretch the stretchClock function but no luck.
I have read about people with a similar kind of issue, but I could not find a solution. Anyone that can help me? Apoligies. It would be more handy to attach my code: '' /* * I2C example sketch for ESP8266 */
#include <Wire.h>
const int DevID = 0x68;
const int PWR_MGT1_REG = 0x6B;
const int DataReg_AX = 0x3B;
const int DataReg_AY = 0x3D;
const int DataReg_AZ = 0x3F;
const int AccConfigReg = 0x1C;
const int GyrConfigReg = 0x1B;
const int SelfTestReg = 0x0D;
const int TempReg = 0x41;
const int DataReg_GX = 0x43;
const int DataReg_GY = 0x45;
const int DataReg_GZ = 0x47;
const int CalibrationConfigAcc = 0xF0;//set this value for calibration
const int CalibrationConfigGyr = 0xE0;//set this value for calibration
const int NormalConfigAcc = 0x00;//set this value for calibration 2G
const int NormalConfigGyr = 0x00;//set this value for calibration 250dps
/*
int16_t Acc_X;
int16_t Acc_Y;
int16_t Acc_Z;
*/
float Acc_X, accAngleX, accAngleY, Yaw_Angle;
float Acc_Y;
float Acc_Z;
//double Acc_X, accAngleX, accAngleY, Yaw_Angle;
//double Acc_Y;
//double Acc_Z;
int8_t X_selfTest;
int8_t Y_selfTest;
int8_t Z_selfTest;
int8_t Acc_X_Y_Z_selfTest;
int16_t Temp;
/*
int16_t Gyro_X;
int16_t Gyro_Y;
int16_t Gyro_Z;
*/
float Gyro_X;
float Gyro_Y;
float Gyro_Z;
int16_t Gyro_X_selfTest;
int16_t Gyro_Y_selfTest;
int16_t Gyro_Z_selfTest;
//int SDApin = 3;//create I2C pinouts for ESP8266;
//int SCLpin = 4;
unsigned long elapsedTime, previousTime, currentTime;
void setup() {// put your setup code here, to run once:
Serial.begin(115200);
Wire.begin ();
// Wire.setClock(400000);
// Wire.setClockStretchLimit(40000);
Wire.beginTransmission(DevID);
Wire.write(PWR_MGT1_REG);
Wire.write(0x0);// wake up the sensor
Wire.endTransmission();
CalibrationProcedure();// enter calibration procedure
}
void loop() {// put your main code here, to run repeatedly:
previousTime = currentTime;
currentTime = millis();
elapsedTime = (currentTime - previousTime) / 1000;
Wire.beginTransmission(DevID);
Wire.write(DataReg_AX);
Wire.endTransmission();
Wire.requestFrom(DevID, 14);
if (Wire.available() == 14) {
Acc_X = ((Wire.read() << 8) | (Wire.read())) / 16384.0;// divide by 16384 for 2G setting according to datasheet
Acc_Y = ((Wire.read() << 8) | (Wire.read())) / 16384.0;
Acc_Z = ((Wire.read() << 8) | (Wire.read())) / 16384.0;
Temp = (Wire.read() << 8) | (Wire.read());
Gyro_X = ((Wire.read() << 8) | (Wire.read())) / 131.0; // divide by 131.0 according to datasheet for setting 250 dps
Gyro_Y = ((Wire.read() << 8) | (Wire.read())) / 131.0;
Gyro_Z = ((Wire.read() << 8) | (Wire.read())) / 131.0;
delay(500);
}
//The formulas below have been extracted from another program and uses mathematical
//values for calulation of pitch roll and yaw. For the moment only pitch is calibrated
//The next purpose of this program is follow a calibration procedure to take approx 200 samples
//and average the total value to correct the pitch roll and yaw value
accAngleX = (atan(Acc_Y / sqrt(pow(Acc_X, 2) + pow(Acc_Z, 2))) * 180 / PI);
accAngleY = (atan(-1 * Acc_X / sqrt(pow(Acc_Y, 2) + pow(Acc_Z, 2))) * 180 / PI);
Yaw_Angle = Yaw_Angle + Gyro_Z * elapsedTime;
float Gyro_X_axis = (float)Gyro_X / 131.0;
float Gyro_Y_axis = (float)Gyro_Y / 131.0;
float Gyro_Z_axis = (float)Gyro_Z / 131.0;
float Temperature = (Temp / (340.0)) + 36.53;
//Serial.print(" Accelero X \t" );
//Serial.print(Acc_X);
//Serial.print(" Accelero Y \t" );
//Serial.print(Acc_Y);
//Serial.print(" Accelero Z \t");
//Serial.print(Acc_Z);
//Serial.println("");
//Serial.print(" Gyro X \t" );
//Serial.print(Gyro_X);
//Serial.print(" Gyro Y \t" );
//Serial.print(Gyro_Y);
//Serial.print(" Gyro Z \t");
//Serial.print(Gyro_Z);
//Serial.print(" Temperature \t");
//Serial.println(Temperature);
//Serial.println(Temp);
Serial.println ("Angle X");
Serial.println(accAngleX);
Serial.println ("Angle Y");
Serial.println (accAngleY);
Serial.println("Yaw Angle");
Serial.println(Yaw_Angle);
delay(500);
}
void CalibrationProcedure() {
Serial.println("Keep sensor steady until calibration process is complete!");
Wire.beginTransmission(DevID);
Wire.write(AccConfigReg);//8 g
Wire.write(CalibrationConfigAcc);
Wire.endTransmission();
delay(250);
Wire.beginTransmission(DevID);
Wire.write(GyrConfigReg);
Wire.write(CalibrationConfigGyr);//250 deg/s
Wire.endTransmission();
delay(500);
Serial.println("Selftest enabled, reading data...");
Wire.beginTransmission(DevID);
Wire.write(SelfTestReg);
Wire.endTransmission();
Wire.requestFrom(DevID, 4);
if (Wire.available() <= 4) {
X_selfTest = Wire.read();
Y_selfTest = Wire.read();
Z_selfTest = Wire.read();
Acc_X_Y_Z_selfTest = Wire.read();
delay(500);
}
//extracting factory trim values after self test
//unsigned integers for accelero variables
uint8_t XA_selfTest;
uint8_t YA_selfTest;
uint8_t ZA_selfTest;
//unsigned integers for gyro variables
uint8_t GX_selfTest;
uint8_t GY_selfTest;
uint8_t GZ_selfTest;
//Factory Trim variables
float FTGX;
float FTGY;
float FTGZ;
float FTAX;
float FTAY;
float FTAZ;
float SelfTestPercentage_GX;
float SelfTestPercentage_GY;
float SelfTestPercentage_GZ;
float SelfTestPercentage_AX;
float SelfTestPercentage_AY;
float SelfTestPercentage_AZ;
GX_selfTest = X_selfTest & 0x1F; // 0x1F is a bit mask to extract the first 5 bits. unsigned format
GY_selfTest = Y_selfTest & 0x1F;
GZ_selfTest = Z_selfTest & 0x1F;
XA_selfTest = (X_selfTest >> 3) | (Acc_X_Y_Z_selfTest & 0x30) >> 4; //shift the first 3 bits and extract bits with a mask depending on the LSB postion in the last received mixed byte
YA_selfTest = (Y_selfTest >> 3) | (Acc_X_Y_Z_selfTest & 0x0C) >> 2;
ZA_selfTest = (Z_selfTest >> 3) | (Acc_X_Y_Z_selfTest & 0x03);
Serial.println ("XA_selfTest");
Serial.println (X_selfTest, HEX);
Serial.println("YA_selfTest");
Serial.println(Y_selfTest, HEX);
Serial.println("ZA_selfTest");
Serial.println(Z_selfTest, HEX);
Serial.println("Acc_X_Y_Z_selfTest");
Serial.println(Acc_X_Y_Z_selfTest, HEX);
//calculate the factory trim settings
FTGX = (25.0 * 131.0) * (pow(1.046, ((float)GX_selfTest - 1.0)));// Factortrim Gyro X
FTGY = (-25.0 * 131.0) * (pow(1.046, ((float)GY_selfTest - 1.0)));// Factortrim Gyro Y
FTGZ = (25.0 * 131.0) * (pow(1.046, ((float)GZ_selfTest - 1.0)));// Factortrim Gyro Z
FTAX = (4096.0 * 0.34) * (pow((0.92 / 0.34), (((float)XA_selfTest - 1.0) / 30.0)));
FTAY = (4096.0 * 0.34) * (pow((0.92 / 0.34), (((float)YA_selfTest - 1.0) / 30.0)));
FTAZ = (4096.0 * 0.34) * (pow((0.92 / 0.34), (((float)ZA_selfTest - 1.0) / 30.0)));
Serial.println("Selftest ended...please copy data");
Serial.println(" GX trim value\t" );
Serial.println(FTGX);
Serial.println(" GY trim value\t" );
Serial.println(FTGY);
Serial.println(" GZ trim value\t");
Serial.println(FTGZ);
Serial.println(" AX trim value\t" );
Serial.println(FTAX);
Serial.println(" AY trim value\t" );
Serial.println(FTAY);
Serial.println(" AZ trim value\t");
Serial.println(FTAZ);
SelfTestPercentage_GX = 100.0 + 100.0 * ((float)GX_selfTest - FTGX) / FTGX;
Serial.println("SelfTestPercentage");
Serial.println(SelfTestPercentage_GX);
SelfTestPercentage_GY = 100.0 + 100.0 * ((float)GY_selfTest - FTGY) / FTGY;
Serial.println("SelfTestPercentage");
Serial.println(SelfTestPercentage_GY);
SelfTestPercentage_GZ = 100.0 + 100.0 * ((float)GZ_selfTest - FTGZ) / FTGZ;
Serial.println("SelfTestPercentage");
Serial.println(SelfTestPercentage_GZ);
SelfTestPercentage_AX = 100.0 + 100.0 * ((float)XA_selfTest - FTAX) / FTAX;
Serial.println("SelfTestPercentage Acclero x, y, z");
Serial.println(SelfTestPercentage_AX);
SelfTestPercentage_AY = 100.0 + 100.0 * ((float)YA_selfTest - FTAY) / FTAY;
Serial.println("SelfTestPercentage Acclero x, y, z");
Serial.println(SelfTestPercentage_AY);
SelfTestPercentage_AZ = 100.0 + 100.0 * ((float)ZA_selfTest - FTAZ) / FTAZ;
Serial.println("SelfTestPercentage Acclero x, y, z");
Serial.println(SelfTestPercentage_AZ);
// get data outputs with self test enabled
Wire.beginTransmission(DevID);
Wire.write(DataReg_AX);
Wire.endTransmission();
Wire.requestFrom(DevID, 14);
if (Wire.available() <= 14) {
Acc_X = (Wire.read() << 8) | (Wire.read());
Acc_Y = (Wire.read() << 8) | (Wire.read());
Acc_Z = (Wire.read() << 8) | (Wire.read());
Temp = (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());
delay(500);
}
//print values with self test enabled
Serial.println("Self test enabled values");
Serial.println(" Accelero X " );
Serial.println(Acc_X);
Serial.println(" Accelero Y " );
Serial.println(Acc_Y);
Serial.println(" Accelero Z ");
Serial.println(Acc_Z);
Serial.println(" Gyro X " );
Serial.println(Gyro_X);
Serial.println(" Gyro Y " );
Serial.println(Gyro_Y);
Serial.println(" Gyro Z ");
Serial.println(Gyro_Z);
delay(500);
//setup the device for normal OPS
Wire.beginTransmission(DevID);
Wire.write(AccConfigReg);
Wire.write(NormalConfigAcc);
Wire.endTransmission();
delay(50);
Wire.beginTransmission(DevID);
Wire.write(GyrConfigReg);
Wire.write(NormalConfigGyr);
Wire.endTransmission();
delay(50);
//request data with self test not enabled
Wire.beginTransmission(DevID);
Wire.write(DataReg_AX);
Wire.endTransmission();
Wire.requestFrom(DevID, 14);
if (Wire.available() <= 14) {
Acc_X = (Wire.read() << 8) | (Wire.read());
Acc_Y = (Wire.read() << 8) | (Wire.read());
Acc_Z = (Wire.read() << 8) | (Wire.read());
Temp = (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());
delay(500);
//print values with self test not enabled
Serial.println("Self test not enabled values");
Serial.println(" Accelero X " );
Serial.println(Acc_X);
Serial.println(" Accelero Y " );
Serial.println(Acc_Y);
Serial.println(" Accelero Z ");
Serial.println(Acc_Z);
Serial.println(" Gyro X " );
Serial.println(Gyro_X);
Serial.println(" Gyro Y " );
Serial.println(Gyro_Y);
Serial.println(" Gyro Z ");
Serial.println(Gyro_Z);
delay(5000);
}
}
'''