|
1 | 1 | #include "ICM_20948.h"
|
2 | 2 |
|
3 |
| -ICM_20948_I2C myIC; |
| 3 | + |
| 4 | +#define MAG_AK09916_I2C_ADDR 0x0C |
| 5 | +#define MAG_AK09916_WHO_AM_I 0x4809 |
| 6 | +#define MAG_REG_WHO_AM_I 0x00 |
| 7 | + |
| 8 | +#define SERIAL_PORT Serial |
| 9 | + |
| 10 | +ICM_20948_I2C myICM; |
4 | 11 |
|
5 | 12 | void setup() {
|
6 | 13 | // put your setup code here, to run once:
|
7 | 14 |
|
| 15 | + SERIAL_PORT.begin(115200); |
| 16 | +// while(!SERIAL_PORT){}; // NOTE: make sure while(!SERIAL_PORT) does not accidentally call Wire.begin a bunch of times |
| 17 | + |
| 18 | + Wire.begin(); |
| 19 | +// Wire.setClock(10000); // low-speed mode maybe helps? |
| 20 | + Wire.setClock(400000); // low-speed mode maybe helps? |
| 21 | + myICM.begin(); |
| 22 | + |
| 23 | + while(!myICM.isConnected()){ |
| 24 | + SERIAL_PORT.print("Could not find the device at (8bit) address: 0x"); |
| 25 | + SERIAL_PORT.print(myICM._addr, HEX); |
| 26 | + SERIAL_PORT.print(". Trying again"); |
| 27 | + SERIAL_PORT.println(); |
| 28 | + delay(500); |
| 29 | + } |
| 30 | + |
| 31 | + SERIAL_PORT.println("Device connected!"); |
| 32 | + |
| 33 | + // Here we are doing a SW reset to make sure the device starts in a known state |
| 34 | + myICM.swReset( ); |
| 35 | + if( myICM.status != ICM_20948_Stat_Ok){ |
| 36 | + SERIAL_PORT.print(F("Software Reset returned: ")); |
| 37 | + SERIAL_PORT.println(myICM.statusString()); |
| 38 | + } |
| 39 | + delay(250); |
| 40 | + |
| 41 | + // Now wake the sensor up |
| 42 | + myICM.sleep( false ); |
| 43 | + myICM.lowPower( false ); |
| 44 | + |
| 45 | + // Set Gyro and Accelerometer to a particular sample mode |
| 46 | + myICM.setSampleMode( (ICM_20948_Internal_Acc | ICM_20948_Internal_Gyr), ICM_20948_Sample_Mode_Continuous ); // options: ICM_20948_Sample_Mode_Continuous or ICM_20948_Sample_Mode_Cycled |
| 47 | + if( myICM.status != ICM_20948_Stat_Ok){ |
| 48 | + SERIAL_PORT.print(F("setSampleMode returned: ")); |
| 49 | + SERIAL_PORT.println(myICM.statusString()); |
| 50 | + } |
| 51 | + |
| 52 | + // Set full scale ranges for both acc and gyr |
| 53 | + ICM_20948_fss_t myFSS; |
| 54 | + myFSS.a = gpm2; // (ICM_20948_ACCEL_CONFIG_FS_SEL_e) |
| 55 | + myFSS.g = dps2000; // (ICM_20948_GYRO_CONFIG_1_FS_SEL_e) |
| 56 | + myICM.setFullScale( (ICM_20948_Internal_Acc | ICM_20948_Internal_Gyr), myFSS ); |
| 57 | + if( myICM.status != ICM_20948_Stat_Ok){ |
| 58 | + SERIAL_PORT.print(F("setFullScale returned: ")); |
| 59 | + SERIAL_PORT.println(myICM.statusString()); |
| 60 | + } |
| 61 | + |
| 62 | + // Set up DLPF configuration |
| 63 | + ICM_20948_dlpcfg_t myDLPcfg; |
| 64 | + myDLPcfg.a = acc_d473bw_n499bw; |
| 65 | + myDLPcfg.g = gyr_d361bw4_n376bw5; |
| 66 | + myICM.setDLPFcfg( (ICM_20948_Internal_Acc | ICM_20948_Internal_Gyr), myDLPcfg ); |
| 67 | + if( myICM.status != ICM_20948_Stat_Ok){ |
| 68 | + SERIAL_PORT.print(F("setDLPcfg returned: ")); |
| 69 | + SERIAL_PORT.println(myICM.statusString()); |
| 70 | + } |
| 71 | + |
| 72 | + // Choose whether or not to use DLPF |
| 73 | + ICM_20948_Status_e accDLPEnableStat = myICM.enableDLPF( ICM_20948_Internal_Acc, false ); |
| 74 | + ICM_20948_Status_e gyrDLPEnableStat = myICM.enableDLPF( ICM_20948_Internal_Gyr, false ); |
| 75 | + SERIAL_PORT.print(F("Enable DLPF for Accelerometer returned: ")); SERIAL_PORT.println(myICM.statusString(accDLPEnableStat)); |
| 76 | + SERIAL_PORT.print(F("Enable DLPF for Gyroscope returned: ")); SERIAL_PORT.println(myICM.statusString(gyrDLPEnableStat)); |
| 77 | + |
| 78 | +// // Enable the I2C master to talk to the magnetometer through the ICM 20948 |
| 79 | +// myICM.i2cMasterEnable( true ); |
| 80 | +// SERIAL_PORT.print(F("Enabling the I2C master returned ")); SERIAL_PORT.println(myICM.statusString()); |
| 81 | + |
| 82 | + // |
| 83 | + myICM.i2cMasterPassthrough( true ); // Set passthrough mode to try to access the magnetometer |
| 84 | + |
8 | 85 | }
|
9 | 86 |
|
10 | 87 | void loop() {
|
11 | 88 | // put your main code here, to run repeatedly:
|
12 | 89 |
|
| 90 | +// if( myICM.dataReady() ){ |
| 91 | +// myICM.getAGMT(); |
| 92 | +//// printRawAGMT( myICM.agmt ); |
| 93 | +// printScaledAGMT( myICM.agmt); |
| 94 | +// |
| 95 | +// delay(20); |
| 96 | +// |
| 97 | +// }else{ |
| 98 | +// Serial.println("0"); |
| 99 | +// } |
| 100 | + |
| 101 | +// Serial.println( myICM.i2cMasterSingleR( MAG_AK09916_I2C_ADDR, MAG_REG_WHO_AM_I ), HEX); |
| 102 | +// Serial.println("hi"); |
| 103 | +// delay(500); |
| 104 | + |
| 105 | + byte error, address; |
| 106 | + int nDevices; |
| 107 | + |
| 108 | + Serial.println("Scanning..."); |
| 109 | + |
| 110 | + nDevices = 0; |
| 111 | + for(address = 1; address < 127; address++ ) |
| 112 | + { |
| 113 | + // The i2c_scanner uses the return value of |
| 114 | + // the Write.endTransmisstion to see if |
| 115 | + // a device did acknowledge to the address. |
| 116 | + Wire.beginTransmission(address); |
| 117 | + error = Wire.endTransmission(); |
| 118 | + |
| 119 | + if (error == 0) |
| 120 | + { |
| 121 | + Serial.print("I2C device found at address 0x"); |
| 122 | + if (address<16) |
| 123 | + Serial.print("0"); |
| 124 | + Serial.print(address,HEX); |
| 125 | + Serial.println(" !"); |
| 126 | + |
| 127 | + nDevices++; |
| 128 | + } |
| 129 | + else if (error==4) |
| 130 | + { |
| 131 | + Serial.print("Unknown error at address 0x"); |
| 132 | + if (address<16) |
| 133 | + Serial.print("0"); |
| 134 | + Serial.println(address,HEX); |
| 135 | + } |
| 136 | + } |
| 137 | + if (nDevices == 0) |
| 138 | + Serial.println("No I2C devices found\n"); |
| 139 | + else |
| 140 | + Serial.println("done\n"); |
| 141 | + |
| 142 | + delay(1000); // wait 5 seconds for next scan |
| 143 | + |
| 144 | +} |
| 145 | + |
| 146 | +void printPaddedInt16b( int16_t val ){ |
| 147 | + if(val > 0){ |
| 148 | + SERIAL_PORT.print(" "); |
| 149 | + if(val < 10000){ SERIAL_PORT.print("0"); } |
| 150 | + if(val < 1000 ){ SERIAL_PORT.print("0"); } |
| 151 | + if(val < 100 ){ SERIAL_PORT.print("0"); } |
| 152 | + if(val < 10 ){ SERIAL_PORT.print("0"); } |
| 153 | + }else{ |
| 154 | + SERIAL_PORT.print("-"); |
| 155 | + if(abs(val) < 10000){ SERIAL_PORT.print("0"); } |
| 156 | + if(abs(val) < 1000 ){ SERIAL_PORT.print("0"); } |
| 157 | + if(abs(val) < 100 ){ SERIAL_PORT.print("0"); } |
| 158 | + if(abs(val) < 10 ){ SERIAL_PORT.print("0"); } |
| 159 | + } |
| 160 | + SERIAL_PORT.print(abs(val)); |
| 161 | +} |
| 162 | + |
| 163 | +void printRawAGMT( ICM_20948_AGMT_t agmt){ |
| 164 | + SERIAL_PORT.print("RAW. Acc [ "); |
| 165 | + printPaddedInt16b( agmt.acc.axes.x ); |
| 166 | + SERIAL_PORT.print(", "); |
| 167 | + printPaddedInt16b( agmt.acc.axes.y ); |
| 168 | + SERIAL_PORT.print(", "); |
| 169 | + printPaddedInt16b( agmt.acc.axes.z ); |
| 170 | + SERIAL_PORT.print(" ], Gyr [ "); |
| 171 | + printPaddedInt16b( agmt.gyr.axes.x ); |
| 172 | + SERIAL_PORT.print(", "); |
| 173 | + printPaddedInt16b( agmt.gyr.axes.y ); |
| 174 | + SERIAL_PORT.print(", "); |
| 175 | + printPaddedInt16b( agmt.gyr.axes.z ); |
| 176 | + SERIAL_PORT.print(" ], Mag [ "); |
| 177 | + printPaddedInt16b( agmt.mag.axes.x ); |
| 178 | + SERIAL_PORT.print(", "); |
| 179 | + printPaddedInt16b( agmt.mag.axes.y ); |
| 180 | + SERIAL_PORT.print(", "); |
| 181 | + printPaddedInt16b( agmt.mag.axes.z ); |
| 182 | + SERIAL_PORT.print(" ], Tmp [ "); |
| 183 | + printPaddedInt16b( agmt.tmp.val ); |
| 184 | + SERIAL_PORT.print(" ]"); |
| 185 | + SERIAL_PORT.println(); |
| 186 | +} |
| 187 | + |
| 188 | +float getAccMG( int16_t raw, uint8_t fss ){ |
| 189 | + switch(fss){ |
| 190 | + case 0 : return (((float)raw)/16.384); break; |
| 191 | + case 1 : return (((float)raw)/8.192); break; |
| 192 | + case 2 : return (((float)raw)/4.096); break; |
| 193 | + case 3 : return (((float)raw)/2.048); break; |
| 194 | + default : return 0; break; |
| 195 | + } |
| 196 | +} |
| 197 | + |
| 198 | +float getGyrDPS( int16_t raw, uint8_t fss ){ |
| 199 | + switch(fss){ |
| 200 | + case 0 : return (((float)raw)/131); break; |
| 201 | + case 1 : return (((float)raw)/65.5); break; |
| 202 | + case 2 : return (((float)raw)/32.8); break; |
| 203 | + case 3 : return (((float)raw)/16.4); break; |
| 204 | + default : return 0; break; |
| 205 | + } |
| 206 | +} |
| 207 | + |
| 208 | +float getMagUT( int16_t raw ){ |
| 209 | +// return (((float)raw)*0.15); |
| 210 | +// todo: this is a much more complicated formula, atually |
| 211 | +} |
| 212 | + |
| 213 | +float getTmpC( int16_t raw ){ |
| 214 | + return (((float)raw)/333.87) + 21; |
| 215 | +} |
| 216 | + |
| 217 | +void printScaledAGMT( ICM_20948_AGMT_t agmt){ |
| 218 | + Serial.print("Scaled. Acc (mg) [ "); |
| 219 | + Serial.print( getAccMG(agmt.acc.axes.x, agmt.fss.a ) ); |
| 220 | + Serial.print(", "); |
| 221 | + Serial.print( getAccMG(agmt.acc.axes.y, agmt.fss.a ) ); |
| 222 | + Serial.print(", "); |
| 223 | + Serial.print( getAccMG(agmt.acc.axes.z, agmt.fss.a ) ); |
| 224 | + Serial.print(" ], Gyr (DPS) [ "); |
| 225 | + Serial.print( getGyrDPS(agmt.gyr.axes.x, agmt.fss.g ) ); |
| 226 | + Serial.print(", "); |
| 227 | + Serial.print( getGyrDPS(agmt.gyr.axes.y, agmt.fss.g ) ); |
| 228 | + Serial.print(", "); |
| 229 | + Serial.print( getGyrDPS(agmt.gyr.axes.z, agmt.fss.g ) ); |
| 230 | + Serial.print(" ], Mag (uT) [ "); |
| 231 | + Serial.print( getMagUT(agmt.mag.axes.x) ); |
| 232 | + Serial.print(", "); |
| 233 | + Serial.print( getMagUT(agmt.mag.axes.y) ); |
| 234 | + Serial.print(", "); |
| 235 | + Serial.print( getMagUT(agmt.mag.axes.z) ); |
| 236 | + Serial.print(" ], Tmp (C) [ "); |
| 237 | + Serial.print( getTmpC(agmt.tmp.val) ); |
| 238 | + Serial.print(" ]"); |
| 239 | + Serial.println(); |
13 | 240 | }
|
0 commit comments