-1
#include<avr/io.h>
float x, y, z, baf = 0, j, i = 0, k, angle, a, b, c, d;
unsigned long current_time = 0;
unsigned long previous_time = 0;
unsigned long time_interval = 0;
float gyro_offset_x = 0.0;
float gyro_offset_y = 0.0;
float gyro_offset_z = 0.0;
void i2cinit(void)
{
 TWSR = 0x00;
 TWBR = 0x14;
 TWCR = (1 << TWEN);
}
void i2cstart(void)
{
 TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN);
 while (!(TWCR & (1 << TWINT)));
}
void i2cwrite( unsigned char data)
{
 TWDR = data;
 TWCR = (1 << TWINT) | (1 << TWEN);
 while (!(TWCR & (1 << TWINT)));
}
unsigned int i2c_receive(unsigned char isLast) {
 if (isLast == 0)
 {
 TWCR |= (1 << TWINT) | (1 << TWEA) | (1 << TWEN);
 }
 else
 {
 TWCR = (1 << TWINT) | (1 << TWEN);
 }
 while (!(TWCR & (1 << TWINT)));
 return TWDR;
}
void i2cstop(void)
{
 TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
}
void mpu6050_init(void) {
 i2cstart();
 i2cwrite(0xD0);
 i2cwrite(0x6B); // PWR_MGMT_1 register
 i2cwrite(0);
 i2cstop();
}
void mpu6050f()
{
 i2cstart();
 i2cwrite(0xD0);
 i2cwrite(0x1B);
 i2cwrite(0x00);// changed here
 i2cstop();
}
float mpu6050rbyte(int gyro) {
 i2cstart();
 i2cwrite(0xD0);
 i2cwrite(gyro);
 i2cstart();
 i2cwrite(0xD0 | 0x01);
 float i = i2c_receive(1);
 i2cstop();
 return i;
}
float mpu6050_whole_data(int a, int b) {
 int msb = mpu6050rbyte(a);
 int lsb = mpu6050rbyte(b);
 float x_gyro = (msb << 8) | lsb;
 return x_gyro;
}
void calibrateGyroOffset() {
 const int numSamples = 100;
 for (k = 0; k < numSamples; k++) {
 gyro_offset_x += mpu6050_whole_data(0x43, 0x44);
 gyro_offset_y += mpu6050_whole_data(0x45, 0x46);
 gyro_offset_z += mpu6050_whole_data(0x47, 0x48);
 }
 gyro_offset_x /= numSamples;
 gyro_offset_y /= numSamples;
 gyro_offset_z /= numSamples;
}
float mpu6050angle(float woho, float gyro) {
 float angular_velocity = (woho - gyro) / 131.0;
 previous_time = current_time;
 current_time = millis();
 time_interval = (current_time - previous_time);
 float filter = (0.98 * angular_velocity) + (0.04 * angular_velocity);
 float angle = baf + (filter * time_interval) / 1000.0;
 baf = angle;
 return angle;
}
void setup()
{
 Serial.begin(9600);
 i2cinit();
 mpu6050_init();
 mpu6050f();
 calibrateGyroOffset();
}
void loop()
{
 x = mpu6050_whole_data(0x43, 0x44);
 y = mpu6050_whole_data(0x45, 0x46);
 z = mpu6050_whole_data(0x47, 0x48);
 // a = mpu6050angle(y, gyro_offset_msb);
 // b = mpu6050angle(z, gyro_offset_lsb);
 j = mpu6050angle(x, gyro_offset_x);
 c = mpu6050angle(y, gyro_offset_y);
 d = mpu6050angle(z, gyro_offset_z);
 // mpu6050r(0x43, &x, &y, &z);
 // mpu6050_init();
 // Serial.print("Offset x");
 // Serial.print(gyro_offset_x) ;
 // Serial.print(" ");
 // Serial.print("Offset y");
 // Serial.print(y) ;
 // Serial.print(" ");
 // // Serial.print("Offset z");
 // Serial.print(z) ;
 // Serial.print(" ");
 Serial.print("Angle x: ");
 Serial.print(j);
 Serial.print(" ");
 Serial.print("Angle y: ");
 Serial.print(c);
 Serial.print(" ");
 Serial.print("Angle z: ");
 Serial.println(d);
}
jsotola
1,5342 gold badges12 silver badges20 bronze badges
asked Oct 2, 2023 at 9:23
2
  • Should at least post what you expect to see and what you did see. Even unexpected outputs might give people reviewing this question a hit as to what is happening. Commented Oct 2, 2023 at 12:38
  • can anyone solve it? is not a question about the gyro Commented Oct 2, 2023 at 14:48

1 Answer 1

0

There may be a number of problems with this code. I will try to edit this answer as you provide feed back. The goal is a workable answer. To be clear, some here may, but it is up to you to fix your code.

  • Dead Reckoning is difficult. Any errors accumulate over time. A gyroscope is usually used as part of a sensor fusion with an Accelerometer or Magnetometer. This allows the gyroscope absolute reading to be corrected or reset to mitigate accumulated error. If sensor fusion is not available, then the gyroscope calibration will be very important in mitigating as much drift as possible.

  • Constrain the problem to make it simple. Initially, constrain the gyroscope movements such that only the X axis is rotated. For example, only rotate the gyroscope on a stable table top. This way, only the X data need be considered / shared as this problem is discussed.

  • Consider finding the gyroscope offset as the first step. The calibration function does not appear to have a time delay as does the normal sampling code. If the calibration function samples the gyroscope as fast as possible, the offsets may be too small or even zero and little use later when applying them to the gyroscope samples.

answered Oct 2, 2023 at 12:55
1
  • The stack exchange web sites are not good for discussions. If anything, this question / answer my still be closed, as it deals w/several aspects of gyroscope usage, before we finish. To mitigate the chances, stick w/edits-to-the-question & comments that include results are well worded. Commented Oct 2, 2023 at 13:02

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.