|
| 1 | +#include "MPU6886.h" |
| 2 | +#include <math.h> |
| 3 | +#include <Arduino.h> |
| 4 | +#include "../M5Stack.h" |
| 5 | +#include "MahonyAHRS.h" |
| 6 | + |
| 7 | +MPU6886::MPU6886(){ |
| 8 | + |
| 9 | +} |
| 10 | + |
| 11 | +void MPU6886::I2C_Read_NBytes(uint8_t driver_Addr, uint8_t start_Addr, uint8_t number_Bytes, uint8_t *read_Buffer){ |
| 12 | + M5.I2C.readBytes(driver_Addr, start_Addr, number_Bytes, read_Buffer); |
| 13 | +} |
| 14 | + |
| 15 | +void MPU6886::I2C_Write_NBytes(uint8_t driver_Addr, uint8_t start_Addr, uint8_t number_Bytes, uint8_t *write_Buffer) { |
| 16 | + M5.I2C.writeBytes(driver_Addr, start_Addr, write_Buffer, number_Bytes); |
| 17 | +} |
| 18 | + |
| 19 | +int MPU6886::Init(void) { |
| 20 | + unsigned char tempdata[1]; |
| 21 | + unsigned char regdata; |
| 22 | + |
| 23 | + Gyscale = GFS_2000DPS; |
| 24 | + Acscale = AFS_8G; |
| 25 | + |
| 26 | + Wire1.begin(21,22); |
| 27 | + |
| 28 | + I2C_Read_NBytes(MPU6886_ADDRESS, MPU6886_WHOAMI, 1, tempdata); |
| 29 | + imuId = tempdata[0]; |
| 30 | + delay(1); |
| 31 | + |
| 32 | + regdata = 0x00; |
| 33 | + I2C_Write_NBytes(MPU6886_ADDRESS, MPU6886_PWR_MGMT_1, 1, ®data); |
| 34 | + delay(10); |
| 35 | + |
| 36 | + regdata = (0x01<<7); |
| 37 | + I2C_Write_NBytes(MPU6886_ADDRESS, MPU6886_PWR_MGMT_1, 1, ®data); |
| 38 | + delay(10); |
| 39 | + |
| 40 | + regdata = (0x01<<0); |
| 41 | + I2C_Write_NBytes(MPU6886_ADDRESS, MPU6886_PWR_MGMT_1, 1, ®data); |
| 42 | + delay(10); |
| 43 | + |
| 44 | + regdata = 0x10; |
| 45 | + I2C_Write_NBytes(MPU6886_ADDRESS, MPU6886_ACCEL_CONFIG, 1, ®data); |
| 46 | + delay(1); |
| 47 | + |
| 48 | + regdata = 0x18; |
| 49 | + I2C_Write_NBytes(MPU6886_ADDRESS, MPU6886_GYRO_CONFIG, 1, ®data); |
| 50 | + delay(1); |
| 51 | + |
| 52 | + regdata = 0x01; |
| 53 | + I2C_Write_NBytes(MPU6886_ADDRESS, MPU6886_CONFIG, 1, ®data); |
| 54 | + delay(1); |
| 55 | + |
| 56 | + regdata = 0x05; |
| 57 | + I2C_Write_NBytes(MPU6886_ADDRESS, MPU6886_SMPLRT_DIV, 1,®data); |
| 58 | + delay(1); |
| 59 | + |
| 60 | + regdata = 0x00; |
| 61 | + I2C_Write_NBytes(MPU6886_ADDRESS, MPU6886_INT_ENABLE, 1, ®data); |
| 62 | + delay(1); |
| 63 | + |
| 64 | + regdata = 0x00; |
| 65 | + I2C_Write_NBytes(MPU6886_ADDRESS, MPU6886_ACCEL_CONFIG2, 1, ®data); |
| 66 | + delay(1); |
| 67 | + |
| 68 | + regdata = 0x00; |
| 69 | + I2C_Write_NBytes(MPU6886_ADDRESS, MPU6886_USER_CTRL, 1, ®data); |
| 70 | + delay(1); |
| 71 | + |
| 72 | + regdata = 0x00; |
| 73 | + I2C_Write_NBytes(MPU6886_ADDRESS, MPU6886_FIFO_EN, 1, ®data); |
| 74 | + delay(1); |
| 75 | + |
| 76 | + regdata = 0x22; |
| 77 | + I2C_Write_NBytes(MPU6886_ADDRESS, MPU6886_INT_PIN_CFG, 1, ®data); |
| 78 | + delay(1); |
| 79 | + |
| 80 | + regdata = 0x01; |
| 81 | + I2C_Write_NBytes(MPU6886_ADDRESS, MPU6886_INT_ENABLE, 1, ®data); |
| 82 | + |
| 83 | + delay(10); |
| 84 | + |
| 85 | + setGyroFsr(Gyscale); |
| 86 | + setAccelFsr(Acscale); |
| 87 | + return 0; |
| 88 | +} |
| 89 | + |
| 90 | +void MPU6886::getAccelAdc(int16_t* ax, int16_t* ay, int16_t* az) { |
| 91 | + uint8_t buf[6]; |
| 92 | + I2C_Read_NBytes(MPU6886_ADDRESS, MPU6886_ACCEL_XOUT_H, 6, buf); |
| 93 | + |
| 94 | + *ax=((int16_t)buf[0]<<8)|buf[1]; |
| 95 | + *ay=((int16_t)buf[2]<<8)|buf[3]; |
| 96 | + *az=((int16_t)buf[4]<<8)|buf[5]; |
| 97 | +} |
| 98 | + |
| 99 | +void MPU6886::getGyroAdc(int16_t* gx, int16_t* gy, int16_t* gz) { |
| 100 | + uint8_t buf[6]; |
| 101 | + I2C_Read_NBytes(MPU6886_ADDRESS,MPU6886_GYRO_XOUT_H, 6, buf); |
| 102 | + |
| 103 | + *gx=((uint16_t)buf[0]<<8)|buf[1]; |
| 104 | + *gy=((uint16_t)buf[2]<<8)|buf[3]; |
| 105 | + *gz=((uint16_t)buf[4]<<8)|buf[5]; |
| 106 | +} |
| 107 | + |
| 108 | +void MPU6886::getTempAdc(int16_t *t) { |
| 109 | + uint8_t buf[2]; |
| 110 | + I2C_Read_NBytes(MPU6886_ADDRESS,MPU6886_TEMP_OUT_H,2,buf); |
| 111 | + |
| 112 | + *t=((uint16_t)buf[0]<<8)|buf[1]; |
| 113 | +} |
| 114 | + |
| 115 | +//!俯仰,航向,横滚:pitch,yaw,roll,指三维空间中飞行器的旋转状态。 |
| 116 | +void MPU6886::getAhrsData(float *pitch, float *roll, float *yaw) { |
| 117 | + |
| 118 | + float accX = 0; |
| 119 | + float accY = 0; |
| 120 | + float accZ = 0; |
| 121 | + |
| 122 | + float gyroX = 0; |
| 123 | + float gyroY = 0; |
| 124 | + float gyroZ = 0; |
| 125 | + |
| 126 | + |
| 127 | + getGyroData(&gyroX, &gyroY, &gyroZ); |
| 128 | + getAccelData(&accX, &accY, &accZ); |
| 129 | + |
| 130 | + MahonyAHRSupdateIMU(gyroX * DEG_TO_RAD, gyroY * DEG_TO_RAD, gyroZ * DEG_TO_RAD, accX, accY, accZ, pitch, roll, yaw); |
| 131 | +} |
| 132 | + |
| 133 | +// Possible gyro scales (and their register bit settings) |
| 134 | +void MPU6886::updateGres() { |
| 135 | + switch (Gyscale) { |
| 136 | + case GFS_250DPS: |
| 137 | + gRes = 250.0/32768.0; |
| 138 | + break; |
| 139 | + case GFS_500DPS: |
| 140 | + gRes = 500.0/32768.0; |
| 141 | + break; |
| 142 | + case GFS_1000DPS: |
| 143 | + gRes = 1000.0/32768.0; |
| 144 | + break; |
| 145 | + case GFS_2000DPS: |
| 146 | + gRes = 2000.0/32768.0; |
| 147 | + break; |
| 148 | + } |
| 149 | + |
| 150 | +} |
| 151 | + |
| 152 | +// Possible accelerometer scales (and their register bit settings) are: |
| 153 | +// 2 Gs (00), 4 Gs (01), 8 Gs (10), and 16 Gs (11). |
| 154 | +// Here's a bit of an algorith to calculate DPS/(ADC tick) based on that 2-bit value: |
| 155 | +void MPU6886::updateAres() { |
| 156 | + switch (Acscale) { |
| 157 | + case AFS_2G: |
| 158 | + aRes = 2.0/32768.0; |
| 159 | + break; |
| 160 | + case AFS_4G: |
| 161 | + aRes = 4.0/32768.0; |
| 162 | + break; |
| 163 | + case AFS_8G: |
| 164 | + aRes = 8.0/32768.0; |
| 165 | + break; |
| 166 | + case AFS_16G: |
| 167 | + aRes = 16.0/32768.0; |
| 168 | + break; |
| 169 | + } |
| 170 | +} |
| 171 | + |
| 172 | +void MPU6886::setGyroFsr(Gscale scale) { |
| 173 | + unsigned char regdata; |
| 174 | + regdata = (scale<<3); |
| 175 | + I2C_Write_NBytes(MPU6886_ADDRESS, MPU6886_GYRO_CONFIG, 1, ®data); |
| 176 | + delay(10); |
| 177 | + Gyscale = scale; |
| 178 | + updateGres(); |
| 179 | +} |
| 180 | + |
| 181 | +void MPU6886::setAccelFsr(Ascale scale) { |
| 182 | + unsigned char regdata; |
| 183 | + regdata = (scale<<3); |
| 184 | + I2C_Write_NBytes(MPU6886_ADDRESS, MPU6886_ACCEL_CONFIG, 1, ®data); |
| 185 | + delay(10); |
| 186 | + Acscale = scale; |
| 187 | + updateAres(); |
| 188 | +} |
| 189 | + |
| 190 | +void MPU6886::getAccelData(float* ax, float* ay, float* az) { |
| 191 | + int16_t accX = 0; |
| 192 | + int16_t accY = 0; |
| 193 | + int16_t accZ = 0; |
| 194 | + getAccelAdc(&accX,&accY,&accZ); |
| 195 | + |
| 196 | + *ax = (float)accX * aRes; |
| 197 | + *ay = (float)accY * aRes; |
| 198 | + *az = (float)accZ * aRes; |
| 199 | +} |
| 200 | + |
| 201 | +void MPU6886::getGyroData(float* gx, float* gy, float* gz) { |
| 202 | + int16_t gyroX = 0; |
| 203 | + int16_t gyroY = 0; |
| 204 | + int16_t gyroZ = 0; |
| 205 | + getGyroAdc(&gyroX,&gyroY,&gyroZ); |
| 206 | + |
| 207 | + *gx = (float)gyroX * gRes; |
| 208 | + *gy = (float)gyroY * gRes; |
| 209 | + *gz = (float)gyroZ * gRes; |
| 210 | +} |
| 211 | + |
| 212 | +void MPU6886::getTempData(float *t) { |
| 213 | + int16_t temp = 0; |
| 214 | + getTempAdc(&temp); |
| 215 | + |
| 216 | + *t = (float)temp / 326.8 + 25.0; |
| 217 | +} |
0 commit comments