Seunghee Jeong
/
Dronequadrotor
.
Diff: main.cpp
- Revision:
- 0:56ba69e447e3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Mon Jul 18 06:37:14 2022 +0000 @@ -0,0 +1,639 @@ +#include "mbed.h" +#include "nRF24L01.h" +#include "RF24.h" +#include "RF24_config.h" + +PwmOut PWM1(p21); +PwmOut PWM2(p22); +PwmOut PWM3(p23); +PwmOut PWM4(p24); +DigitalOut led1(LED1); +DigitalOut led_switch(LED4); +//DigitalIn switch_on(p5, PullDown); +Ticker loops; // 프로그램 무한루프 + +RF24 NRF24L01(p5, p6, p7, p15, p8); + +I2C i2c(p28, p27); //(I2C_SDA,I2C_SCL); +Serial pc(USBTX, USBRX); //D1D0 + +int MPU9250_ADDRESS = (0x68 << 1), //0b11010000 +WHO_AM_I_MPU9250 = 0x75, +FIFO_EN = 0x23, +SMPLRT_DIV = 0x19, +CONFIG = 0x1A, +GYRO_CONFIG = 0x1B, +ACCEL_CONFIG = 0x1C, +ACCEL_CONFIG2 = 0x1D, +ACCEL_XOUT_H = 0x3B, +TEMP_OUT_H = 0x41, +GYRO_XOUT_H = 0x43, +PWR_MGMT_1 = 0x6B, +PWR_MGMT_2 = 0x6C, +INT_PIN_CFG = 0x37, +AK8963_ADDRESS = (0x0C << 1), //0b00001100 0x0C<<1 +WHO_AM_I_AK8963 = 0x00, // should return 0x48 +AK8963_ST1 = 0x02, +AK8963_XOUT_L = 0x03, +AK8963_CNTL = 0x0A, +AK8963_ASAX = 0x10; + +float gyro_bias[3] = { 0,0,0 }; +float accel_bias[3] = { 0,0,0 }; +int16_t gyro[3]; +int16_t accel[3]; + +float accel_fu[3] = { 0,0,0 }; +float accel_f2[3] = { 0,0,0 }; +float accel_f1[3] = { 0,0,0 }; +float accel_f[3] = { 0,0,0 }; + +float gyro_f[3] = { 0,0,0 }; +float gyro_angle[3] = { 0,0,0 }; +float roll_c, roll_accel, roll_g_n, roll_g_old, roll_a_n, roll_a_old = 0; +float pitch_c, pitch_accel, pitch_g_n, pitch_g_old, pitch_a_n, pitch_a_old = 0; +float tau = 0.3; +float accel_tau = 1; + +const uint64_t pipe = 0x1212121212LL; +int8_t recv[30]; +int16_t PITCH = 0, ROLL = 0, YAW = 0, THROTTLE = 0; +int8_t ackData[30]; +int8_t flip1 = 1; + +// ETC +float roll_controller, pitch_controller, yaw_controller = 0.0; +float tilt_cont[4]; +float checksum[2] = {0,0}; +int BUT1, BUT2; + +//char BUT1, BUT2, prev_BUT2; +int rf_fail_count = 0; + +int l_count = 0; +float dt = 0.0025; // 0.0025 +float roll_f, pitch_f, yaw_f, yaw_c; + +// 적절하게 조절 0 +float K_scale = 0.0001; // 1 +float Kp_roll = 15, Kd_roll = 40 ; // 0.0015 0.0024 +float Kp_pitch = 16, Kd_pitch = 40 ; // 0.0015 0.0024 +float Kp_yaw = 50, Kd_yaw = 10 ; // + +float roll_cont, pitch_cont, yaw_cont = 0; +float rollcompensate, pitchcompensate = 0; +float thrust_c = 0.0; + +// 피치, 요 에러도 추가 +float roll_err, roll_rate_err; +float pitch_err, pitch_rate_err; +float yaw_err, yaw_rate_err; + +float thrust_in = 0.0; +float roll_ref = 0.0, roll_rate_ref = 0.0; +float pitch_ref = 0, pitch_rate_ref = 0;; // 추가 +float yaw_ref = 0, yaw_rate_ref = 0; + +float pwm1_pw, pwm2_pw, pwm3_pw, pwm4_pw; // 1이면 풀가동 +float ROLL_ERR_MAX = 40.0, ROLL_RATE_ERR_MAX = 40.0; // maximum errors considered +float PITCH_ERR_MAX = 40.0, PITCH_RATE_ERR_MAX = 40.0; // maximum errors considered +float YAW_ERR_MAX = 30.0, YAW_RATE_ERR_MAX = 30.0; // maximum errors considered + +void WHO_AM_I(void); +void MPU9250_INIT(void); +void MPU9250_RESET(void); +void MPU9250_GET_GYRO(int16_t * destination); +void MPU9250_GET_ACCEL(int16_t * destination); +void gyro_bias_f(void); +void control(void); +void pwm_drive(void); +void control_loop(void); +int constrain_int16(int16_t x, int min, int max); +float constrain_float(float x, float min, float max); +void RF_READ(); +void yaw_reset(); +void moving_cont(); +float set_min(float x, float min); + +void RF_READ() +{ + if (NRF24L01.available()) + { + NRF24L01.read(recv, 10); + + // 스케일링 다른데서 곱하기 + ROLL = *(int16_t*)(&recv[0])- 3; //ROLL = - ROLL; offset = 0 + PITCH = *(int16_t*)(&recv[2])- 7;//flip pitch and roll offset = 6 + YAW = *(int16_t*)(&recv[4]) - 0; // offset = 2 + THROTTLE = *(int16_t*)(&recv[6]) - 0; // offset = 0 + BUT1 = recv[8]; + BUT2 = recv[9]; //should hold value here + //pc.printf("\r RF_READ : %d, %d, %d, %d \n\r", (int)ROLL, (int)PITCH, (int)YAW, (int)THROTTLE); + rf_fail_count = 0; + } + + else + { + rf_fail_count = rf_fail_count + 1; + + //printf(" rf_fail_count : %d\n\r", rf_fail_count); + + if (rf_fail_count >= 20 && rf_fail_count < 100) + { + printf(" rf_fail_count : %d\n\r", rf_fail_count); + THROTTLE = THROTTLE - 2; + THROTTLE = constrain_int16(THROTTLE, 0, 1023); + } + if (rf_fail_count >= 50) + { + THROTTLE = 0; + } + if (rf_fail_count >= 100) + { + rf_fail_count = 100; + } + } +} + +void yaw_reset() +{ + if(set_min(yaw_ref,20)!= 0) + gyro_angle[2] = 0; +} + +void control(void) +{ + //pc.printf(" _ref : %5.2f %5.2f %5.2f %5.2f \n\r", roll_ref, pitch_ref, yaw_ref, thrust_in); + + roll_err = roll_ref - roll_f; + roll_rate_err = roll_rate_ref - gyro_f[0]; + + if (roll_err > ROLL_ERR_MAX) + roll_err = ROLL_ERR_MAX; + else if (roll_err < -(ROLL_ERR_MAX)) + roll_err = -(ROLL_ERR_MAX); + + if (roll_rate_err > ROLL_RATE_ERR_MAX) + roll_rate_err = ROLL_RATE_ERR_MAX; + else if (roll_rate_err < -(ROLL_RATE_ERR_MAX)) + roll_rate_err = -(ROLL_RATE_ERR_MAX); + + roll_cont = K_scale * (Kp_roll * roll_err + Kd_roll * roll_rate_err); + + if (roll_cont > 0.33) + roll_cont = 0.33; + else if (roll_cont < -0.33) + roll_cont = -0.33; + + /*-------------------------------------------------------------------*/ + + pitch_err = pitch_ref - pitch_f; + pitch_rate_err = pitch_rate_ref - gyro_f[1]; + + if (pitch_err > PITCH_ERR_MAX) + pitch_err = PITCH_ERR_MAX; + else if (pitch_err < -(PITCH_ERR_MAX)) + pitch_err = -(PITCH_ERR_MAX); + + if (pitch_rate_err > PITCH_RATE_ERR_MAX) + pitch_rate_err = PITCH_RATE_ERR_MAX; + else if (pitch_rate_err < -(PITCH_RATE_ERR_MAX)) + pitch_rate_err = -(PITCH_RATE_ERR_MAX); + + pitch_cont = K_scale * (Kp_pitch * pitch_err + Kd_pitch * pitch_rate_err); + + if (pitch_cont > 0.33) + pitch_cont = 0.33; + else if (pitch_cont < -0.33) + pitch_cont = -0.33; + + + /*-------------------------------------------------------------------------*/ + + yaw_err = yaw_ref - gyro_angle[2]; + yaw_rate_err = yaw_rate_ref - gyro_f[2]; + + if (yaw_err > YAW_ERR_MAX) + yaw_err = YAW_ERR_MAX; + else if (yaw_err < -(YAW_ERR_MAX)) + yaw_err = -(YAW_ERR_MAX); + + if (yaw_rate_err > YAW_RATE_ERR_MAX) + yaw_rate_err = YAW_RATE_ERR_MAX; + else if (yaw_rate_err < -(YAW_RATE_ERR_MAX)) + yaw_rate_err = -(YAW_RATE_ERR_MAX); + if(yaw_ref == 0) + yaw_cont = K_scale * (Kp_yaw * yaw_err + Kd_yaw * yaw_rate_err); + else + { + yaw_cont = K_scale * (Kp_yaw * yaw_err); + yaw_ref = 0; + } + + if (yaw_cont > 0.20) + yaw_cont = 0.20; + else if (yaw_cont < -0.20) + yaw_cont = -0.20; + + thrust_c = thrust_in / (float)1654; //control_scale = 2000 + if (thrust_c > 0.8) + thrust_c = 0.8; + +} + +//control tilted moving +void moving_cont() +{ + checksum[0] = roll_ref + pitch_ref; + if(checksum[0] == checksum[1]) + { + rollcompensate = accel_f[1]*(float)(0.5); + pitchcompensate = accel_f[0]*(float)(0.5); + rollcompensate = constrain_float(rollcompensate,-0.05,0.05); + pitchcompensate = constrain_float(pitchcompensate,-0.05,0.05); + + } + else + { + rollcompensate = 0; + pitchcompensate = 0; + + } + checksum[1] = checksum[0]; +} + + +void pwm_drive(void)//roll+ = pitch-, +{ + //pc.printf(" _c : %5.2f %5.2f %5.2f %5.2f \n\r", roll_c, pitch_c, yaw_c, thrust_c); + pwm1_pw = -(roll_cont + rollcompensate) - (pitch_cont + pitchcompensate) -yaw_cont + thrust_c ; // 최댓값 1, 최솟값 0 + pwm2_pw = (roll_cont + rollcompensate) - (pitch_cont + pitchcompensate) + yaw_cont + thrust_c ; + pwm3_pw = -(roll_cont + rollcompensate) + (pitch_cont + pitchcompensate) + yaw_cont + thrust_c ; + pwm4_pw = +(roll_cont + rollcompensate) + (pitch_cont + pitchcompensate) - yaw_cont + thrust_c ; + + if(pwm1_pw >= 1) + pwm1_pw = 1; + else if(pwm1_pw < 0) + pwm1_pw = 0; + if(pwm2_pw >= 1) + pwm2_pw = 1; + else if(pwm2_pw < 0) + pwm2_pw = 0; + if(pwm3_pw >= 1) + pwm3_pw = 1; + else if(pwm3_pw < 0) + pwm3_pw = 0; + if(pwm4_pw >= 1) + pwm4_pw = 1; + else if(pwm4_pw < 0) + pwm4_pw = 0; + + if (rf_fail_count>=50) // switch_on = 1; + { + pwm1_pw = 0.0; + pwm2_pw = 0.0; + pwm3_pw = 0.0; + pwm4_pw = 0.0; + } + + + PWM1 = pwm1_pw; + PWM2 = pwm2_pw; + PWM3 = pwm3_pw; + PWM4 = pwm4_pw; +} + +void control_loop(void) +{ + + MPU9250_GET_GYRO(gyro); + gyro_f[0] = gyro[0] / 32.8 - gyro_bias[0]; + gyro_f[1] = -(gyro[1] / 32.8 - gyro_bias[1]); + gyro_f[2] = -(gyro[2] / 32.8 - gyro_bias[2]); + + MPU9250_GET_ACCEL(accel); + accel_f[0] = (accel[0] / 8192.0 - accel_bias[0]); //%Navigation frame reference (NED) // 9.8m/s^2 ( G ) + accel_f[1] = (accel[1] / 8192.0 - accel_bias[1]) * (-1); // 부호? + accel_f[2] = (accel[2] / 8192.0 - accel_bias[2]) * (-1); + + /* + //accel low pass filter + accel_fu[0] = (accel[0] / 8192.0 - accel_bias[0]); //%Navigation frame reference (NED) // 9.8m/s^2 ( G ) + accel_fu[1] = (accel[1] / 8192.0 - accel_bias[1]) * (-1); // 부호? + accel_fu[2] = (accel[2] / 8192.0 - accel_bias[2]) * (-1); + + //accel low pass filter ----------- + accel_f2[0]=(1-dt/accel_tau)*accel_f1[0]+dt/accel_tau*accel_fu[0]; + accel_f2[1]=(1-dt/accel_tau)*accel_f1[1]+dt/accel_tau*accel_fu[1]; + accel_f2[2]=(1-dt/accel_tau)*accel_f1[2]+dt/accel_tau*accel_fu[2]; + + accel_f1[0]=accel_f2[0]; + accel_f1[1]=accel_f2[1]; + accel_f1[2]=accel_f2[2]; + + accel_f[0]=accel_f2[0]; + accel_f[1]=accel_f2[1]; + accel_f[2]=accel_f2[2]; + */ + //---------------------------------- + + //get roll and pitch from Accelometer values + roll_accel = atan(accel_f[1] / accel_f[2]) * 180.0 / 3.14; + //roll_accel = atan(accel_f[1] / accel_f[2]) * 180.0 / 3.14; //degree ' + pitch_accel = asin(constrain_float(accel_f[0],(float)-1,(float)1)) * 180.0 / 3.14; // apply constrain to avoid NaN + + //get Roll, Pitch, Yaw from Gyro + gyro_angle[0] = gyro_angle[0] + (gyro_f[0]) * dt; //Roll + gyro_angle[1] = gyro_angle[1] + (gyro_f[1]) * dt; //Pitch + gyro_angle[2] = gyro_angle[2] + (gyro_f[2]) * dt; //Yaw + + // YAW 360도 넘길 때 빼는 방법 + + //get roll and pitch by applying Complementary Filter + roll_g_n = (1 - dt / tau) * roll_g_old + dt * gyro_f[0]; + roll_a_n = (1 - dt / tau) * roll_a_old + dt / tau * roll_accel; + + pitch_g_n = (1 - dt / tau) * pitch_g_old + dt * gyro_f[1]; + pitch_a_n = (1 - dt / tau) * pitch_a_old + dt / tau * pitch_accel; + + roll_g_old = roll_g_n; + roll_a_old = roll_a_n; + + pitch_g_old = pitch_g_n; + pitch_a_old = pitch_a_n; + //pc.printf("\r%5.2f\t%5.2f",pitch_g_old, pitch_a_old); + roll_f = roll_g_old + roll_a_old; + pitch_f = pitch_g_old + pitch_a_old; //this value is weird + + RF_READ(); + /* + ROLL = ROLL - (int)offset[0]; + PITCH = PITCH - (int)offset[1]; + YAW = YAW - (int)offset[2]; + THROTTLE = THROTTLE - (int)offset[3]; + */ + + roll_ref = -(set_min((float)ROLL,6)); + pitch_ref = set_min((float)PITCH,6); + yaw_ref = -(set_min((float)YAW,6)); + thrust_in = set_min((float)THROTTLE,6); + + yaw_reset(); + + control(); + + //moving_cont(); + + pwm_drive(); + + + /* + if (l_count == 400 ) { + //pc.printf("l_count per 10") + + //pc.printf("----------------------------------\n\r"); + //pc.printf("\r Gyro data deg/s :\t %5.2f\t %5.2f\t %5.2f\n\r", gyro_f[0], gyro_f[1], gyro_f[2]); // 각속도 + //pc.printf("\r Gyro to angle :\t %5.2f\t %5.2f\t %5.2f\n\r", gyro_angle[0], gyro_angle[1], gyro_angle[2]); //Gyro print + //pc.printf("\r Accel data /s^2 :\t %5.2f\t %5.2f\t %5.2f\n\r", accel_f[0], accel_f[1], accel_f[2]); //Accel print + //pc.printf("\r Accel to angle :\t %5.2f\t %5.2f\n\r", roll_accel, pitch_accel); + + //pc.printf("\r R_f P_f Y angle :\t %5.2f\t %5.2f\t %5.2f\n\r", roll_f, pitch_f, gyro_angle[2]); //Roll, Pitch, Yaw 각도 + + // pc.printf("\r control input : %d, %d, %d, %f \n\r\n", (int)ROLL, (int)PITCH, (int)YAW, (float)THROTTLE); //RF_READ + //pc.printf("\r control value :\t %5.2f\t %5.2f\t %5.2f\t %5.2f\n\r", roll_c, pitch_c, yaw_c, thrust_c); // 모터에 들어가는 값 + //pc.printf("\r RPYT_control :\t %5.2f\t%5.2f\t%5.2f\t%5.2f \n\r", roll_cont, pitch_cont, yaw_cont, thrust_c); + //pc.printf("\r PWM Output :\t %5.2f\t%5.2f\t%5.2f\t%5.2f\n\r", pwm1_pw, pwm2_pw, pwm3_pw, pwm4_pw); // 모터가 내는 추력 0~1 + //pc.printf("\r RPYT_err :\t%5.3f\t%5.3f\t%5.3f \n\r", roll_err, pitch_err, yaw_err); + //pc.printf("\t\tRoll\tPitch\tYaw\tThrust\t\r\n"); + pc.printf("\r Angle :\t%5.2f\t%5.2f\t%5.2f\n\r", roll_f, pitch_f, gyro_angle[2]); //Roll, Pitch, Yaw 각도 표 출력 + pc.printf("\r RF input :\t%d\t%d\t%d\t%d \n\r\n", (int)ROLL, (int)PITCH, (int)YAW, (int)THROTTLE); //RF intput 표 출력 + + + //pc.printf("\r _ref : %5.2f %5.2f %5.2f %5.2f \n\r", roll_ref, pitch_ref, yaw_ref, thrust_in); // 제어에 쓰이는 값 + + l_count = 1; + } + + l_count = l_count + 1; + */ + + //wait(dt); + +} +float set_min(float x, float min) +{ + if ( x<min && x> -min) + x = 0; + return x; +} + +int constrain_int16(int16_t x, int min, int max) +{ + if (x > max) + x = max; + else if (x < min) + x = min; + return x; +} + +float constrain_float(float x, float min, float max) +{ + if (x > max) + x = max; + else if (x < min) + x = min; + return x; +} + +void MPU9250_RESET() +{ + // reset device + char cmd[2]; + cmd[0] = PWR_MGMT_1; //status + cmd[1] = 0x80; + i2c.write(MPU9250_ADDRESS, cmd, 2, 0); + wait(0.1); +} + +void MPU9250_INIT() +{ + char cmd[3]; + cmd[0] = PWR_MGMT_1; //reset + cmd[1] = 0x80; + i2c.write(MPU9250_ADDRESS, cmd, 2); + pc.printf("MPU 1 \n\r"); + wait(0.1); + + cmd[0] = PWR_MGMT_1; // Auto selects the best available clock source PLL if ready, + cmd[1] = 0x01; // else use the Internal oscillator + i2c.write(MPU9250_ADDRESS, cmd, 2, 0); + pc.printf("MPU 2 \n\r"); + wait(0.1); + + // Select Bandwidth of Gyroscopes BW 41Hz 1KHz internal sampling + cmd[0] = CONFIG; + cmd[1] = 0x03; + i2c.write(MPU9250_ADDRESS, cmd, 2, 0); + pc.printf("MPU 3 \n\r"); + wait(0.1); + + // sample rate = (internal sample rate) /(1+4) = 1000/5=200 Hz + cmd[0] = SMPLRT_DIV; + cmd[1] = 0x00;//0x04 + i2c.write(MPU9250_ADDRESS, cmd, 2, 0); + pc.printf("MPU 4 \n\r"); + wait(0.1); + + + cmd[0] = GYRO_CONFIG; + cmd[1] = 0b00010000;// Gyro full scale 1000 deg/sec; Gyro DLPF Enable + i2c.write(MPU9250_ADDRESS, cmd, 2, 0); + pc.printf("MPU 6 \n\r"); + wait(0.1); + + // Set accelerometer configuration + // Accel fulll sacle range +/- 4g + cmd[0] = ACCEL_CONFIG; + cmd[1] = 0b00001000;// Accel + i2c.write(MPU9250_ADDRESS, cmd, 2, 0); + pc.printf("MPU 8 \n\r"); + wait(0.1); + + cmd[0] = ACCEL_CONFIG2; + cmd[1] = 0b00000101; // 218 Hz bandwidth, 1kHz Sampling for accelerometer + i2c.write(MPU9250_ADDRESS, cmd, 2, 0); + pc.printf("MPU 10 \n\r"); + wait(0.1); + + //XYZ Gyro acel enable + cmd[0] = PWR_MGMT_2; + cmd[1] = 0x00; + i2c.write(MPU9250_ADDRESS, cmd, 2, 0); + pc.printf("MPU 11 \n\r"); + wait(0.1); + + cmd[0] = INT_PIN_CFG; + cmd[1] = 0x22; //0x02 + i2c.write(MPU9250_ADDRESS, cmd, 2, 0); + pc.printf("MPU 12 \n\r"); + wait(0.1); +} + +void WHO_AM_I() +{ + char cmd[2]; + char rvd[2]; + + cmd[0] = WHO_AM_I_MPU9250; + i2c.write(MPU9250_ADDRESS, cmd, 1, 1); + i2c.read(MPU9250_ADDRESS | 1, rvd, 1, 0); + + pc.printf(" IMU device id is 0x%x \n\r", rvd[0]); + wait(1); +} + +void MPU9250_GET_GYRO(int16_t * destination) +{ + char cmd[6]; + cmd[0] = GYRO_XOUT_H; + i2c.write(MPU9250_ADDRESS, cmd, 1, 1); + i2c.read(MPU9250_ADDRESS | 1, cmd, 6, 0); + destination[0] = (int16_t)(((int16_t)cmd[0] << 8) | cmd[1]); + destination[1] = (int16_t)(((int16_t)cmd[2] << 8) | cmd[3]); + destination[2] = (int16_t)(((int16_t)cmd[4] << 8) | cmd[5]); + + //pc.printf(" get_gyro : %d, %d, %d\n\r", destination[0], destination[1], destination[2]); +} + +void MPU9250_GET_ACCEL(int16_t * destination) +{ + char cmd[6]; + cmd[0] = ACCEL_XOUT_H; + i2c.write(MPU9250_ADDRESS, cmd, 1, 1); + i2c.read(MPU9250_ADDRESS | 1, cmd, 6, 0); + destination[0] = (int16_t)(((int16_t)cmd[0] << 8) | cmd[1]); + destination[1] = (int16_t)(((int16_t)cmd[2] << 8) | cmd[3]); + destination[2] = (int16_t)(((int16_t)cmd[4] << 8) | cmd[5]); + + //pc.printf(" get_accel : %d, %d, %d \n\r", destination[0], destination[1], destination[2]); +} + +void gyro_bias_f(void) +{ + int16_t gyro1[3]; + //int16_t gyro_bias[3]; + + pc.printf(" Please keep still 5 seconds\n\r"); + for (int i = 0; i < 200; i++) + { + MPU9250_GET_GYRO(gyro1); //정지상태 각속도를 gyro1에 측정, 32.8로 스케일링, 100번 측정한 값을 모두 더함 + gyro_bias[0] = gyro_bias[0] + gyro1[0] / 32.8; + gyro_bias[1] = gyro_bias[1] + gyro1[1] / 32.8; + gyro_bias[2] = gyro_bias[2] + gyro1[2] / 32.8; + //pc.printf(" gyro_bias finding i= %d\n\r", i); + + } + gyro_bias[0] = gyro_bias[0] / 200.0; //500으로 나누어 평균 도출 + gyro_bias[1] = gyro_bias[1] / 200.0; + gyro_bias[2] = gyro_bias[2] / 200.0; + //pc.printf(" Gyro_Bias finding completed %\n\r"); +} + +void accel_bias_f(void) +{ + int16_t accel1[3]; + //int16_t accel_bias[3]; + + pc.printf(" Please keep still 5 seconds\n\r"); + for (int i = 0; i < 100; i++) + { + MPU9250_GET_ACCEL(accel1); //정지상태 가속도를 accel1에 측정, 8192.0로 스케일링, 100번 측정한 값을 모두 더함 + accel_bias[0] = accel_bias[0] + accel1[0] / 8192.0; + accel_bias[1] = accel_bias[1] + accel1[1] / 8192.0; + accel_bias[2] = accel_bias[2] + accel1[2] / 8192.0; + pc.printf(" accel_bias finding i= %d\n\r", i); + } + accel_bias[0] = accel_bias[0] / 100.0; //100으로 나누어 평균 도출 + accel_bias[1] = accel_bias[1] / 100.0; + accel_bias[2] = accel_bias[2] / 100.0 - 1; //중력값 보정 + pc.printf(" Accel_Bias finding completed %\n\r"); +} + + + +int main() +{ + PWM1.period(0.0001);// 10 kHz PWM for PWM1~PWM4 + + wait(3); + pc.printf("------------------------\n\r"); + NRF24L01.begin(); + NRF24L01.setDataRate(RF24_2MBPS); //RF24_2MBPS + NRF24L01.setChannel(90); // set channel 10 20 30 + NRF24L01.setPayloadSize(28); + NRF24L01.setAddressWidth(5); + NRF24L01.setRetries(2, 4); //1,3 2,8 1,8 + NRF24L01.enableAckPayload(); + NRF24L01.openReadingPipe(0, pipe); + NRF24L01.startListening(); + + MPU9250_RESET(); + MPU9250_INIT(); + pc.baud(38400); + //pc.printf("%d th Who am I?\n\r", count); + WHO_AM_I(); + + + + //pc.printf(" count and gyro outputs(x,y,z)\n\r"); + //pc.printf(" count and accel outputs(x,y,z)\n\r"); + + gyro_bias_f(); + accel_bias_f(); + pc.printf(" \ngyro biases(deg/sec) %5.2f %5.2f %5.2f \n\r", gyro_bias[0], gyro_bias[1], gyro_bias[2]); // 초기화 됐는지 확인 + pc.printf(" accel biases(G) %5.2f %5.2f %5.2f \n\n\r", accel_bias[0], accel_bias[1], accel_bias[2]); // 초기화 됐는지 확인 + wait(1); + + + loops.attach_us(&control_loop, 2500); // ticker 2500 +} \ No newline at end of file