#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);
}
1 Answer 1
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.
-
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.st2000– st200010/02/2023 13:02:34Commented Oct 2, 2023 at 13:02
can anyone solve it?
is not a question about the gyro