Hello
I'm using mpu6050 to get the value of roll,pitch,yaw.
I used a filter to get it right. The roll and pitch are good, but the Z-axis yaw has a strange value.
There are two problems.
1. Even if the sensor stays flat, the yaw value increases slightly (like accumulation).
2. After a few moves, the initial value of yaw changes.
In the picture below, the mpu6050 is left flat. All should be zero, but yaw values are completely different. It was tested for less than 5 minutes.

Here's the code I wrote it's written. I used complementary filter filter.
void mpu_init(void)
{
ret_code_t ret_code;
// Initiate MPU driver
ret_code = app_mpu_init();
APP_ERROR_CHECK(ret_code); // Check for errors in return value
// Setup and configure the MPU with intial values
app_mpu_config_t p_mpu_config = MPU_DEFAULT_CONFIG(); // Load default values
p_mpu_config.smplrt_div = 19; // Change sampelrate. Sample Rate = Gyroscope Output Rate / (1 + SMPLRT_DIV). 19 gives a sample rate of 50Hz
p_mpu_config.accel_config.afs_sel = AFS_2G; // Set accelerometer full scale range
p_mpu_config.gyro_config.fs_sel = GFS_250DPS; // Set gyro full scale range
ret_code = app_mpu_config(&p_mpu_config); // Configure the MPU with above values
APP_ERROR_CHECK(ret_code); // Check for errors in return value
}
int16_t AcX, AcY, AcZ, Tmp, GyX, GyY, GyZ;
//double mpu_accel_x, mpu_accel_y, mpu_accel_z;
//double mpu_gyro_x, mpu_gyro_y, mpu_gyro_z;
double dt;
double accel_angle_x, accel_angle_y, accel_angle_z;
double gyro_angle_x, gyro_angle_y, gyro_angle_z;
//double filtered_angle_x, filtered_angle_y, filtered_angle_z;
double baseAcX, baseAcY, baseAcZ;
double baseGyX, baseGyY, baseGyZ;
float tmp_angle_x, tmp_angle_y, tmp_angle_z;
static void readAccelGyro() //send to app
{
uint32_t err_code;
double angle_x, angle_y;
accel_values_t accel_values; //mpu6050
gyro_values_t gyro_values;
app_mpu_read_accel(&accel_values);
err_code = app_mpu_read_accel(&accel_values);
APP_ERROR_CHECK(err_code);
app_mpu_read_gyro(&gyro_values);
err_code = app_mpu_read_gyro(&gyro_values);
APP_ERROR_CHECK(err_code);
mpu_accel_x = accel_values.x;
mpu_accel_y = accel_values.y;
mpu_accel_z = accel_values.z;
mpu_gyro_x = gyro_values.x;
mpu_gyro_y = gyro_values.y;
mpu_gyro_z = gyro_values.z;
}
float sumAcX = 0, sumAcY = 0, sumAcZ = 0;
float sumGyX = 0, sumGyY = 0, sumGyZ = 0;
void calibAccelGyro(){
sumAcX = 0; sumAcY = 0; sumAcZ = 0;
sumGyX = 0; sumGyY = 0; sumGyZ = 0;
readAccelGyro();
for(int i=0; i<10; i++){
readAccelGyro();
sumAcX += mpu_accel_x;
sumAcY += mpu_accel_y;
sumAcZ += mpu_accel_z;
sumGyX += mpu_gyro_x;
sumGyY += mpu_gyro_y;
sumGyZ += mpu_gyro_z;
nrf_delay_ms(100);
}
baseAcX = sumAcX / 10;
baseAcY = sumAcY / 10;
baseAcZ = sumAcZ / 10;
baseGyX = sumGyX / 10;
baseGyY = sumGyY / 10;
baseGyZ = sumGyZ / 10;
}
uint32_t t_now;
uint32_t t_prev;
void initDT(){
t_prev = app_timer_cnt_get()*1000/32768;//milli-sec
//printf("t_prev : %d\n", (int)t_prev); //511
}
void calcDT(){
t_now = app_timer_cnt_get()*1000/32768;//milli-sec
dt = (t_now - t_prev) / 1000.0; //millis()
t_prev = t_now;
}
double acc_angle_x, acc_angle_y, acc_angle_z;
double acc_angle_x_2, acc_angle_y_2, acc_angle_z_3;
void calcAccelYPR(){
float accel_x, accel_y, accel_z;
float accel_xz, accel_yz;
const float RADIANS_TO_DEGREES = 180/3.14159;
accel_x = mpu_accel_x - baseAcX;
accel_y = mpu_accel_y - baseAcY;
//accel_z = mpu_accel_z + (16384 - baseAcZ); //different some example
accel_z = mpu_accel_z - (16384 - baseAcZ); //test
accel_yz = sqrt(pow(accel_y, 2) + pow(accel_z, 2));
accel_angle_y = atan(-accel_x / accel_yz)*RADIANS_TO_DEGREES;
accel_xz = sqrt(pow(accel_x, 2) + pow(accel_z, 2));
accel_angle_x = atan(accel_y / accel_xz)*RADIANS_TO_DEGREES;
accel_angle_z = 0;
//Accel angle test
/*acc_angle_x_2 = sqrt(pow(mpu_accel_x, 2) + pow(mpu_accel_z, 2));
acc_angle_x = atan(mpu_accel_y / acc_angle_x_2);
acc_angle_x = acc_angle_x * RADIANS_TO_DEGREES;
acc_angle_y_2 = sqrt(pow(mpu_accel_y, 2) + pow(mpu_accel_z, 2));
acc_angle_y = atan(-mpu_accel_x / acc_angle_y_2);
acc_angle_y = acc_angle_y * RADIANS_TO_DEGREES;*/
}
double gyro_x, gyro_y, gyro_z;
double test_angle_z;
void calcGyroYPR(){
const float GYROXYZ_TO_DEGREES_PER_SED = 131;
gyro_x = (mpu_gyro_x - baseGyX) / GYROXYZ_TO_DEGREES_PER_SED;
gyro_y = (mpu_gyro_y - baseGyY) / GYROXYZ_TO_DEGREES_PER_SED;
gyro_z = (mpu_gyro_z - baseGyZ) / GYROXYZ_TO_DEGREES_PER_SED;
gyro_angle_x += gyro_x * dt;
gyro_angle_y += gyro_y * dt;
gyro_angle_z += gyro_z * dt;
}
double test_filter_z;
void calcFilteredYPR(){
const float ALPHA = 0.96;
tmp_angle_x = 0;
tmp_angle_y = 0;
tmp_angle_z = 0;
tmp_angle_x = filtered_angle_x + gyro_x * dt;
tmp_angle_y = filtered_angle_y + gyro_y * dt;
tmp_angle_z = filtered_angle_z + gyro_z * dt; //original
filtered_angle_x = ALPHA * tmp_angle_x + (1.0 - ALPHA) * accel_angle_x;
filtered_angle_y = ALPHA * tmp_angle_y + (1.0 - ALPHA) * accel_angle_y;
filtered_angle_z = tmp_angle_z;
}
void SendData()
{
ret_code_t err_code;
//Filter
printf("%.0lf", filtered_angle_x); //filter value
printf(", ");
printf("%.0lf", filtered_angle_y);
printf(", ");
printf("%.0lf\n", filtered_angle_z);
nrf_delay_ms(10);
}
int main(void)
{
uint32_t err_code;
bool erase_bonds = false;
// Initialize.
gpio_init();
uart_init();
log_init();
timers_init();
app_buttons_init();
power_management_init();
ble_stack_init();
gap_params_init();
gatt_init();
services_init();
advertising_init();
conn_params_init();
peer_manager_init();
err_code = app_button_enable();
APP_ERROR_CHECK(err_code);
adc_configure(); //baterry value & LED
pwm_init();
mpu_init(); //mpu6050
bsp_board_init(BSP_INIT_LEDS); //use bsp
// Start execution.
printf("\r\nHelmet Device started.\r\n");
NRF_LOG_INFO("Debug logging for UART over RTT started.");
advertising_start(erase_bonds); //false
All_Stop();
do_play_buzzer(); //When start play buzzer
nrf_gpio_pin_set(POWER_SW); //HIGH : power on
calibAccelGyro(); //filter average value
initDT();
// Enter main loop.
for (;;)
{
readAccelGyro();
calcDT();
calcAccelYPR(); //accel
calcGyroYPR(); //gyro
calcFilteredYPR(); //filter
SendData();
pm_sec_params_set(NULL); //No Security parameters
//idle_state_handle(); //if no data sleep mode
}
}
Is there something wrong with gyro? Can I know about this problem?
Thank you.