SkipperS2v2 and bmp

Dependencies:   BMP280 mpu9250forskipper mbed

Committer:
motoseki
Date:
Mon Aug 22 02:51:01 2016 +0000
Revision:
2:c1c7afb86416
Parent:
1:5c8e961811d1
for bmp280

Who changed what in which revision?

UserRevisionLine numberNew contents of line
motoseki 0:e6b1cd3646df 1 #include "mbed.h"
motoseki 0:e6b1cd3646df 2 #include "MPU9250.h"
motoseki 1:5c8e961811d1 3 #include "BMP280.h"
motoseki 1:5c8e961811d1 4
motoseki 1:5c8e961811d1 5 #define bmpadr 0x76<<1 // SD0 pulldown 0x76<<1 , pullup 0x77<<1
motoseki 1:5c8e961811d1 6
motoseki 1:5c8e961811d1 7 //I2C SDA,SCL: PC_9, PA_8
motoseki 0:e6b1cd3646df 8
motoseki 0:e6b1cd3646df 9 SPI spi(PC_12, PC_11, PC_10); // mosi, miso, sclk
motoseki 0:e6b1cd3646df 10 DigitalOut cs(PA_15);
motoseki 1:5c8e961811d1 11 Serial pc(PA_2,PA_3); //v2
motoseki 1:5c8e961811d1 12 //Serial pc(PA_9,PA_10); //original
motoseki 0:e6b1cd3646df 13
motoseki 0:e6b1cd3646df 14 float sum = 0;
motoseki 0:e6b1cd3646df 15 uint32_t sumCount = 0;
motoseki 2:c1c7afb86416 16 float bmpTEM , bmpPRE;
motoseki 0:e6b1cd3646df 17 MPU9250 mpu9250;
motoseki 1:5c8e961811d1 18 BMP280 bmp(PC_9, PA_8 ,bmpadr); //(PinName sda, PinName scl, char slave_adr)
motoseki 0:e6b1cd3646df 19 Timer t;
motoseki 2:c1c7afb86416 20 float PRES_first;
motoseki 0:e6b1cd3646df 21
motoseki 0:e6b1cd3646df 22 int main() {
motoseki 1:5c8e961811d1 23 wait(2);
motoseki 0:e6b1cd3646df 24 pc.baud(9600);
motoseki 0:e6b1cd3646df 25 //a8=0;
motoseki 0:e6b1cd3646df 26 //c9=0;
motoseki 0:e6b1cd3646df 27 pc.printf("SkipperS2 Peripheral Test...\n");wait(1);
motoseki 0:e6b1cd3646df 28 pc.printf("L2G2IS SPI 0xD9?\n");
motoseki 0:e6b1cd3646df 29 // Chip must be deselected
motoseki 0:e6b1cd3646df 30 cs = 1;
motoseki 0:e6b1cd3646df 31 // Setup the spi for 8 bit data, high steady state clock,
motoseki 0:e6b1cd3646df 32 // second edge capture, with a 1MHz clock rate
motoseki 0:e6b1cd3646df 33 spi.format(8,3);
motoseki 0:e6b1cd3646df 34 spi.frequency(1000000);
motoseki 0:e6b1cd3646df 35 // Select the device by seting chip select low
motoseki 0:e6b1cd3646df 36 cs = 0;
motoseki 0:e6b1cd3646df 37 // Send 0x8f, the command to read the WHOAMI register
motoseki 0:e6b1cd3646df 38 spi.write(0x80);
motoseki 0:e6b1cd3646df 39 // Send a dummy byte to receive the contents of the WHOAMI register
motoseki 0:e6b1cd3646df 40 int whoami_l2 = spi.write(0x00);
motoseki 0:e6b1cd3646df 41 pc.printf("WHOAMI register = 0x%X\n", whoami_l2);
motoseki 0:e6b1cd3646df 42 // Deselect the device
motoseki 0:e6b1cd3646df 43 cs = 1;
motoseki 0:e6b1cd3646df 44
motoseki 0:e6b1cd3646df 45 pc.printf("MPU9250 I2C test\n");
motoseki 0:e6b1cd3646df 46
motoseki 0:e6b1cd3646df 47
motoseki 0:e6b1cd3646df 48
motoseki 0:e6b1cd3646df 49
motoseki 0:e6b1cd3646df 50 //Set up I2C
motoseki 0:e6b1cd3646df 51 i2c.frequency(400000); // use fast (400 kHz) I2C
motoseki 0:e6b1cd3646df 52
motoseki 0:e6b1cd3646df 53 pc.printf("CPU SystemCoreClock is %d Hz\r\n", SystemCoreClock);
motoseki 0:e6b1cd3646df 54
motoseki 0:e6b1cd3646df 55 t.start();
motoseki 0:e6b1cd3646df 56
motoseki 1:5c8e961811d1 57 //BMP initialize
motoseki 1:5c8e961811d1 58 bmp.initialize();
motoseki 2:c1c7afb86416 59 PRES_first = bmp.getPressure();
motoseki 0:e6b1cd3646df 60
motoseki 0:e6b1cd3646df 61 // Read the WHO_AM_I register, this is a good test of communication
motoseki 0:e6b1cd3646df 62 uint8_t whoami = mpu9250.readByte(MPU9250_ADDRESS, WHO_AM_I_MPU9250); // Read WHO_AM_I register for MPU-9250
motoseki 0:e6b1cd3646df 63 pc.printf("I AM 0x%x\n\r", whoami); pc.printf("I SHOULD BE 0x71\n\r");
motoseki 0:e6b1cd3646df 64
motoseki 0:e6b1cd3646df 65 if (whoami == 0x71) // WHO_AM_I should always be 0x68
motoseki 0:e6b1cd3646df 66 {
motoseki 0:e6b1cd3646df 67 pc.printf("MPU9250 is online...\n\r");
motoseki 0:e6b1cd3646df 68 wait(1);
motoseki 0:e6b1cd3646df 69
motoseki 0:e6b1cd3646df 70
motoseki 0:e6b1cd3646df 71 mpu9250.resetMPU9250(); // Reset registers to default in preparation for device calibration
motoseki 0:e6b1cd3646df 72 mpu9250.calibrateMPU9250(gyroBias, accelBias); // Calibrate gyro and accelerometers, load biases in bias registers
motoseki 0:e6b1cd3646df 73 //pc.printf("x gyro bias = %f\n\r", gyroBias[0]);
motoseki 0:e6b1cd3646df 74 //pc.printf("y gyro bias = %f\n\r", gyroBias[1]);
motoseki 0:e6b1cd3646df 75 //pc.printf("z gyro bias = %f\n\r", gyroBias[2]);
motoseki 0:e6b1cd3646df 76 //pc.printf("x accel bias = %f\n\r", accelBias[0]);
motoseki 0:e6b1cd3646df 77 //pc.printf("y accel bias = %f\n\r", accelBias[1]);
motoseki 0:e6b1cd3646df 78 //pc.printf("z accel bias = %f\n\r", accelBias[2]);
motoseki 0:e6b1cd3646df 79 wait(2);
motoseki 0:e6b1cd3646df 80 mpu9250.initMPU9250();
motoseki 0:e6b1cd3646df 81 pc.printf("MPU9250 initialized for active data mode....\n\r"); // Initialize device for active mode read of acclerometer, gyroscope, and temperature
motoseki 0:e6b1cd3646df 82 mpu9250.initAK8963(magCalibration);
motoseki 0:e6b1cd3646df 83 pc.printf("AK8963 initialized for active data mode....\n\r"); // Initialize device for active mode read of magnetometer
motoseki 0:e6b1cd3646df 84 pc.printf("Accelerometer full-scale range = %f g\n\r", 2.0f*(float)(1<<Ascale));
motoseki 0:e6b1cd3646df 85 pc.printf("Gyroscope full-scale range = %f deg/s\n\r", 250.0f*(float)(1<<Gscale));
motoseki 0:e6b1cd3646df 86 if(Mscale == 0) pc.printf("Magnetometer resolution = 14 bits\n\r");
motoseki 0:e6b1cd3646df 87 if(Mscale == 1) pc.printf("Magnetometer resolution = 16 bits\n\r");
motoseki 0:e6b1cd3646df 88 if(Mmode == 2) pc.printf("Magnetometer ODR = 8 Hz\n\r");
motoseki 0:e6b1cd3646df 89 if(Mmode == 6) pc.printf("Magnetometer ODR = 100 Hz\n\r");
motoseki 0:e6b1cd3646df 90 wait(2);
motoseki 0:e6b1cd3646df 91 }
motoseki 0:e6b1cd3646df 92 else
motoseki 0:e6b1cd3646df 93 {
motoseki 0:e6b1cd3646df 94 pc.printf("Could not connect to MPU9250: \n\r");
motoseki 0:e6b1cd3646df 95 pc.printf("%#x \n", whoami);
motoseki 0:e6b1cd3646df 96
motoseki 2:c1c7afb86416 97
motoseki 0:e6b1cd3646df 98 while(1) ; // Loop forever if communication doesn't happen
motoseki 0:e6b1cd3646df 99 }
motoseki 0:e6b1cd3646df 100
motoseki 0:e6b1cd3646df 101 mpu9250.getAres(); // Get accelerometer sensitivity
motoseki 0:e6b1cd3646df 102 mpu9250.getGres(); // Get gyro sensitivity
motoseki 0:e6b1cd3646df 103 mpu9250.getMres(); // Get magnetometer sensitivity
motoseki 0:e6b1cd3646df 104 //pc.printf("Accelerometer sensitivity is %f LSB/g \n\r", 1.0f/aRes);
motoseki 0:e6b1cd3646df 105 //pc.printf("Gyroscope sensitivity is %f LSB/deg/s \n\r", 1.0f/gRes);
motoseki 0:e6b1cd3646df 106 //pc.printf("Magnetometer sensitivity is %f LSB/G \n\r", 1.0f/mRes);
motoseki 0:e6b1cd3646df 107 magbias[0] = +470.; // User environmental x-axis correction in milliGauss, should be automatically calculated
motoseki 0:e6b1cd3646df 108 magbias[1] = +120.; // User environmental x-axis correction in milliGauss
motoseki 0:e6b1cd3646df 109 magbias[2] = +125.; // User environmental x-axis correction in milliGauss
motoseki 0:e6b1cd3646df 110
motoseki 0:e6b1cd3646df 111 while(1) {
motoseki 0:e6b1cd3646df 112
motoseki 0:e6b1cd3646df 113 // If intPin goes high, all data registers have new data
motoseki 0:e6b1cd3646df 114 if(mpu9250.readByte(MPU9250_ADDRESS, INT_STATUS) & 0x01) { // On interrupt, check if data ready interrupt
motoseki 0:e6b1cd3646df 115
motoseki 0:e6b1cd3646df 116 mpu9250.readAccelData(accelCount); // Read the x/y/z adc values
motoseki 0:e6b1cd3646df 117 // Now we'll calculate the accleration value into actual g's
motoseki 0:e6b1cd3646df 118 ax = (float)accelCount[0]*aRes - accelBias[0]; // get actual g value, this depends on scale being set
motoseki 0:e6b1cd3646df 119 ay = (float)accelCount[1]*aRes - accelBias[1];
motoseki 0:e6b1cd3646df 120 az = (float)accelCount[2]*aRes - accelBias[2];
motoseki 0:e6b1cd3646df 121
motoseki 0:e6b1cd3646df 122 mpu9250.readGyroData(gyroCount); // Read the x/y/z adc values
motoseki 0:e6b1cd3646df 123 // Calculate the gyro value into actual degrees per second
motoseki 0:e6b1cd3646df 124 gx = (float)gyroCount[0]*gRes - gyroBias[0]; // get actual gyro value, this depends on scale being set
motoseki 0:e6b1cd3646df 125 gy = (float)gyroCount[1]*gRes - gyroBias[1];
motoseki 0:e6b1cd3646df 126 gz = (float)gyroCount[2]*gRes - gyroBias[2];
motoseki 0:e6b1cd3646df 127
motoseki 0:e6b1cd3646df 128 mpu9250.readMagData(magCount); // Read the x/y/z adc values
motoseki 0:e6b1cd3646df 129 // Calculate the magnetometer values in milliGauss
motoseki 0:e6b1cd3646df 130 // Include factory calibration per data sheet and user environmental corrections
motoseki 0:e6b1cd3646df 131 mx = (float)magCount[0]*mRes*magCalibration[0] - magbias[0]; // get actual magnetometer value, this depends on scale being set
motoseki 0:e6b1cd3646df 132 my = (float)magCount[1]*mRes*magCalibration[1] - magbias[1];
motoseki 0:e6b1cd3646df 133 mz = (float)magCount[2]*mRes*magCalibration[2] - magbias[2];
motoseki 0:e6b1cd3646df 134 }
motoseki 0:e6b1cd3646df 135
motoseki 0:e6b1cd3646df 136 Now = t.read_us();
motoseki 0:e6b1cd3646df 137 deltat = (float)((Now - lastUpdate)/1000000.0f) ; // set integration time by time elapsed since last filter update
motoseki 0:e6b1cd3646df 138 lastUpdate = Now;
motoseki 0:e6b1cd3646df 139
motoseki 0:e6b1cd3646df 140 sum += deltat;
motoseki 0:e6b1cd3646df 141 sumCount++;
motoseki 0:e6b1cd3646df 142
motoseki 0:e6b1cd3646df 143 // if(lastUpdate - firstUpdate > 10000000.0f) {
motoseki 0:e6b1cd3646df 144 // beta = 0.04; // decrease filter gain after stabilized
motoseki 0:e6b1cd3646df 145 // zeta = 0.015; // increasey bias drift gain after stabilized
motoseki 0:e6b1cd3646df 146 // }
motoseki 0:e6b1cd3646df 147
motoseki 0:e6b1cd3646df 148 // Pass gyro rate as rad/s
motoseki 0:e6b1cd3646df 149 mpu9250.MadgwickQuaternionUpdate(ax, ay, az, gx*PI/180.0f, gy*PI/180.0f, gz*PI/180.0f, my, mx, mz);
motoseki 0:e6b1cd3646df 150 mpu9250.MahonyQuaternionUpdate(ax, ay, az, gx*PI/180.0f, gy*PI/180.0f, gz*PI/180.0f, my, mx, mz);
motoseki 0:e6b1cd3646df 151
motoseki 0:e6b1cd3646df 152 // Serial print and/or display at 0.5 s rate independent of data rates
motoseki 0:e6b1cd3646df 153 delt_t = t.read_ms() - count;
motoseki 0:e6b1cd3646df 154 if (delt_t > 500) { // update LCD once per half-second independent of read rate
motoseki 0:e6b1cd3646df 155
motoseki 0:e6b1cd3646df 156 //pc.printf("ax = %f", 1000*ax);
motoseki 0:e6b1cd3646df 157 //pc.printf(" ay = %f", 1000*ay);
motoseki 0:e6b1cd3646df 158 //pc.printf(" az = %f mg\n\r", 1000*az);
motoseki 0:e6b1cd3646df 159
motoseki 1:5c8e961811d1 160 //pc.printf("gx = %f", gx);
motoseki 1:5c8e961811d1 161 //pc.printf(" gy = %f", gy);
motoseki 1:5c8e961811d1 162 //pc.printf(" gz = %f deg/s\n\r", gz);
motoseki 0:e6b1cd3646df 163
motoseki 0:e6b1cd3646df 164 //pc.printf("gx = %f", mx);
motoseki 0:e6b1cd3646df 165 //pc.printf(" gy = %f", my);
motoseki 0:e6b1cd3646df 166 //pc.printf(" gz = %f mG\n\r", mz);
motoseki 0:e6b1cd3646df 167
motoseki 0:e6b1cd3646df 168 tempCount = mpu9250.readTempData(); // Read the adc values
motoseki 0:e6b1cd3646df 169 temperature = ((float) tempCount) / 333.87f + 21.0f; // Temperature in degrees Centigrade
motoseki 0:e6b1cd3646df 170 //pc.printf(" temperature = %f C\n\r", temperature);
motoseki 0:e6b1cd3646df 171
motoseki 0:e6b1cd3646df 172 //pc.printf("q0 = %f\n\r", q[0]);
motoseki 0:e6b1cd3646df 173 //pc.printf("q1 = %f\n\r", q[1]);
motoseki 0:e6b1cd3646df 174 //pc.printf("q2 = %f\n\r", q[2]);
motoseki 0:e6b1cd3646df 175 //pc.printf("q3 = %f\n\r", q[3]);
motoseki 0:e6b1cd3646df 176
motoseki 0:e6b1cd3646df 177
motoseki 0:e6b1cd3646df 178 // Define output variables from updated quaternion---these are Tait-Bryan angles, commonly used in aircraft orientation.
motoseki 0:e6b1cd3646df 179 // In this coordinate system, the positive z-axis is down toward Earth.
motoseki 0:e6b1cd3646df 180 // Yaw is the angle between Sensor x-axis and Earth magnetic North (or true North if corrected for local declination, looking down on the sensor positive yaw is counterclockwise.
motoseki 0:e6b1cd3646df 181 // Pitch is angle between sensor x-axis and Earth ground plane, toward the Earth is positive, up toward the sky is negative.
motoseki 0:e6b1cd3646df 182 // Roll is angle between sensor y-axis and Earth ground plane, y-axis up is positive roll.
motoseki 0:e6b1cd3646df 183 // These arise from the definition of the homogeneous rotation matrix constructed from quaternions.
motoseki 0:e6b1cd3646df 184 // Tait-Bryan angles as well as Euler angles are non-commutative; that is, the get the correct orientation the rotations must be
motoseki 0:e6b1cd3646df 185 // applied in the correct order which for this configuration is yaw, pitch, and then roll.
motoseki 0:e6b1cd3646df 186 // For more see http://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles which has additional links.
motoseki 0:e6b1cd3646df 187 yaw = atan2(2.0f * (q[1] * q[2] + q[0] * q[3]), q[0] * q[0] + q[1] * q[1] - q[2] * q[2] - q[3] * q[3]);
motoseki 0:e6b1cd3646df 188 pitch = -asin(2.0f * (q[1] * q[3] - q[0] * q[2]));
motoseki 0:e6b1cd3646df 189 roll = atan2(2.0f * (q[0] * q[1] + q[2] * q[3]), q[0] * q[0] - q[1] * q[1] - q[2] * q[2] + q[3] * q[3]);
motoseki 0:e6b1cd3646df 190 pitch *= 180.0f / PI;
motoseki 0:e6b1cd3646df 191 yaw *= 180.0f / PI;
motoseki 0:e6b1cd3646df 192 yaw -= 13.8f; // Declination at Danville, California is 13 degrees 48 minutes and 47 seconds on 2014-04-04
motoseki 0:e6b1cd3646df 193 roll *= 180.0f / PI;
motoseki 0:e6b1cd3646df 194
motoseki 2:c1c7afb86416 195 //pc.printf("Yaw, Pitch, Roll: %f %f %f \n\r", yaw, pitch, roll);
motoseki 0:e6b1cd3646df 196 //pc.printf("average rate = %f\n\r", (float) sumCount/sum);
motoseki 2:c1c7afb86416 197
motoseki 2:c1c7afb86416 198 bmpTEM=bmp.getTemperature();
motoseki 2:c1c7afb86416 199 bmpPRE=bmp.getPressure();
motoseki 2:c1c7afb86416 200 pc.printf("PRE : %f\n",bmpPRE - PRES_first);
motoseki 0:e6b1cd3646df 201
motoseki 0:e6b1cd3646df 202 myled= !myled;
motoseki 0:e6b1cd3646df 203 count = t.read_ms();
motoseki 0:e6b1cd3646df 204 sum = 0;
motoseki 0:e6b1cd3646df 205 sumCount = 0;
motoseki 0:e6b1cd3646df 206 }
motoseki 0:e6b1cd3646df 207 }
motoseki 0:e6b1cd3646df 208
motoseki 0:e6b1cd3646df 209 while(1){
motoseki 0:e6b1cd3646df 210 pc.printf(".");
motoseki 0:e6b1cd3646df 211 wait(1);
motoseki 0:e6b1cd3646df 212 }
motoseki 0:e6b1cd3646df 213 }
motoseki 0:e6b1cd3646df 214