An mbed app using the MPU6050 for crash detection

Dependencies:   MPU6050 SDFileSystem mbed

Revision:
0:be9547c5b62c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sat Mar 14 15:46:05 2015 +0000
@@ -0,0 +1,647 @@
+/* Testing whether we can get peak detection and how fast we can get data. Stripped out all
+    of the data collection stuff and now we just light an led when we get a peak detection*/
+
+// Libraries to include
+#include "mbed.h"
+#include "MPU6050.h"
+#include "SDFileSystem.h"
+
+// Pin Declarations
+// Four on-board LED
+DigitalOut myled1(LED1);
+DigitalOut myled2(LED2);
+DigitalOut myled3(LED3);
+DigitalOut myled4(LED4);
+
+// External LED
+DigitalOut crashled(p20);
+DigitalOut ext_myled2(p12);
+DigitalOut ext_myled3(p13);
+DigitalOut ext_myled4(p14);
+
+// External Pushbuttons
+InterruptIn pb1(p21);
+InterruptIn pb2(p22);
+InterruptIn crashb(p23);
+
+// Function prototypes
+void pb1_irq();
+void pb2_irq();
+void crashb_irq();
+void threshold_detector(int cur_i);
+
+
+void initMPU6050();
+void setup();
+
+// Macros
+#define VARS_FILE_NAME "/sd/data_acq/vars.txt"
+#define LOG_FILE_NAME "/sd/data_acq/log_%d.txt"
+
+#define PACKET_NOTIFY_COUNT 100000000
+
+#define BUF_LEN 512
+
+// Global Variables
+SDFileSystem sd(p5, p6, p7, p8, "sd", p9, SDFileSystem::SWITCH_POS_NC, 18000000); // SD Filesystem
+Serial pc(USBTX, USBRX); // Serial Debug
+bool serial_toggle = 1;
+
+// Files
+FileHandle *fp_data;
+//FILE *fp_data;
+FILE *fp_log;
+FILE *fp_vars;
+
+char data_file[50];
+char log_file[50];
+
+int log_file_count = 0;
+int data_file_count = 0;
+int imu_num = 1;
+
+// IMU
+MPU6050 *imu1 = new MPU6050(); // IMU instance
+bool connected, calibrated;
+
+Timer timer1; // Timer
+
+// Toggle the LEDs
+bool led1_val = false;
+bool led2_val = false;
+
+// Data status
+bool get_data = false;
+
+// Data sample counter
+bool data_write = true;
+bool packet_counter = false;
+int counting_up = 0;
+int counting_up_1 = 0;
+float elapsed_time = 0;
+
+// Mag threshold
+int mag_threshold = 25;
+int mag_window = 10;
+float mag_percent = 0.90;
+float avg_mag = 0;
+float acc_mag = 0;
+float acc_running_sum = 0;
+int counter_acc = 0;
+
+// Rotation Threshold
+int rot_threshold = 129600; // 360 degrees per second
+int rot_window = 10;
+float rot_percent = 0.90;
+float avg_rot = 0;
+float gyro_mag = 0;
+float gyro_running_sum = 0;
+int counter_gyro = 0;
+
+// Data
+int i = 0; // Buffer index variable
+int j = 0; // Loop index variable
+float ax_buf[BUF_LEN], ay_buf[BUF_LEN], az_buf[BUF_LEN];
+float avg_samp_mag[BUF_LEN], avg_samp_rot[BUF_LEN];
+float gx_buf[BUF_LEN], gy_buf[BUF_LEN], gz_buf[BUF_LEN];
+//float yaw_buf[BUF_LEN], pitch_buf[BUF_LEN], roll_buf[BUF_LEN];
+
+float *ax, *ay, *az, *gx, *gy, *gz, *yaw, *pitch, *roll;
+
+// Biases
+float gyro_bias[3], accel_bias[3];
+
+// Current State Machine State
+enum state{STATE_1, STATE_2A, STATE_2B, STATE_3A, STATE_3B};
+enum state cur_state = STATE_1;
+
+int main() {
+    
+    __disable_irq();    // Disable Interrupts
+    
+    setup();
+
+    if (connected & !calibrated) {
+        fclose(fp_log);
+
+        // Set up the IMU to default values
+        initMPU6050();
+
+        // Setup for unique values
+        imu1->setFullScaleAccelRange(MPU6050_ACCEL_FS_16);
+        imu1->setFullScaleGyroRange(MPU6050_GYRO_FS_2000);
+
+        // Set up the data packets
+        ax = (float *) malloc(sizeof(*ax));
+        ay = (float *) malloc(sizeof(*ay));
+        az = (float *) malloc(sizeof(*az));
+        gx = (float *) malloc(sizeof(*gx));
+        gy = (float *) malloc(sizeof(*gy));
+        gz = (float *) malloc(sizeof(*gz));
+        yaw = (float *) malloc(sizeof(*yaw));
+        pitch = (float *) malloc(sizeof(*pitch));
+        roll = (float *) malloc(sizeof(*roll));
+        
+        pc.printf("SystemCoreClock = %d Hz\n\r", SystemCoreClock);
+        
+        pc.printf("Waiting to take data...\n\r");
+
+        __enable_irq();
+        
+        myled1 = 0;
+        myled2 = 1;
+        ext_myled2 = 1;
+
+        while(1) {
+            if (get_data) {
+                counting_up_1++;
+                // Run the function to get the data and convert it
+                if (imu1->getIntDataReadyStatus()) {
+                    counting_up++;
+                    // Call the helper function
+                    imu1->getAndConvertData(ax, ay, az, yaw, pitch, roll, accel_bias, gyro_bias, gx, gy, gz);
+                    //imu1->getMotion6(ax, ay, az, yaw, pitch, roll);
+                }
+                
+                // Store the most recent values
+                ax_buf[i % BUF_LEN] = *ax;
+                ay_buf[i % BUF_LEN] = *ay;
+                az_buf[i % BUF_LEN] = *az;
+
+                gx_buf[i % BUF_LEN] = *gx;
+                gy_buf[i % BUF_LEN] = *gy;
+                gz_buf[i % BUF_LEN] = *gz;
+
+//                yaw_buf[i % BUF_LEN] = *yaw;
+//                pitch_buf[i % BUF_LEN] = *pitch;
+//                roll_buf[i % BUF_LEN] = *roll;
+                
+                threshold_detector(i);
+
+                i++;
+                if (i == BUF_LEN && data_write) {
+                    // On my mac, it is writing in little-endian
+                    
+                    // Store the data on the SD card
+//                    fp_data->write(ax_buf, sizeof(ax_buf));
+//                    fp_data->write("\n", sizeof(char));
+//                    fp_data->write(ay_buf, sizeof(ay_buf));
+//                    fp_data->write("\n", sizeof(char));
+//                    fp_data->write(az_buf, sizeof(az_buf));
+//                    fp_data->write("\n", sizeof(char));
+//                    fp_data->write(yaw_buf, sizeof(yaw_buf));
+//                    fp_data->write("\n", sizeof(char));
+//                    fp_data->write(pitch_buf, sizeof(pitch_buf));
+//                    fp_data->write("\n", sizeof(char));
+//                    fp_data->write(roll_buf, sizeof(roll_buf));
+//                    fp_data->write("\n", sizeof(char));
+                    
+//                    for (j = 0; j < BUF_LEN; j++) {
+//                        fprintf(fp_data, "%f, %f, %f, %f, %f, %f\n", ax_buf[j], ay_buf[j], az_buf[j], yaw_buf[j], pitch_buf[j], roll_buf[j]);
+//                    }
+
+                    for (j = 0; j < BUF_LEN; j++) {
+                        fp_data->write(&(ax_buf[j]), sizeof(ax_buf[j]));
+                        fp_data->write(&(ay_buf[j]), sizeof(ay_buf[j]));
+                        fp_data->write(&(az_buf[j]), sizeof(az_buf[j]));
+                        fp_data->write(&(gx_buf[j]), sizeof(gx_buf[j]));
+                        fp_data->write(&(gy_buf[j]), sizeof(gy_buf[j]));
+                        fp_data->write(&(gz_buf[j]), sizeof(gz_buf[j]));
+//                        fp_data->write(&(yaw_buf[j]), sizeof(yaw_buf[j]));
+//                        fp_data->write(&(pitch_buf[j]), sizeof(pitch_buf[j]));
+//                        fp_data->write(&(roll_buf[j]), sizeof(roll_buf[j]));
+                        fp_data->write(&(avg_samp_mag[j]), sizeof(avg_samp_mag[j]));
+                        fp_data->write(&(avg_samp_rot[j]), sizeof(avg_samp_rot[j]));
+                        //pc.printf("%f %f %f %f %f %f\n\r", gx_buf[j], gy_buf[j], gz_buf[j], yaw_buf[j], pitch_buf[j], roll_buf[j]);
+                    }
+
+                    // Reset i
+                    i = 0;
+                }
+//                
+//
+//                // Periodically tell we are still taking data
+//                if (packet_counter) {
+//                    if ((counting_up % PACKET_NOTIFY_COUNT) == 0) {
+//                        if (serial_toggle)
+//                            pc.printf("%d Packets Received\n\r", counting_up);
+//
+//                        if ((fp_log = fopen(log_file, "a")) == NULL) {
+//                            if (serial_toggle) 
+//                                pc.printf("Failed to open log file 0 \n\r");
+//                        }
+//                        else {
+//                            fprintf(fp_log, "%d Packets Received\n\r", counting_up);
+//                            fclose(fp_log);
+//                        }
+//                    }
+//                }
+            }
+        }
+    }
+    else {
+        pc.printf("Conection Fail!\n\r");
+        fprintf(fp_log, "Connection Fail!\n\r");
+
+        fclose(fp_log);
+
+        while(1) {
+            myled4 = 0;
+            ext_myled4 = 0;
+            myled1 = 1;
+            wait(0.1);
+            myled1 = 0;
+            myled2 = 1;
+            ext_myled2 = 1;
+            wait(0.1);
+            myled2 = 0;
+            ext_myled2 = 0;
+            myled3 = 1;
+            ext_myled3 = 1;
+            wait(0.1);
+            myled3 = 0;
+            ext_myled3 = 0;
+            myled4 = 1;
+            ext_myled4 = 1;
+            wait(0.1);
+        }
+    }
+}
+
+void pb1_irq() {
+    switch (cur_state) {
+        case STATE_1:
+            cur_state = STATE_2A;
+            pc.printf("PB1: STATE_1->STATE_2A\n\r");
+            break;
+        case STATE_2A:
+            pc.printf("PB1: STATE_2A->STATE_2A\n\r");
+            break;
+        case STATE_3A:
+            cur_state = STATE_1;
+            if (serial_toggle)
+                pc.printf("PB1: STATE_3A->STATE_1\n\r");
+
+            // Create the data file name
+            sprintf(data_file, "data_acq/data%d.txt", data_file_count);
+            //sprintf(data_file, "/sd/data_acq/data%d.txt", data_file_count);
+            data_file_count++; // Increment the data file count
+
+            // Write the new count to the vars file
+            fp_vars = fopen(VARS_FILE_NAME, "w");
+            fprintf(fp_vars, "log=%d\ndata=%d\nimu=%d\n", log_file_count+1, data_file_count, imu_num);
+            fclose(fp_vars);
+
+            // Try to open the data file
+            fp_data = sd.open(data_file, O_WRONLY | O_CREAT | O_TRUNC);
+            //fp_data = fopen(data_file, "w");
+            if (fp_data == NULL) {
+                if (serial_toggle)
+                    pc.printf("Failed to open data file: %s\n\r", data_file);
+                
+                if ((fp_log = fopen(log_file, "a")) == NULL)
+                    if (serial_toggle)
+                        pc.printf("Failed to open log file 1\n\r");
+                else {
+                    fprintf(fp_log, "Failed to open data file: %s\n\r", data_file);
+                    fclose(fp_log);
+                }
+            }
+            else {
+                
+                if (serial_toggle)
+                    pc.printf("Opened data file for writing: %s\n\r", data_file);
+        
+                if ((fp_log = fopen(log_file, "a")) == NULL)
+                    if (serial_toggle)
+                        pc.printf("Failed to open log file 2\n\r");
+                else {
+                    fprintf(fp_log, "Opened data file for writing: %s\n\r", data_file);
+                    fclose(fp_log);
+                }
+            
+                if (serial_toggle)
+                    pc.printf("Started taking data...\n\r");
+
+                get_data = true;
+                timer1.start();
+                myled2 = 0; // Taking data
+                myled3 = 1;
+            }
+            break;
+        case STATE_2B:
+            cur_state = STATE_3B;
+            pc.printf("PB1: STATE_2B->STATE_3B\n\r");
+            break;
+        case STATE_3B:
+            cur_state = STATE_2A;
+            pc.printf("PB1: STATE_3B->STATE_2A\n\r");
+            break;
+    }  
+}
+
+void pb2_irq() {
+    
+    switch (cur_state) {
+        case STATE_1:
+            cur_state = STATE_2B;
+            pc.printf("PB2: STATE_1->STATE_2B\n\r");
+            break;
+        case STATE_2A:
+            cur_state = STATE_3A;
+            pc.printf("PB2: STATE_2A->STATE_3B\n\r");
+            break;
+        case STATE_3A:
+            cur_state = STATE_2B;
+            pc.printf("PB2: STATE_3A->STATE_2B\n\r");
+            break;
+        case STATE_2B:
+            pc.printf("PB2: STATE_2B->STATE_2B\n\r");
+            break;
+        case STATE_3B:
+            cur_state = STATE_1;
+            timer1.stop();
+            
+            // Write the remaining values from the buffer
+            for (j = 0; j < i; j++) {
+                fp_data->write(&(ax_buf[j]), sizeof(ax_buf[j]));
+                fp_data->write(&(ay_buf[j]), sizeof(ay_buf[j]));
+                fp_data->write(&(az_buf[j]), sizeof(az_buf[j]));
+                fp_data->write(&(gx_buf[j]), sizeof(gx_buf[j]));
+                fp_data->write(&(gy_buf[j]), sizeof(gy_buf[j]));
+                fp_data->write(&(gz_buf[j]), sizeof(gz_buf[j]));
+//                fp_data->write(&(yaw_buf[j]), sizeof(yaw_buf[j]));
+//                fp_data->write(&(pitch_buf[j]), sizeof(pitch_buf[j]));
+//                fp_data->write(&(roll_buf[j]), sizeof(roll_buf[j]));
+                fp_data->write(&(avg_samp_mag[j]), sizeof(avg_samp_mag[j]));
+                fp_data->write(&(avg_samp_rot[j]), sizeof(avg_samp_rot[j]));
+                //pc.printf("%f %f %f %f %f %f\n\r", ax_buf[j], ay_buf[j], az_buf[j], yaw_buf[j], pitch_buf[j], roll_buf[j]);
+            }
+
+            if(serial_toggle)
+                pc.printf("PB2: STATE_3B->STATE_1\n\r");
+
+            if (fp_data != NULL) {
+                if (serial_toggle) {
+                    pc.printf("\n\rClosing files: %s\n\r", data_file);
+                    pc.printf("Samples Taken: %d, %d\n\r", counting_up, counting_up_1);
+                    pc.printf("Time for all samples: %f\n\r", elapsed_time = timer1.read());
+                    pc.printf("Sample Rate: %f\n\r", (float) counting_up / elapsed_time);
+                }
+                
+                if (fp_data->close())
+                //if (fclose(fp_data))
+                    pc.printf("Failed to close file\n\r");
+                else
+                    fp_data = NULL;
+
+                if ((fp_log = fopen(log_file, "a")) == NULL) {
+                    if (serial_toggle) {
+                        pc.printf("Failed to open log file\n\r");
+                    }
+                }
+                else {
+                    fprintf(fp_log, "\n\rClosing file: %s\n\r", data_file);
+                    fprintf(fp_log, "Samples Taken: %d,%d\n\r", counting_up, counting_up_1);
+                    fprintf(fp_log, "Time for all samples: %f\n\r", elapsed_time);
+                    fprintf(fp_log, "Sample Rate: %f\n\r", (float) counting_up / elapsed_time);
+                    fclose(fp_log);
+                }
+            }
+            
+            get_data = false;
+            counting_up = 0;
+            counting_up_1 = 0;
+            timer1.reset();
+    
+            myled3 = 0; // Done taking data
+        
+            // Flash the fourth led twice
+            for (j = 0; j < 4; j++) {
+                myled4 = 1;
+                wait(0.25);
+                myled4 = 0;
+                wait(0.25);
+            }
+                
+            myled2 = 1; // Ready to take more data
+            break;
+    } // Switch
+}
+
+void crashb_irq() {
+    crashled = 0;
+}
+
+void threshold_detector(int cur_i) {
+    // The last 10 samples
+    for (j = i; j > i-mag_window; j--) {
+        acc_mag = 0;
+        acc_mag = ax_buf[j % BUF_LEN]*ax_buf[j % BUF_LEN] + ay_buf[j % BUF_LEN]*ay_buf[j % BUF_LEN] + az_buf[j % BUF_LEN]*az_buf[j % BUF_LEN];
+        acc_running_sum = acc_running_sum + acc_mag;
+        
+        gyro_mag = 0;
+        gyro_mag = gx_buf[j % BUF_LEN]*gx_buf[j % BUF_LEN] + gy_buf[j % BUF_LEN]*gy_buf[j % BUF_LEN] + gz_buf[j % BUF_LEN]*gz_buf[j % BUF_LEN];
+        gyro_running_sum = gyro_running_sum + gyro_mag;
+    }
+    
+    avg_mag = acc_running_sum / mag_window;
+    avg_samp_mag[i] = avg_mag;
+    
+    avg_rot = gyro_running_sum / rot_window;
+    avg_samp_rot[i] = avg_rot;
+    
+    if (avg_mag > mag_threshold*mag_percent)
+        crashled = 1;
+        
+    if (avg_rot > rot_threshold*rot_percent)
+        crashled = 1;
+        
+    acc_running_sum = 0;
+    gyro_running_sum = 0;
+    acc_mag = 0;
+    gyro_mag = 0;
+    avg_mag = 0;
+    avg_rot = 0;
+}
+
+void setup() {
+    // Setting up
+    myled1 = 1;
+    
+    // Pin setup
+    pb1.mode(PullUp);
+    pb1.rise(&pb1_irq);
+
+    pb2.mode(PullUp);
+    pb2.rise(&pb2_irq);
+    
+    crashb.mode(PullUp);
+    crashb.rise(&crashb_irq);
+    
+    // Serial debug baud rate 
+    pc.baud(9600);
+    pc.printf("\n\r");
+    
+    //Display the card type and capacity
+    pc.printf("\nCard type: ");
+    if (sd.card_type() == SDFileSystem::CARD_NONE)
+        pc.printf("None\n\r");
+    else if (sd.card_type() == SDFileSystem::CARD_MMC)
+        pc.printf("MMC\n\r");
+    else if (sd.card_type() == SDFileSystem::CARD_SD)
+        pc.printf("SD\n\r");
+    else if (sd.card_type() == SDFileSystem::CARD_SDHC)
+        pc.printf("SDHC\n\r");
+    else
+        pc.printf("Unknown\n\r");
+    pc.printf("Sectors: %llu\n\r", sd.disk_sectors());
+    pc.printf("Capacity: %.1fMB\n\r", (sd.disk_sectors() * 512) / 1048576.0);
+
+    // Open the setup file, if possible, if not, create one
+    // Contains the last log file number
+    fp_vars = fopen(VARS_FILE_NAME, "r");
+    if (fp_vars == NULL) {
+        pc.printf("No Vars File; Creating One...\n\r");
+        fp_vars = fopen(VARS_FILE_NAME, "w");
+        fprintf(fp_vars, "log=%d\ndata=%d\nimu=%d\n", log_file_count, data_file_count, imu_num);
+        fprintf(fp_vars, "mag_threshold=%d\nmag_window=%d\nmag_percent=%f\n", mag_threshold, mag_window, mag_percent);
+        fprintf(fp_vars, "rot_threshold=%d\nrot_window=%d\nrot_percent=%f\n", rot_threshold, rot_window, rot_percent);
+        fprintf(fp_vars, "serial=%d\n", serial_toggle);
+        fclose(fp_vars);
+    }
+    else {
+        fscanf(fp_vars, "log=%d\ndata=%d\nimu=%d\n", &log_file_count, &data_file_count, &imu_num);
+        fscanf(fp_vars, "mag_threshold=%d\nmag_window=%d\nmag_percent=%f\n", &mag_threshold, &mag_window, &mag_percent);
+        fscanf(fp_vars, "rot_threshold=%d\nrot_window=%d\nrot_percent=%f\n", &rot_threshold, &rot_window, &rot_percent);
+        fscanf(fp_vars, "serial=%d\n", &serial_toggle);
+        rewind(fp_vars);
+        fprintf(fp_vars, "log=%d\ndata=%d\nimu=%d\n", log_file+1, data_file+1, imu_num);
+        pc.printf("%d,%d,%d\n\r", log_file_count, data_file_count, imu_num);
+    }
+    
+    // Open the log file to write
+    sprintf(log_file, LOG_FILE_NAME, log_file_count);
+    if ((fp_log = fopen(log_file, "w")) == NULL)
+        pc.printf("Failed to open log file: %s\n\r", log_file);
+        
+    // Get the last log file number
+    pc.printf("Log File Starting at %d\n\r", log_file_count);
+    pc.printf("Data File Starting at %d\n\r", data_file_count);
+    pc.printf("Using IMU %d\n\r", imu_num);
+    
+    fprintf(fp_log, "Log File Starting at %d\n\r", log_file_count);
+    fprintf(fp_log, "Data File Starting at %d\n\r", data_file_count);
+    fprintf(fp_log, "Using IMU %d\n\r", imu_num);
+    
+    // An empty line
+    fprintf(fp_log, "\n\r");
+    
+    // Test the connection
+    connected = imu1->testConnection();
+    if (connected) {
+        pc.printf("Connection Success!\n\r");
+        fprintf(fp_log, "Connection Success!\n\r");
+    }
+    else {
+        pc.printf("Connection Failed!\n\r");
+        fprintf(fp_log, "Connection Failed!\n\r");
+    }
+
+    if (connected) {
+        float destination[6];
+        calibrated = imu1->selfTest(destination);
+
+        if (!calibrated) {
+            pc.printf("Passed Self Test\n\r");
+            fprintf(fp_log, "Passed Self Test\n\r");
+        }
+        else {
+            pc.printf("Failed Self Test\n\r");
+            fprintf(fp_log, "Failed Self Test\n\r");
+        }
+
+        // Set the biases
+        accel_bias[0] = 0;
+        accel_bias[1] = 0;
+        accel_bias[2] = 0;
+        
+        gyro_bias[0] = 0;
+        gyro_bias[1] = 0;
+        gyro_bias[2] = 0;
+    }
+}
+
+/* Notes on sampling rates and output rates
+ * The accelerometer ALWAYS outputs data at 1kHz.
+ * The gyroscope has a variable output rate at either 1 kHz or 8 kHz
+ *      set by DLPF_CFG
+ * The MPU6050 will sample data at the rate specified by setting the
+ *      SMPLRT_DIV value and put these values into the sensor output
+ *      registers, fifo output, dmp sampling, and motion detection.
+ * What this means is that even though the accelerometer and gyroscope
+ *      are outputting at 1 kHz and 1 or 8 kHz, the MPU6050 may be
+ *      ignoring data if the sampling rate is set lower than these. It
+ *      also means that it can get multiple accelerometer outputs that
+ *      are duplicates if the sampling rate is set higher than 1 kHz.
+ * The bandpass filter causes a delay in the data getting outputted so
+ *      this also needs to be factored into the equation. From my
+ *      understanding, the delay will set the maximum rate that the
+ *      sensor can output at. So a delay of 4.9 ms means that the max
+ *      rate that the sensor can output at is 1/0.0049s, about 200 Hz. 
+ * In this example we set DLPF_CFG = 0x3 which will set a 1 kHz 
+ *      output rate for both the gyro and acelerometer. But there
+ *      is a delay of 4.9 ms for the accelerometer and 4.8 ms for the
+ *      gyro so the output rate is 200 Hz. We set the MPU6050 sampling
+ *      rate to be 200 Hz so that we don't have duplicates and don't
+ *      miss any data point. 
+*/
+
+void initMPU6050() {
+    // Clear sleep mode bit, enable all sensors
+    imu1->setSleepEnabled(false);
+
+    // Wait for PLL to lock
+    wait(0.1);
+
+    // Set clock source to have x-axis gyro reference
+    imu1->setClockSource(MPU6050_CLOCK_PLL_XGYRO);
+
+    // Disable FSYNC and set accle and gyro to 44 and 42 Hz, respectively
+    // Set DLPF_CFG to 0 for a sample rate of 1 kHz for the acceleromter and
+    // 8 kHz for the gyroscope. 
+    imu1->setDLPFMode(MPU6050_DLPF_BW_256);
+
+    // Set the sampling rate of the device. This is the rate at which the registers
+    // get occupied and it is Gyroscope_Rate/x where x is the argument sent into 
+    // setRate(x)
+    imu1->setRate(0x3);
+
+    // Set the gyroscope configuration
+    imu1->setGyroXSelfTest(false); // Clear the self-test bits
+    imu1->setGyroYSelfTest(false);
+    imu1->setGyroZSelfTest(false);
+    imu1->setFullScaleGyroRange(MPU6050_GYRO_FS_250); // Clear the FS bits
+    imu1->setFullScaleGyroRange(MPU6050_GYRO_FS_2000); // Set the full-scale range
+
+    // Set the accelerometer configuration
+    imu1->setAccelXSelfTest(false); // Clear the self-test bits
+    imu1->setAccelYSelfTest(false); 
+    imu1->setAccelZSelfTest(false);
+    imu1->setFullScaleAccelRange(MPU6050_ACCEL_FS_2); // Clear the AFS bits
+    imu1->setFullScaleAccelRange(MPU6050_ACCEL_FS_16); // Set the full-scale range
+
+    // Configure interrupts and bypass enable
+    // Set interrupt pin active high, push-pull, and clear on read of INT_STATUS
+    // Enable I2C_BYPASS_EN so addition chips can join the I2C bus and all can be
+    // controlled by the microcontroller as master
+    imu1->setInterruptMode(MPU6050_INTMODE_ACTIVEHIGH);
+    imu1->setInterruptDrive(MPU6050_INTDRV_PUSHPULL);
+    imu1->setInterruptLatch(MPU6050_INTLATCH_WAITCLEAR);
+    imu1->setInterruptLatchClear(MPU6050_INTCLEAR_STATUSREAD);
+    imu1->setFSyncInterruptLevel(false);
+    imu1->setFSyncInterruptEnabled(false);
+    imu1->setI2CBypassEnabled(true);
+    imu1->setIntDataReadyEnabled(true);
+
+}
\ No newline at end of file