A quick and dirty demo of the Xadow M0 acceleromoeter values displayed on the Xadow OLED 0.96" (using the SSD1308 128x64 OLED Driver with I2C interface library).

Dependencies:   mbed SSD1308_128x64_I2C_opt XadowGPS BMP180 ADXL345_I2C MPU9250 USBDevice

Committer:
ruevs
Date:
Sat Feb 23 18:07:47 2019 +0000
Revision:
8:4e8991196bb8
Parent:
7:4931dbfbc042
Child:
9:310663c014d8
Fix the call to MahonyQuaternionUpdate to reflect the proper orientation of the accelerometer and gyroscope axis in the MPU9250.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ruevs 2:7abdbccdf0c8 1 #define __STDC_LIMIT_MACROS 1
ruevs 2:7abdbccdf0c8 2 #include <stdint.h>
seeed 0:b017c907d53d 3
ruevs 2:7abdbccdf0c8 4 #include "ADXL345_I2C.h"
ruevs 2:7abdbccdf0c8 5 #include "SSD1308.h"
ruevs 5:50051611b5bd 6 #include "MPU9250.h"
ruevs 5:50051611b5bd 7 #include "BMP180.h"
ruevs 2:7abdbccdf0c8 8
ruevs 5:50051611b5bd 9 #define DEBUG
seeed 0:b017c907d53d 10
seeed 0:b017c907d53d 11 #ifdef DEBUG
seeed 0:b017c907d53d 12 #include "USBSerial.h" // To use USB virtual serial, a driver is needed, check http://mbed.org/handbook/USBSerial
seeed 0:b017c907d53d 13 #define LOG(args...) pc.printf(args)
seeed 0:b017c907d53d 14 USBSerial pc;
seeed 0:b017c907d53d 15 #else
seeed 0:b017c907d53d 16 #define LOG(args...)
seeed 0:b017c907d53d 17 #endif
seeed 0:b017c907d53d 18
ruevs 2:7abdbccdf0c8 19 #define MAX_ACC_AXIS 3
seeed 0:b017c907d53d 20 ADXL345_I2C accelerometer(P0_5, P0_4);
seeed 0:b017c907d53d 21
ruevs 2:7abdbccdf0c8 22 // Xhadow - OLED 128x64 is connected with I2C
ruevs 2:7abdbccdf0c8 23 I2C i2c(P0_5, P0_4); // SDA, SCL
ruevs 2:7abdbccdf0c8 24 SSD1308 oled = SSD1308(i2c, SSD1308_SA0);
ruevs 5:50051611b5bd 25 SSD1308 oled2 = SSD1308(i2c, SSD1308_SA1);
ruevs 5:50051611b5bd 26
ruevs 5:50051611b5bd 27 // MPU9250 9DOF IMU - accelerometer, gyroscope, magnetometer access class
ruevs 5:50051611b5bd 28 MPU9250 mpu9250(i2c);
ruevs 5:50051611b5bd 29
ruevs 5:50051611b5bd 30 // BMP180 pressure and temperature sensor access class
ruevs 5:50051611b5bd 31 BMP180 bmp180(&i2c);
ruevs 2:7abdbccdf0c8 32
ruevs 2:7abdbccdf0c8 33 AnalogIn AD00(P0_11);
ruevs 2:7abdbccdf0c8 34 AnalogIn AD01(P0_12);
ruevs 2:7abdbccdf0c8 35 AnalogIn ChargerStatus(P0_13); // ADC input from VCC through a 200K/200K divider with extara 100K pull down on !DONE and 49.9K on !CHRG
ruevs 2:7abdbccdf0c8 36
ruevs 2:7abdbccdf0c8 37 DigitalOut blue_led(P0_20, 0);
ruevs 2:7abdbccdf0c8 38 DigitalOut white_led(P0_23, 1);
ruevs 2:7abdbccdf0c8 39 DigitalOut Bus3V3En(P0_14, 1); // Pin that controls the BUS-3V3 (3.3V) regulator output to the Xadow Bus
ruevs 2:7abdbccdf0c8 40
ruevs 2:7abdbccdf0c8 41 InterruptIn test_int(P0_7);
ruevs 2:7abdbccdf0c8 42
ruevs 2:7abdbccdf0c8 43 void test_pin_int(void)
ruevs 2:7abdbccdf0c8 44 {
ruevs 2:7abdbccdf0c8 45 white_led = !white_led;
ruevs 2:7abdbccdf0c8 46 Bus3V3En = !Bus3V3En;
ruevs 2:7abdbccdf0c8 47 }
ruevs 2:7abdbccdf0c8 48
ruevs 5:50051611b5bd 49 void MPU9250Test()
ruevs 5:50051611b5bd 50 {
ruevs 5:50051611b5bd 51 Timer t;
ruevs 5:50051611b5bd 52 float sum = 0;
ruevs 5:50051611b5bd 53 uint32_t sumCount = 0;
ruevs 5:50051611b5bd 54
ruevs 5:50051611b5bd 55 char buffer[14];
ruevs 5:50051611b5bd 56
ruevs 5:50051611b5bd 57 uint8_t whoami;
ruevs 5:50051611b5bd 58
ruevs 5:50051611b5bd 59 //___ Set up I2C: use fast (400 kHz) I2C ___
ruevs 5:50051611b5bd 60 i2c.frequency(400000);
ruevs 5:50051611b5bd 61
ruevs 5:50051611b5bd 62 wait(10); // to allow terminal to cooect on PC
ruevs 5:50051611b5bd 63
ruevs 5:50051611b5bd 64 while(1) {
ruevs 5:50051611b5bd 65 if (bmp180.init() != 0) {
ruevs 5:50051611b5bd 66 LOG("Error communicating with BMP180r\n");
ruevs 5:50051611b5bd 67 } else {
ruevs 7:4931dbfbc042 68 LOG("Initialized BMP180\r\n");
ruevs 5:50051611b5bd 69 break;
ruevs 5:50051611b5bd 70 }
ruevs 5:50051611b5bd 71 wait(1);
ruevs 5:50051611b5bd 72 }
ruevs 5:50051611b5bd 73
ruevs 5:50051611b5bd 74 LOG("CPU SystemCoreClock is %d Hz\r\n", SystemCoreClock);
ruevs 5:50051611b5bd 75
ruevs 5:50051611b5bd 76 t.start(); // Timer ON
ruevs 5:50051611b5bd 77
ruevs 5:50051611b5bd 78 // Read the WHO_AM_I register, this is a good test of communication
ruevs 5:50051611b5bd 79 whoami = mpu9250.readByte(MPU9250_ADDRESS, WHO_AM_I_MPU9250);
ruevs 5:50051611b5bd 80
ruevs 5:50051611b5bd 81 LOG("I AM 0x%x\r\n", whoami); LOG("I SHOULD BE 0x71\r\n");
ruevs 5:50051611b5bd 82 if (I2Cstate != 0) // error on I2C
ruevs 5:50051611b5bd 83 LOG("I2C failure while reading WHO_AM_I register");
ruevs 5:50051611b5bd 84
ruevs 5:50051611b5bd 85 if (whoami == 0x71) // WHO_AM_I should always be 0x71
ruevs 5:50051611b5bd 86 {
ruevs 5:50051611b5bd 87 LOG("MPU9250 WHO_AM_I is 0x%x\r\n", whoami);
ruevs 5:50051611b5bd 88 LOG("MPU9250 is online...\r\n");
ruevs 5:50051611b5bd 89 sprintf(buffer, "0x%x", whoami);
ruevs 5:50051611b5bd 90 wait(1);
ruevs 5:50051611b5bd 91
ruevs 5:50051611b5bd 92 mpu9250.resetMPU9250(); // Reset registers to default in preparation for device calibration
ruevs 5:50051611b5bd 93
ruevs 5:50051611b5bd 94 mpu9250.MPU9250SelfTest(SelfTest); // Start by performing self test and reporting values (accelerometer and gyroscope self test)
ruevs 5:50051611b5bd 95 LOG("x-axis self test: acceleration trim within : %f % of factory value\r\n", SelfTest[0]);
ruevs 5:50051611b5bd 96 LOG("y-axis self test: acceleration trim within : %f % of factory value\r\n", SelfTest[1]);
ruevs 5:50051611b5bd 97 LOG("z-axis self test: acceleration trim within : %f % of factory value\r\n", SelfTest[2]);
ruevs 5:50051611b5bd 98 LOG("x-axis self test: gyration trim within : %f % of factory value\r\n", SelfTest[3]);
ruevs 5:50051611b5bd 99 LOG("y-axis self test: gyration trim within : %f % of factory value\r\n", SelfTest[4]);
ruevs 5:50051611b5bd 100 LOG("z-axis self test: gyration trim within : %f % of factory value\r\n", SelfTest[5]);
ruevs 5:50051611b5bd 101
ruevs 5:50051611b5bd 102 mpu9250.calibrateMPU9250(gyroBias, accelBias); // Calibrate gyro and accelerometer, load biases in bias registers
ruevs 5:50051611b5bd 103 LOG("x gyro bias = %f\r\n", gyroBias[0]);
ruevs 5:50051611b5bd 104 LOG("y gyro bias = %f\r\n", gyroBias[1]);
ruevs 5:50051611b5bd 105 LOG("z gyro bias = %f\r\n", gyroBias[2]);
ruevs 5:50051611b5bd 106 LOG("x accel bias = %f\r\n", accelBias[0]);
ruevs 5:50051611b5bd 107 LOG("y accel bias = %f\r\n", accelBias[1]);
ruevs 5:50051611b5bd 108 LOG("z accel bias = %f\r\n", accelBias[2]);
ruevs 5:50051611b5bd 109 wait(2);
ruevs 5:50051611b5bd 110
ruevs 5:50051611b5bd 111 // Initialize device for active mode read of acclerometer, gyroscope, and temperature
ruevs 5:50051611b5bd 112 mpu9250.initMPU9250();
ruevs 5:50051611b5bd 113 LOG("MPU9250 initialized for active data mode....\r\n");
ruevs 5:50051611b5bd 114
ruevs 5:50051611b5bd 115 // Initialize device for active mode read of magnetometer, 16 bit resolution, 100Hz.
ruevs 5:50051611b5bd 116 mpu9250.initAK8963(magCalibration);
ruevs 5:50051611b5bd 117 LOG("AK8963 initialized for active data mode....\r\n");
ruevs 5:50051611b5bd 118 LOG("Accelerometer full-scale range = %f g\r\n", 2.0f*(float)(1<<Ascale));
ruevs 5:50051611b5bd 119 LOG("Gyroscope full-scale range = %f deg/s\r\n", 250.0f*(float)(1<<Gscale));
ruevs 5:50051611b5bd 120 if(Mscale == 0) LOG("Magnetometer resolution = 14 bits\r\n");
ruevs 5:50051611b5bd 121 if(Mscale == 1) LOG("Magnetometer resolution = 16 bits\r\n");
ruevs 5:50051611b5bd 122 if(Mmode == 2) LOG("Magnetometer ODR = 8 Hz\r\n");
ruevs 5:50051611b5bd 123 if(Mmode == 6) LOG("Magnetometer ODR = 100 Hz\r\n");
ruevs 5:50051611b5bd 124 wait(1);
ruevs 5:50051611b5bd 125 }
ruevs 5:50051611b5bd 126
ruevs 5:50051611b5bd 127 else // Connection failure
ruevs 5:50051611b5bd 128 {
ruevs 5:50051611b5bd 129 LOG("Could not connect to MPU9250: \r\n");
ruevs 5:50051611b5bd 130 LOG("%#x \n", whoami);
ruevs 5:50051611b5bd 131 sprintf(buffer, "WHO_AM_I 0x%x", whoami);
ruevs 5:50051611b5bd 132 while(1) ; // Loop forever if communication doesn't happen
ruevs 5:50051611b5bd 133 }
ruevs 5:50051611b5bd 134
ruevs 5:50051611b5bd 135 mpu9250.getAres(); // Get accelerometer sensitivity
ruevs 5:50051611b5bd 136 mpu9250.getGres(); // Get gyro sensitivity
ruevs 5:50051611b5bd 137 mpu9250.getMres(); // Get magnetometer sensitivity
ruevs 5:50051611b5bd 138 LOG("Accelerometer sensitivity is %f LSB/g \r\n", 1.0f/aRes);
ruevs 5:50051611b5bd 139 LOG("Gyroscope sensitivity is %f LSB/deg/s \r\n", 1.0f/gRes);
ruevs 5:50051611b5bd 140 LOG("Magnetometer sensitivity is %f LSB/G \r\n", 1.0f/mRes);
ruevs 5:50051611b5bd 141 magbias[0] = +470.; // User environmental x-axis correction in milliGauss, should be automatically calculated
ruevs 5:50051611b5bd 142 magbias[1] = +120.; // User environmental x-axis correction in milliGauss
ruevs 5:50051611b5bd 143 magbias[2] = +125.; // User environmental x-axis correction in milliGauss
ruevs 5:50051611b5bd 144
ruevs 5:50051611b5bd 145 while(1) {
ruevs 5:50051611b5bd 146
ruevs 5:50051611b5bd 147 // If intPin goes high, all data registers have new data
ruevs 5:50051611b5bd 148 if(mpu9250.readByte(MPU9250_ADDRESS, INT_STATUS) & 0x01) { // On interrupt, check if data ready interrupt
ruevs 5:50051611b5bd 149
ruevs 5:50051611b5bd 150 mpu9250.readAccelData(accelCount); // Read the x/y/z adc values
ruevs 5:50051611b5bd 151 // Now we'll calculate the accleration value into actual g's
ruevs 5:50051611b5bd 152 if (I2Cstate != 0) //error on I2C
ruevs 5:50051611b5bd 153 LOG("I2C error ocurred while reading accelerometer data. I2Cstate = %d \r\n", I2Cstate);
ruevs 5:50051611b5bd 154 else{ // I2C read or write ok
ruevs 5:50051611b5bd 155 I2Cstate = 1;
ruevs 5:50051611b5bd 156 ax = (float)accelCount[0]*aRes - accelBias[0]; // get actual g value, this depends on scale being set
ruevs 5:50051611b5bd 157 ay = (float)accelCount[1]*aRes - accelBias[1];
ruevs 5:50051611b5bd 158 az = (float)accelCount[2]*aRes - accelBias[2];
ruevs 5:50051611b5bd 159 }
ruevs 5:50051611b5bd 160
ruevs 5:50051611b5bd 161 mpu9250.readGyroData(gyroCount); // Read the x/y/z adc values
ruevs 5:50051611b5bd 162 // Calculate the gyro value into actual degrees per second
ruevs 5:50051611b5bd 163 if (I2Cstate != 0) //error on I2C
ruevs 5:50051611b5bd 164 LOG("I2C error ocurred while reading gyrometer data. I2Cstate = %d \r\n", I2Cstate);
ruevs 5:50051611b5bd 165 else{ // I2C read or write ok
ruevs 5:50051611b5bd 166 I2Cstate = 1;
ruevs 5:50051611b5bd 167 gx = (float)gyroCount[0]*gRes - gyroBias[0]; // get actual gyro value, this depends on scale being set
ruevs 5:50051611b5bd 168 gy = (float)gyroCount[1]*gRes - gyroBias[1];
ruevs 5:50051611b5bd 169 gz = (float)gyroCount[2]*gRes - gyroBias[2];
ruevs 5:50051611b5bd 170 }
ruevs 5:50051611b5bd 171
ruevs 5:50051611b5bd 172 mpu9250.readMagData(magCount); // Read the x/y/z adc values
ruevs 5:50051611b5bd 173 // Calculate the magnetometer values in milliGauss
ruevs 5:50051611b5bd 174 // Include factory calibration per data sheet and user environmental corrections
ruevs 5:50051611b5bd 175 if (I2Cstate != 0) //error on I2C
ruevs 5:50051611b5bd 176 LOG("I2C error ocurred while reading magnetometer data. I2Cstate = %d \r\n", I2Cstate);
ruevs 5:50051611b5bd 177 else{ // I2C read or write ok
ruevs 5:50051611b5bd 178 I2Cstate = 1;
ruevs 5:50051611b5bd 179 mx = (float)magCount[0]*mRes*magCalibration[0] - magbias[0]; // get actual magnetometer value, this depends on scale being set
ruevs 5:50051611b5bd 180 my = (float)magCount[1]*mRes*magCalibration[1] - magbias[1];
ruevs 5:50051611b5bd 181 mz = (float)magCount[2]*mRes*magCalibration[2] - magbias[2];
ruevs 5:50051611b5bd 182 }
ruevs 5:50051611b5bd 183
ruevs 5:50051611b5bd 184 mpu9250.getCompassOrientation(orientation);
ruevs 5:50051611b5bd 185 }
ruevs 5:50051611b5bd 186
ruevs 5:50051611b5bd 187 Now = t.read_us();
ruevs 5:50051611b5bd 188 deltat = (float)((Now - lastUpdate)/1000000.0f) ; // set integration time by time elapsed since last filter update
ruevs 5:50051611b5bd 189 lastUpdate = Now;
ruevs 5:50051611b5bd 190 sum += deltat;
ruevs 5:50051611b5bd 191 sumCount++;
ruevs 5:50051611b5bd 192
ruevs 8:4e8991196bb8 193 // Sensors x (y)-axis of the accelerometer/gyro is aligned with the y (x)-axis of the magnetometer;
ruevs 8:4e8991196bb8 194 // the magnetometer z-axis (+ down) is misaligned with z-axis (+ up) of accelerometer and gyro!
ruevs 8:4e8991196bb8 195 // We have to make some allowance for this orientation mismatch in feeding the output to the quaternion filter.
ruevs 8:4e8991196bb8 196 // We will assume that +y accel/gyro is North, then x accel/gyro is East. So if we want te quaternions properly aligned
ruevs 8:4e8991196bb8 197 // we need to feed into the madgwick function Ay, Ax, -Az, Gy, Gx, -Gz, Mx, My, and Mz. But because gravity is by convention
ruevs 8:4e8991196bb8 198 // positive down, we need to invert the accel data, so we pass -Ay, -Ax, Az, Gy, Gx, -Gz, Mx, My, and Mz into the Madgwick
ruevs 8:4e8991196bb8 199 // function to get North along the accel +y-axis, East along the accel +x-axis, and Down along the accel -z-axis.
ruevs 8:4e8991196bb8 200 // This orientation choice can be modified to allow any convenient (non-NED) orientation convention.
ruevs 8:4e8991196bb8 201 // This is ok by aircraft orientation standards!
ruevs 5:50051611b5bd 202 // Pass gyro rate as rad/s
ruevs 8:4e8991196bb8 203 // mpu9250.MadgwickQuaternionUpdate(-ay, -ax, az, gy*PI/180.0f, gx*PI/180.0f, -gz*PI/180.0f, mx, my, mz);
ruevs 8:4e8991196bb8 204 mpu9250.MahonyQuaternionUpdate(-ay, -ax, az, gy*PI/180.0f, gx*PI/180.0f, -gz*PI/180.0f, mx, my, mz);
ruevs 5:50051611b5bd 205
ruevs 5:50051611b5bd 206
ruevs 5:50051611b5bd 207 // Serial print and/or display at 1.5 s rate independent of data rates
ruevs 5:50051611b5bd 208 delt_t = t.read_ms() - count;
ruevs 5:50051611b5bd 209 if (delt_t > 1500) { // update LCD once per half-second independent of read rate
ruevs 7:4931dbfbc042 210 LOG("\033[2J"); // ANSI clear screen ESC[2J
ruevs 5:50051611b5bd 211 LOG("ax = %f", 1000*ax);
ruevs 5:50051611b5bd 212 LOG(" ay = %f", 1000*ay);
ruevs 5:50051611b5bd 213 LOG(" az = %f mg\r\n", 1000*az);
ruevs 5:50051611b5bd 214 LOG("gx = %f", gx);
ruevs 5:50051611b5bd 215 LOG(" gy = %f", gy);
ruevs 5:50051611b5bd 216 LOG(" gz = %f deg/s\r\n", gz);
ruevs 5:50051611b5bd 217 LOG("mx = %f", mx);
ruevs 5:50051611b5bd 218 LOG(" my = %f", my);
ruevs 5:50051611b5bd 219 LOG(" mz = %f mG\r\n", mz);
ruevs 5:50051611b5bd 220
ruevs 5:50051611b5bd 221
ruevs 5:50051611b5bd 222 tempCount = mpu9250.readTempData(); // Read the adc values
ruevs 5:50051611b5bd 223 if (I2Cstate != 0) //error on I2C
ruevs 5:50051611b5bd 224 LOG("I2C error ocurred while reading sensor temp. I2Cstate = %d \r\n", I2Cstate);
ruevs 5:50051611b5bd 225 else{ // I2C read or write ok
ruevs 5:50051611b5bd 226 I2Cstate = 1;
ruevs 5:50051611b5bd 227 temperature = ((float) tempCount) / 333.87f + 21.0f; // Temperature in degrees Centigrade
ruevs 5:50051611b5bd 228 LOG(" temperature = %f C\r\n", temperature);
ruevs 5:50051611b5bd 229 }
ruevs 5:50051611b5bd 230 LOG("q0 = %f\r\n", q[0]);
ruevs 5:50051611b5bd 231 LOG("q1 = %f\r\n", q[1]);
ruevs 5:50051611b5bd 232 LOG("q2 = %f\r\n", q[2]);
ruevs 5:50051611b5bd 233 LOG("q3 = %f\r\n", q[3]);
ruevs 5:50051611b5bd 234
ruevs 5:50051611b5bd 235 LOG("Compass orientation: %f\r\n", orientation[0]);
ruevs 5:50051611b5bd 236
ruevs 5:50051611b5bd 237
ruevs 5:50051611b5bd 238
ruevs 5:50051611b5bd 239
ruevs 5:50051611b5bd 240 // Define output variables from updated quaternion---these are Tait-Bryan angles, commonly used in aircraft orientation.
ruevs 5:50051611b5bd 241 // In this coordinate system, the positive z-axis is down toward Earth.
ruevs 5:50051611b5bd 242 // 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.
ruevs 5:50051611b5bd 243 // Pitch is angle between sensor x-axis and Earth ground plane, toward the Earth is positive, up toward the sky is negative.
ruevs 5:50051611b5bd 244 // Roll is angle between sensor y-axis and Earth ground plane, y-axis up is positive roll.
ruevs 5:50051611b5bd 245 // These arise from the definition of the homogeneous rotation matrix constructed from quaternions.
ruevs 5:50051611b5bd 246 // Tait-Bryan angles as well as Euler angles are non-commutative; that is, the get the correct orientation the rotations must be
ruevs 5:50051611b5bd 247 // applied in the correct order which for this configuration is yaw, pitch, and then roll.
ruevs 5:50051611b5bd 248 // For more see http://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles which has additional links.
ruevs 5:50051611b5bd 249
ruevs 5:50051611b5bd 250 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]);
ruevs 5:50051611b5bd 251 pitch = -asin(2.0f * (q[1] * q[3] - q[0] * q[2]));
ruevs 5:50051611b5bd 252 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]);
ruevs 5:50051611b5bd 253 pitch *= 180.0f / PI;
ruevs 5:50051611b5bd 254 yaw *= 180.0f / PI;
ruevs 5:50051611b5bd 255 yaw -= 13.8f; // Declination at Danville, California is 13 degrees 48 minutes and 47 seconds on 2014-04-04
ruevs 5:50051611b5bd 256 roll *= 180.0f / PI;
ruevs 5:50051611b5bd 257
ruevs 5:50051611b5bd 258
ruevs 5:50051611b5bd 259 LOG("Yaw, Pitch, Roll: %f %f %f\r\n", yaw, pitch, roll);
ruevs 5:50051611b5bd 260 LOG("average rate = %f\r\n", (float) sumCount/sum);
ruevs 5:50051611b5bd 261
ruevs 5:50051611b5bd 262
ruevs 5:50051611b5bd 263
ruevs 5:50051611b5bd 264 myled= !myled;
ruevs 5:50051611b5bd 265 count = t.read_ms();
ruevs 5:50051611b5bd 266
ruevs 5:50051611b5bd 267 if(count > 1<<21) {
ruevs 5:50051611b5bd 268 t.start(); // start the timer over again if ~30 minutes has passed
ruevs 5:50051611b5bd 269 count = 0;
ruevs 5:50051611b5bd 270 deltat= 0;
ruevs 5:50051611b5bd 271 lastUpdate = t.read_us();
ruevs 5:50051611b5bd 272 }
ruevs 5:50051611b5bd 273 sum = 0;
ruevs 5:50051611b5bd 274 sumCount = 0;
ruevs 5:50051611b5bd 275
ruevs 5:50051611b5bd 276 //BMP180
ruevs 5:50051611b5bd 277 bmp180.startTemperature();
ruevs 5:50051611b5bd 278 wait_ms(5); // Wait for conversion to complete
ruevs 5:50051611b5bd 279 float temp;
ruevs 5:50051611b5bd 280 if(bmp180.getTemperature(&temp) != 0) {
ruevs 5:50051611b5bd 281 LOG("Error getting temperature\n");
ruevs 5:50051611b5bd 282 continue;
ruevs 5:50051611b5bd 283 }
ruevs 5:50051611b5bd 284
ruevs 5:50051611b5bd 285 bmp180.startPressure(BMP180::ULTRA_LOW_POWER);
ruevs 5:50051611b5bd 286 wait_ms(10); // Wait for conversion to complete
ruevs 5:50051611b5bd 287 int pressure;
ruevs 5:50051611b5bd 288 if(bmp180.getPressure(&pressure) != 0) {
ruevs 5:50051611b5bd 289 LOG("Error getting pressure\n");
ruevs 5:50051611b5bd 290 continue;
ruevs 5:50051611b5bd 291 }
ruevs 5:50051611b5bd 292
ruevs 5:50051611b5bd 293 LOG("Pressure = %d Pa Temperature = %f C\r\n", pressure, temp);
ruevs 5:50051611b5bd 294
ruevs 5:50051611b5bd 295 }
ruevs 5:50051611b5bd 296 }
ruevs 5:50051611b5bd 297 }
ruevs 5:50051611b5bd 298
seeed 0:b017c907d53d 299 int main()
seeed 0:b017c907d53d 300 {
ruevs 2:7abdbccdf0c8 301 int readings[MAX_ACC_AXIS] = {0, 0, 0};
ruevs 2:7abdbccdf0c8 302 int MAXreadings[MAX_ACC_AXIS] = {INT16_MIN, INT16_MIN, INT16_MIN};
ruevs 2:7abdbccdf0c8 303 int MINreadings[MAX_ACC_AXIS] = {INT16_MAX, INT16_MAX, INT16_MAX};
ruevs 2:7abdbccdf0c8 304
ruevs 2:7abdbccdf0c8 305 char display_buf[17];
ruevs 2:7abdbccdf0c8 306
ruevs 2:7abdbccdf0c8 307 test_int.rise(test_pin_int);
seeed 0:b017c907d53d 308
ruevs 5:50051611b5bd 309 MPU9250Test();
ruevs 5:50051611b5bd 310
seeed 0:b017c907d53d 311 LOG("Starting ADXL345 test...\n");
seeed 0:b017c907d53d 312 LOG("Device ID is: 0x%02x\n", accelerometer.getDeviceID());
ruevs 2:7abdbccdf0c8 313
ruevs 5:50051611b5bd 314 /* // Simple OLED speed test
ruevs 5:50051611b5bd 315 oled.fillDisplay(0xAA);
ruevs 5:50051611b5bd 316 oled.writeBigChar(1,0,'6');
ruevs 5:50051611b5bd 317
ruevs 5:50051611b5bd 318 uint8_t cnt=0;
ruevs 5:50051611b5bd 319 int cycl=0;
ruevs 5:50051611b5bd 320 while(1){
ruevs 5:50051611b5bd 321 snprintf(display_buf, sizeof(display_buf), "%5i", cnt++);
ruevs 5:50051611b5bd 322 oled.writeString(0, 0, display_buf);
ruevs 5:50051611b5bd 323 if (0==cnt) {
ruevs 5:50051611b5bd 324 ++cycl;
ruevs 5:50051611b5bd 325 snprintf(display_buf, sizeof(display_buf), "%5i", cycl);
ruevs 5:50051611b5bd 326 oled.writeString(1, 0, display_buf);
ruevs 5:50051611b5bd 327 }
ruevs 5:50051611b5bd 328 }
ruevs 5:50051611b5bd 329 */
ruevs 5:50051611b5bd 330 oled2.writeString(0, 0, "OLED 2:");
ruevs 5:50051611b5bd 331 oled2.writeString(1, 0, "GEEKCREIT");
ruevs 5:50051611b5bd 332 oled2.writeString(2, 0, "Banggood 0x7A");
ruevs 5:50051611b5bd 333
ruevs 2:7abdbccdf0c8 334 oled.writeString(0, 0, "Accelerometer:");
ruevs 2:7abdbccdf0c8 335 oled.writeString(1, 0, " Curr Min Max");
seeed 0:b017c907d53d 336
seeed 0:b017c907d53d 337 //Go into standby mode to configure the device.
seeed 0:b017c907d53d 338 accelerometer.setPowerControl(0x00);
seeed 0:b017c907d53d 339
seeed 0:b017c907d53d 340 //Full resolution, +/-16g, 4mg/LSB.
seeed 0:b017c907d53d 341 accelerometer.setDataFormatControl(0x0B);
seeed 0:b017c907d53d 342
seeed 0:b017c907d53d 343 //3.2kHz data rate.
seeed 0:b017c907d53d 344 accelerometer.setDataRate(ADXL345_3200HZ);
seeed 0:b017c907d53d 345
seeed 0:b017c907d53d 346 //Measurement mode.
seeed 0:b017c907d53d 347 accelerometer.setPowerControl(0x08);
seeed 0:b017c907d53d 348
seeed 0:b017c907d53d 349 while (1) {
seeed 0:b017c907d53d 350 accelerometer.getOutput(readings);
ruevs 2:7abdbccdf0c8 351
ruevs 2:7abdbccdf0c8 352 for (int i=0; i<MAX_ACC_AXIS; ++i) {
ruevs 2:7abdbccdf0c8 353 if ((int16_t)readings[i] > (int16_t)MAXreadings[i]) {
ruevs 2:7abdbccdf0c8 354 MAXreadings[i] = readings[i];
ruevs 2:7abdbccdf0c8 355 }
ruevs 2:7abdbccdf0c8 356 if ((int16_t)readings[i] < (int16_t)MINreadings[i]) {
ruevs 2:7abdbccdf0c8 357 MINreadings[i] = readings[i];
ruevs 2:7abdbccdf0c8 358 }
ruevs 2:7abdbccdf0c8 359
ruevs 2:7abdbccdf0c8 360 snprintf(display_buf, sizeof(display_buf), "%c%5i%5i%5i",
ruevs 2:7abdbccdf0c8 361 'X'+i, (int16_t)readings[i], (int16_t)MINreadings[i], (int16_t)MAXreadings[i] );
ruevs 2:7abdbccdf0c8 362 oled.writeString(2+i, 0, display_buf);
ruevs 2:7abdbccdf0c8 363 LOG("%c:%i|%i|%i\r\n", 'X'+i, (int16_t)readings[i], (int16_t)MINreadings[i], (int16_t)MAXreadings[i] );
ruevs 2:7abdbccdf0c8 364 }
ruevs 2:7abdbccdf0c8 365
ruevs 2:7abdbccdf0c8 366 /* snprintf(display_buf, sizeof(display_buf), "Ch: %u", ChargerStatus.read_u16());
ruevs 2:7abdbccdf0c8 367 oled.writeString(2+MAX_ACC_AXIS, 0, display_buf);
ruevs 2:7abdbccdf0c8 368
ruevs 2:7abdbccdf0c8 369 snprintf(display_buf, sizeof(display_buf), "Ch: %f", 3.3*(float)ChargerStatus.read_u16()/UINT16_MAX);
ruevs 2:7abdbccdf0c8 370 oled.writeString(2+MAX_ACC_AXIS+1, 0, display_buf);
ruevs 2:7abdbccdf0c8 371 */
ruevs 2:7abdbccdf0c8 372 snprintf(display_buf, sizeof(display_buf), "Bat:%.2fV", 3.3*ChargerStatus);
ruevs 2:7abdbccdf0c8 373 oled.writeString(2+MAX_ACC_AXIS+2, 0, display_buf);
ruevs 2:7abdbccdf0c8 374
ruevs 2:7abdbccdf0c8 375 LOG("Ch: %f\r\n", ChargerStatus.read());
ruevs 2:7abdbccdf0c8 376 LOG("Chu: %u\r\n", ChargerStatus.read_u16());
ruevs 2:7abdbccdf0c8 377 LOG("A0: %f\r\n", (float)AD00.read());
ruevs 2:7abdbccdf0c8 378 LOG("A1: %f\r\n", AD01.read());
ruevs 2:7abdbccdf0c8 379
ruevs 2:7abdbccdf0c8 380 blue_led = !blue_led;
ruevs 2:7abdbccdf0c8 381 // white_led = !white_led; // toggled by pin P0_7 interrupt
ruevs 2:7abdbccdf0c8 382
ruevs 2:7abdbccdf0c8 383 // deepsleep(); // Deep sleep until external interrupt // The wakeup pin on Xadow is on the sme buton at RESET - no good.
seeed 0:b017c907d53d 384
seeed 0:b017c907d53d 385 wait(1);
seeed 0:b017c907d53d 386 }
seeed 0:b017c907d53d 387
seeed 0:b017c907d53d 388 }