fin

Files at this revision

API Documentation at this revision

Comitter:
jbeason3
Date:
Tue Nov 19 04:30:59 2019 +0000
Commit message:
fin;

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r f2207cfaf993 main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Tue Nov 19 04:30:59 2019 +0000
@@ -0,0 +1,263 @@
+#include "mbed.h"
+#include "MPU9250.h"
+#include "SDFileSystem.h"
+SDFileSystem sd(p5,p6,p7,p8, "sd");
+DigitalOut myled(LED1);
+MPU9250 mpu9250(p28,p27);
+PwmOut servo(p26);
+Serial pc(USBTX, USBRX); // tx, rx
+
+float Time;
+float sum = 0;
+float servo_PWM;
+float angle;
+char buffer[100];
+char file_name[100];
+uint32_t sumCount = 0;
+Timer t;
+Ticker logTicker;
+
+
+void mpu9250_initialization(){
+    pc.printf("####CPU SystemCoreClock is %d Hz\r\n", SystemCoreClock);   
+    //initial com check
+    uint8_t whoami = mpu9250.readByte(MPU9250_ADDRESS, WHO_AM_I_MPU9250);  // Read WHO_AM_I register for MPU-9250
+    pc.printf("####I AM 0x%x\n\r", whoami); pc.printf("I SHOULD BE 0x71\n\r");
+    if (whoami == 0x71) // WHO_AM_I should always be 0x68
+    {  
+        pc.printf("####MPU9250 WHO_AM_I is 0x%x\n\r", whoami);
+        pc.printf("####MPU9250 is online...\n\r"); 
+        wait(1);
+        //reset MPU and conduct self test//
+        pc.printf("####Please wait,IMU Resetting####\r\n");
+        mpu9250.resetMPU9250(); // Reset registers to default in preparation for device calibration
+        pc.printf("####Self Test####\r\n");
+        //initial MPU9250 Parameters
+        mpu9250.Ascale = AFS_2G;
+        mpu9250.Gscale = GFS_250DPS;               // GFS_250DPS, GFS_500DPS, GFS_1000DPS, GFS_2000DPS
+        mpu9250.Mscale = MFS_16BITS;               // MFS_14BITS or MFS_16BITS, 14-bit or 16-bit magnetometer resolution
+        mpu9250.Mmode = 0x06;
+        mpu9250.delt_t=0;
+        mpu9250.deltat=0.0f;
+        mpu9250.lastUpdate = 0;
+        mpu9250.firstUpdate = 0;
+        mpu9250.Now = 0;
+        mpu9250.count=0;
+        mpu9250.q[0] = 1.0f;
+        mpu9250.q[1] = 0.0f;
+        mpu9250.q[2] = 0.0f;
+        mpu9250.q[3] = 0.0f;
+        // mpu9250.MPU9250SelfTest(SelfTest); // Start by performing self test and reporting values
+        //pc.printf("x-axis self test: acceleration trim within : %f % of factory value\n\r", SelfTest[0]);  
+        // pc.printf("y-axis self test: acceleration trim within : %f % of factory value\n\r", SelfTest[1]);  
+        //pc.printf("z-axis self test: acceleration trim within : %f % of factory value\n\r", SelfTest[2]);  
+        //pc.printf("x-axis self test: gyration trim within : %f % of factory value\n\r", SelfTest[3]);  
+        //pc.printf("y-axis self test: gyration trim within : %f % of factory value\n\r", SelfTest[4]);  
+        //pc.printf("z-axis self test: gyration trim within : %f % of factory value\n\r", SelfTest[5]);  
+        pc.printf("####Gyro and accelerometer Calibration will start in 5 seconds####\r\n");
+        pc.printf("####Please keep the IMU still\r\n");
+        wait(5);
+        pc.printf("####Calibration starts\r\n");
+        mpu9250.calibrateMPU9250(mpu9250.gyroBias, mpu9250.accelBias); // Calibrate gyro and accelerometers, load biases in bias registers  
+        pc.printf("x gyro bias = %f\n\r", mpu9250.gyroBias[0]);
+        pc.printf("y gyro bias = %f\n\r", mpu9250.gyroBias[1]);
+        pc.printf("z gyro bias = %f\n\r", mpu9250.gyroBias[2]);
+        pc.printf("x accel bias = %f\n\r", mpu9250.accelBias[0]);
+        pc.printf("y accel bias = %f\n\r", mpu9250.accelBias[1]);
+        pc.printf("z accel bias = %f\n\r", mpu9250.accelBias[2]);
+        wait(2);
+        ///initialization
+        mpu9250.initMPU9250(); 
+        pc.printf("MPU9250 initialized for active data mode....\n\r"); // Initialize device for active mode read of acclerometer, gyroscope, and temperature
+        mpu9250.initAK8963(mpu9250.magCalibration);
+        pc.printf("Magnetometer initilized\r\n");
+       // pc.printf("AK8963 initialized for active data mode....\n\r"); // Initialize device for active mode read of magnetometer
+       // pc.printf("Accelerometer full-scale range = %f  g\n\r", 2.0f*(float)(1<<Ascale));
+       // pc.printf("Gyroscope full-scale range = %f  deg/s\n\r", 250.0f*(float)(1<<Gscale));
+        if(mpu9250.Mscale == 0) pc.printf("Magnetometer resolution = 14  bits\n\r");
+        if(mpu9250.Mscale == 1) pc.printf("Magnetometer resolution = 16  bits\n\r");
+        if(mpu9250.Mmode == 2) pc.printf("Magnetometer ODR = 8 Hz\n\r");
+        if(mpu9250.Mmode == 6) pc.printf("Magnetometer ODR = 100 Hz\n\r");
+    }
+    else
+    {
+        pc.printf("Could not connect to MPU9250: \n\r");
+        pc.printf("%#x \n",  whoami);
+        while(1) ; // Loop forever if communication doesn't happen
+    }
+    mpu9250.getAres(); // Get accelerometer sensitivity
+    mpu9250.getGres(); // Get gyro sensitivity
+    mpu9250.getMres(); // Get magnetometer sensitivity
+    pc.printf("Accelerometer sensitivity is %f LSB/g \n\r", 1.0f/mpu9250.aRes);
+    pc.printf("Gyroscope sensitivity is %f LSB/deg/s \n\r", 1.0f/mpu9250.gRes);
+    pc.printf("Magnetometer sensitivity is %f LSB/G \n\r", 1.0f/mpu9250.mRes);
+    pc.printf("####IMU initialization done####\r\n");
+    wait(1);
+}
+
+
+void mag_cali(){
+    int32_t mag_bias[3] = {0, 0, 0};
+    int16_t mag_max[3] = {-32767, -32767, -32767}, mag_min[3] = {32767, 32767, 32767}, mag_temp[3] = {0, 0, 0};
+    //float dest1[3]={0,0,0}, dest2[3]={0,0,0};
+    pc.printf("####Compass Calibration starts in 5 seconds\r\n");
+    wait(5);
+    pc.printf("###Start moving your imu in figure 8\r\n");
+    for (int i=0;i<1500;i++){   //1500 for 100 Hz           
+            mpu9250.readMagData(mag_temp);  // Read the x/y/z adc values   
+            for(int jj=0; jj<3; jj++){
+            if(mag_temp[jj] > mag_max[jj]) mag_max[jj] = mag_temp[jj];
+            if(mag_temp[jj] < mag_min[jj]) mag_min[jj] = mag_temp[jj];
+            }
+            wait(0.01);//delay for 10 ms.
+    }
+    //get hard iron correction
+    // Get hard iron correction
+    mag_bias[0]  = (mag_max[0] + mag_min[0])/2;  // get average x mag bias in counts
+    mag_bias[1]  = (mag_max[1] + mag_min[1])/2;  // get average y mag bias in counts
+    mag_bias[2]  = (mag_max[2] + mag_min[2])/2;  // get average z mag bias in counts
+    mpu9250.magbias[0] = (float) mag_bias[0]*mpu9250.mRes*mpu9250.magCalibration[0];  // save mag biases in G for main program
+    mpu9250.magbias[1] = (float) mag_bias[1]*mpu9250.mRes*mpu9250.magCalibration[1];   
+    mpu9250.magbias[2] = (float) mag_bias[2]*mpu9250.mRes*mpu9250.magCalibration[2];  
+    pc.printf("####Mag bias =%f,%f,%f\r\n",mpu9250.magbias[0],mpu9250.magbias[1],mpu9250.magbias[2]);
+    /*//get soft iron correction
+    // Get soft iron correction estimate
+    mag_scale[0]  = (mag_max[0] - mag_min[0])/2;  // get average x axis max chord length in counts
+    mag_scale[1]  = (mag_max[1] - mag_min[1])/2;  // get average y axis max chord length in counts
+    mag_scale[2]  = (mag_max[2] - mag_min[2])/2;  // get average z axis max chord length in counts
+    
+    float avg_rad = mag_scale[0] + mag_scale[1] + mag_scale[2];
+    avg_rad /= 3.0;
+    
+    dest2[0] = avg_rad/((float)mag_scale[0]);
+    dest2[1] = avg_rad/((float)mag_scale[1]);
+    dest2[2] = avg_rad/((float)mag_scale[2]);
+    */
+    pc.printf("####Mag Calibration done!\r\n");
+}
+
+void set_servo_angle(){
+    if(mpu9250.pitch > 90){
+        angle = 90;
+        }
+    if(mpu9250.pitch < -90){
+        angle = -90;
+        }
+    else{
+        angle=mpu9250.pitch;
+        }
+    servo_PWM =  .0005/(angle+180);
+    servo.period(0.2);
+    servo.pulsewidth(servo_PWM);
+}
+
+void log_data(){
+    
+    FILE *fp = fopen(file_name, "a"); 
+    if(fp == NULL) error("Could not open file for write\n"); 
+    
+    fprintf(fp, "$IMURW,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f\r\n", Time,mpu9250.ax,mpu9250.ay,mpu9250.az,mpu9250.gx,mpu9250.gy,mpu9250.gz,mpu9250.mx,mpu9250.my,mpu9250.mz);
+    fprintf(fp, "$IMUPS,%f,%f,%f,%f,%f,%f,%f,%f;\r\n", Time, mpu9250.roll, mpu9250.pitch, mpu9250.yaw,mpu9250.q[0],mpu9250.q[1],mpu9250.q[2],mpu9250.q[3]);
+    fprintf(fp, "$SERVO,%f,%f,%f,%f;\r\n", Time, servo_PWM, angle, mpu9250.pitch);
+    fclose(fp); 
+    
+}
+
+int main() {
+    pc.baud(9600);
+    pc.printf("Please set a file name \r\n");
+    pc.scanf("%s",buffer);
+    sprintf(file_name,"/sd/mydir/%s.txt",buffer);
+    pc.printf("The file name and directory is: %s\r\n", file_name);
+    logTicker.attach(&log_data,1.0);
+    t.start();  
+    mpu9250_initialization();
+    mag_cali();
+    
+    
+    pc.printf("####IMU is all set, going to start sensing in 5 seconds\r\n");
+    wait(5);
+    while(1){
+        if(mpu9250.readByte(MPU9250_ADDRESS, INT_STATUS) & 0x01) {  // On interrupt, check if data ready interrupt
+            mpu9250.readAccelData(mpu9250.accelCount);  // Read the x/y/z adc values   
+            // Now we'll calculate the accleration value into actual g's
+            mpu9250.ax = (float)mpu9250.accelCount[0]*mpu9250.aRes - mpu9250.accelBias[0];  // get actual g value, this depends on scale being set
+            mpu9250.ay = (float)mpu9250.accelCount[1]*mpu9250.aRes - mpu9250.accelBias[1];   
+            mpu9250.az = (float)mpu9250.accelCount[2]*mpu9250.aRes - mpu9250.accelBias[2];  
+           
+            mpu9250.readGyroData(mpu9250.gyroCount);  // Read the x/y/z adc values
+            // Calculate the gyro value into actual degrees per second
+            mpu9250.gx = (float)mpu9250.gyroCount[0]*mpu9250.gRes - mpu9250.gyroBias[0];  // get actual gyro value, this depends on scale being set
+            mpu9250.gy = (float)mpu9250.gyroCount[1]*mpu9250.gRes - mpu9250.gyroBias[1];  
+            mpu9250.gz = (float)mpu9250.gyroCount[2]*mpu9250.gRes - mpu9250.gyroBias[2];   
+          
+            mpu9250.readMagData(mpu9250.magCount);  // Read the x/y/z adc values   
+            // Calculate the magnetometer values in milliGauss
+            // Include factory calibration per data sheet and user environmental corrections
+            mpu9250.mx = (float)mpu9250.magCount[0]*mpu9250.mRes*mpu9250.magCalibration[0] - mpu9250.magbias[0];  // get actual magnetometer value, this depends on scale being set
+            mpu9250.my = (float)mpu9250.magCount[1]*mpu9250.mRes*mpu9250.magCalibration[1] - mpu9250.magbias[1];  
+            mpu9250.mz = (float)mpu9250.magCount[2]*mpu9250.mRes*mpu9250.magCalibration[2] - mpu9250.magbias[2];   
+        }
+        
+        mpu9250.Now = t.read_us();
+        mpu9250.deltat = (float)((mpu9250.Now - mpu9250.lastUpdate)/1000000.0f) ; // set integration time by time elapsed since last filter update
+        mpu9250.lastUpdate = mpu9250.Now;
+        sum += mpu9250.deltat;
+        sumCount++;
+        //mpu9250.MadgwickQuaternionUpdate(ax, ay, az, gx*PI/180.0f, gy*PI/180.0f, gz*PI/180.0f,  mx,  my, mz);
+        //compute the quaternion.
+
+         mpu9250.MahonyQuaternionUpdate(mpu9250.ax, mpu9250.ay, mpu9250.az,
+                                       mpu9250.gx*PI/180.00, mpu9250.gy*PI/180.00, mpu9250.gz*PI/180.00, 
+                                       mpu9250.mx, mpu9250.my, mpu9250.mz);
+
+           //    pc.printf("Q=%f,%f,%f,%f\r\n",mpu9250.q[0],mpu9250.q[1],mpu9250.q[2],mpu9250.q[3]);
+        // Serial print and/or display at 0.5 s rate independent of data rates
+        mpu9250.delt_t = t.read_ms() - mpu9250.count;
+        if (mpu9250.delt_t > 100) {
+//            pc.printf("ax = %f", 1000*mpu9250.ax); 
+//            pc.printf(" ay = %f", 1000*mpu9250.ay); 
+//            pc.printf(" az = %f  mg\n\r", 1000*mpu9250.az); 
+//            pc.printf("gx = %f", mpu9250.gx); 
+//            pc.printf("gy = %f", mpu9250.gy); 
+//            pc.printf("gz = %f  deg/s\n\r", mpu9250.gz); 
+            //pc.printf("mx = %f", mpu9250.mx); 
+            //pc.printf(" my = %f", mpu9250.my); 
+            //pc.printf(" mz = %f  mG\n\r", mpu9250.mz);
+//            tempCount = mpu9250.readTempData();  // Read the adc values
+//            temperature = ((float) tempCount) / 333.87f + 21.0f; // Temperature in degrees Centigrade
+//            pc.printf(" temperature = %f  C\n\r", temperature); 
+//            
+            mpu9250.roll  = atan2(2.0f * (mpu9250.q[0] * mpu9250.q[1] + mpu9250.q[2] * mpu9250.q[3]),
+                                  mpu9250.q[0] * mpu9250.q[0] - mpu9250.q[1] * mpu9250.q[1] - mpu9250.q[2] * mpu9250.q[2] + mpu9250.q[3] * mpu9250.q[3]);
+            mpu9250.pitch = -asin(2.0f * (mpu9250.q[1] * mpu9250.q[3] - mpu9250.q[0] * mpu9250.q[2]));
+            mpu9250.yaw   = atan2(2.0f * (mpu9250.q[1] * mpu9250.q[2] + mpu9250.q[0] * mpu9250.q[3]), 
+                                  mpu9250.q[0] * mpu9250.q[0] + mpu9250.q[1] * mpu9250.q[1] - mpu9250.q[2] * mpu9250.q[2] - mpu9250.q[3] * mpu9250.q[3]);   
+            mpu9250.pitch *= 180.0f / PI;
+            mpu9250.yaw   *= 180.0f / PI; 
+            mpu9250.yaw   += 15.0f; // Declination at RI
+            mpu9250.roll  *= 180.0f / PI;
+            
+            
+            
+            
+            Time = t.read();
+            set_servo_angle();
+            pc.printf("Pitch, Servo Angle, Time: %f %f %f %f\n\r", mpu9250.pitch, angle, Time);
+            myled= !myled;
+            mpu9250.count = t.read_ms(); 
+            
+            if(mpu9250.count > 1<<21) {
+                t.start(); // start the timer over again if ~30 minutes has passed
+                mpu9250.count = 0;
+                mpu9250.deltat= 0;
+                mpu9250.lastUpdate = t.read_us();
+            }
+            sum = 0;
+            sumCount = 0; 
+        }
+ 
+    
+    }    
+
+}