Skip to content

Commit d0b72df

Browse files
authored
Merge pull request #69 from sparkfun/release_candidate
v1.2.6
2 parents ffca57b + 359278e commit d0b72df

File tree

7 files changed

+2323
-531
lines changed

7 files changed

+2323
-531
lines changed

DMP.md

+2,268-500
Large diffs are not rendered by default.

examples/Arduino/Example10_DMP_FastMultipleSensors/Example10_DMP_FastMultipleSensors.ino

+21-8
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ void loop()
188188
// In case of drift, the sum will not add to 1, therefore, quaternion data need to be corrected with right bias values.
189189
// The quaternion data is scaled by 2^30.
190190

191-
//SERIAL_PORT.printf("Quat6 data is: Q1:%ld Q2:%ld Q3:%ld Accuracy:%d\r\n", data.Quat6.Data.Q1, data.Quat6.Data.Q2, data.Quat6.Data.Q3);
191+
//SERIAL_PORT.printf("Quat6 data is: Q1:%ld Q2:%ld Q3:%ld\r\n", data.Quat6.Data.Q1, data.Quat6.Data.Q2, data.Quat6.Data.Q3);
192192

193193
// Scale to +/- 1
194194
double q1 = ((double)data.Quat6.Data.Q1) / 1073741824.0; // Convert to double. Divide by 2^30
@@ -316,11 +316,12 @@ ICM_20948_Status_e ICM_20948::initializeDMP(void)
316316
// Enable accel and gyro sensors through PWR_MGMT_2
317317
// Enable Accelerometer (all axes) and Gyroscope (all axes) by writing zero to PWR_MGMT_2
318318
result = setBank(0); if (result > worstResult) worstResult = result; // Select Bank 0
319-
uint8_t pwrMgmt2 = 0x40; // Set the reserved bit 6
319+
uint8_t pwrMgmt2 = 0x40; // Set the reserved bit 6 (pressure sensor disable?)
320320
result = write(AGB0_REG_PWR_MGMT_2, &pwrMgmt2, 1); if (result > worstResult) worstResult = result; // Write one byte to the PWR_MGMT_2 register
321321

322-
// Configure I2C_Master/Gyro/Accel in Low Power Mode (cycled) with LP_CONFIG
323-
result = setSampleMode((ICM_20948_Internal_Mst | ICM_20948_Internal_Acc | ICM_20948_Internal_Gyr), ICM_20948_Sample_Mode_Cycled); if (result > worstResult) worstResult = result;
322+
// Place _only_ I2C_Master in Low Power Mode (cycled) via LP_CONFIG
323+
// The InvenSense Nucleo example initially puts the accel and gyro into low power mode too, but then later updates LP_CONFIG so only the I2C_Master is in Low Power Mode
324+
result = setSampleMode(ICM_20948_Internal_Mst, ICM_20948_Sample_Mode_Cycled); if (result > worstResult) worstResult = result;
324325

325326
// Disable the FIFO
326327
result = enableFIFO(false); if (result > worstResult) worstResult = result;
@@ -343,6 +344,11 @@ ICM_20948_Status_e ICM_20948::initializeDMP(void)
343344
// dps2000
344345
result = setFullScale((ICM_20948_Internal_Acc | ICM_20948_Internal_Gyr), myFSS); if (result > worstResult) worstResult = result;
345346

347+
// The InvenSense Nucleo code also enables the gyro DLPF (but leaves GYRO_DLPFCFG set to zero = 196.6Hz (3dB))
348+
// We found this by going through the SPI data generated by ZaneL's Teensy-ICM-20948 library byte by byte...
349+
// The gyro DLPF is enabled by default (GYRO_CONFIG_1 = 0x01) so the following line should have no effect, but we'll include it anyway
350+
result = enableDLPF(ICM_20948_Internal_Gyr, true); if (result > worstResult) worstResult = result;
351+
346352
// Enable interrupt for FIFO overflow from FIFOs through INT_ENABLE_2
347353
// If we see this interrupt, we'll need to reset the FIFO
348354
//result = intEnableOverflowFIFO( 0x1F ); if (result > worstResult) worstResult = result; // Enable the interrupt on all FIFOs
@@ -364,8 +370,12 @@ ICM_20948_Status_e ICM_20948::initializeDMP(void)
364370
// Set gyro sample rate divider with GYRO_SMPLRT_DIV
365371
// Set accel sample rate divider with ACCEL_SMPLRT_DIV_2
366372
ICM_20948_smplrt_t mySmplrt;
367-
mySmplrt.g = 4; // ODR is computed as follows: 1.1 kHz/(1+GYRO_SMPLRT_DIV[7:0]). 4 = 220Hz
368-
mySmplrt.a = 4; // ODR is computed as follows: 1.125 kHz/(1+ACCEL_SMPLRT_DIV[11:0]). 4 = 225Hz
373+
//mySmplrt.g = 19; // ODR is computed as follows: 1.1 kHz/(1+GYRO_SMPLRT_DIV[7:0]). 19 = 55Hz. InvenSense Nucleo example uses 19 (0x13).
374+
//mySmplrt.a = 19; // ODR is computed as follows: 1.125 kHz/(1+ACCEL_SMPLRT_DIV[11:0]). 19 = 56.25Hz. InvenSense Nucleo example uses 19 (0x13).
375+
mySmplrt.g = 4; // 225Hz
376+
mySmplrt.a = 4; // 225Hz
377+
//mySmplrt.g = 8; // 112Hz
378+
//mySmplrt.a = 8; // 112Hz
369379
result = setSampleRate((ICM_20948_Internal_Acc | ICM_20948_Internal_Gyr), mySmplrt); if (result > worstResult) worstResult = result;
370380

371381
// Setup DMP start address through PRGM_STRT_ADDRH/PRGM_STRT_ADDRL
@@ -436,7 +446,7 @@ ICM_20948_Status_e ICM_20948::initializeDMP(void)
436446
// 0=1125Hz sample rate, 1=562.5Hz sample rate, ... 4=225Hz sample rate, ...
437447
// 10=102.2727Hz sample rate, ... etc.
438448
// @param[in] gyro_level 0=250 dps, 1=500 dps, 2=1000 dps, 3=2000 dps
439-
result = setGyroSF(4, 3); if (result > worstResult) worstResult = result; // 0 = 225Hz (see above), 3 = 2000dps (see above)
449+
result = setGyroSF(4, 3); if (result > worstResult) worstResult = result; // 4 = 225Hz (see above), 3 = 2000dps (see above)
440450

441451
// Configure the Gyro full scale
442452
// 2000dps : 2^28
@@ -448,17 +458,20 @@ ICM_20948_Status_e ICM_20948::initializeDMP(void)
448458

449459
// Configure the Accel Only Gain: 15252014 (225Hz) 30504029 (112Hz) 61117001 (56Hz)
450460
//const unsigned char accelOnlyGain[4] = {0x03, 0xA4, 0x92, 0x49}; // 56Hz
451-
const unsigned char accelOnlyGain[4] = {0x00, 0xE8, 0xBA, 0x2E}; // InvenSense Nucleo example uses 225Hz
461+
const unsigned char accelOnlyGain[4] = {0x00, 0xE8, 0xBA, 0x2E}; // 225Hz
462+
//const unsigned char accelOnlyGain[4] = {0x01, 0xD1, 0x74, 0x5D}; // 112Hz
452463
result = writeDMPmems(ACCEL_ONLY_GAIN, 4, &accelOnlyGain[0]); if (result > worstResult) worstResult = result;
453464

454465
// Configure the Accel Alpha Var: 1026019965 (225Hz) 977872018 (112Hz) 882002213 (56Hz)
455466
//const unsigned char accelAlphaVar[4] = {0x34, 0x92, 0x49, 0x25}; // 56Hz
456467
const unsigned char accelAlphaVar[4] = {0x3D, 0x27, 0xD2, 0x7D}; // 225Hz
468+
//const unsigned char accelAlphaVar[4] = {0x3A, 0x49, 0x24, 0x92}; // 112Hz
457469
result = writeDMPmems(ACCEL_ALPHA_VAR, 4, &accelAlphaVar[0]); if (result > worstResult) worstResult = result;
458470

459471
// Configure the Accel A Var: 47721859 (225Hz) 95869806 (112Hz) 191739611 (56Hz)
460472
//const unsigned char accelAVar[4] = {0x0B, 0x6D, 0xB6, 0xDB}; // 56Hz
461473
const unsigned char accelAVar[4] = {0x02, 0xD8, 0x2D, 0x83}; // 225Hz
474+
//const unsigned char accelAVar[4] = {0x05, 0xB6, 0xDB, 0x6E}; // 112Hz
462475
result = writeDMPmems(ACCEL_A_VAR, 4, &accelAVar[0]); if (result > worstResult) worstResult = result;
463476

464477
// Configure the Accel Cal Rate

examples/Arduino/Example9_DMP_MultipleSensors/Example9_DMP_MultipleSensors.ino

+1-1
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ void loop()
190190
// In case of drift, the sum will not add to 1, therefore, quaternion data need to be corrected with right bias values.
191191
// The quaternion data is scaled by 2^30.
192192

193-
//SERIAL_PORT.printf("Quat6 data is: Q1:%ld Q2:%ld Q3:%ld Accuracy:%d\r\n", data.Quat6.Data.Q1, data.Quat6.Data.Q2, data.Quat6.Data.Q3, data.Quat6.Data.Accuracy);
193+
//SERIAL_PORT.printf("Quat6 data is: Q1:%ld Q2:%ld Q3:%ld\r\n", data.Quat6.Data.Q1, data.Quat6.Data.Q2, data.Quat6.Data.Q3);
194194

195195
// Scale to +/- 1
196196
double q1 = ((double)data.Quat6.Data.Q1) / 1073741824.0; // Convert to double. Divide by 2^30

library.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=SparkFun 9DoF IMU Breakout - ICM 20948 - Arduino Library
2-
version=1.2.5
2+
version=1.2.6
33
author=SparkFun Electronics <[email protected]>
44
maintainer=SparkFun Electronics <sparkfun.com>
55
sentence=Use the low-power high-resolution ICM 20948 9 DoF IMU from Invensense with I2C or SPI. Version 1.2 of the library includes support for the InvenSense Digital Motion Processor (DMP™).

src/ICM_20948.cpp

+18-6
Original file line numberDiff line numberDiff line change
@@ -1215,8 +1215,9 @@ ICM_20948_Status_e ICM_20948::initializeDMP(void)
12151215
uint8_t pwrMgmt2 = 0x40; // Set the reserved bit 6 (pressure sensor disable?)
12161216
result = write(AGB0_REG_PWR_MGMT_2, &pwrMgmt2, 1); if (result > worstResult) worstResult = result; // Write one byte to the PWR_MGMT_2 register
12171217

1218-
// Configure I2C_Master/Gyro/Accel in Low Power Mode (cycled) with LP_CONFIG
1219-
result = setSampleMode((ICM_20948_Internal_Mst | ICM_20948_Internal_Acc | ICM_20948_Internal_Gyr), ICM_20948_Sample_Mode_Cycled); if (result > worstResult) worstResult = result;
1218+
// Place _only_ I2C_Master in Low Power Mode (cycled) via LP_CONFIG
1219+
// The InvenSense Nucleo example initially puts the accel and gyro into low power mode too, but then later updates LP_CONFIG so only the I2C_Master is in Low Power Mode
1220+
result = setSampleMode(ICM_20948_Internal_Mst, ICM_20948_Sample_Mode_Cycled); if (result > worstResult) worstResult = result;
12201221

12211222
// Disable the FIFO
12221223
result = enableFIFO(false); if (result > worstResult) worstResult = result;
@@ -1239,6 +1240,11 @@ ICM_20948_Status_e ICM_20948::initializeDMP(void)
12391240
// dps2000
12401241
result = setFullScale((ICM_20948_Internal_Acc | ICM_20948_Internal_Gyr), myFSS); if (result > worstResult) worstResult = result;
12411242

1243+
// The InvenSense Nucleo code also enables the gyro DLPF (but leaves GYRO_DLPFCFG set to zero = 196.6Hz (3dB))
1244+
// We found this by going through the SPI data generated by ZaneL's Teensy-ICM-20948 library byte by byte...
1245+
// The gyro DLPF is enabled by default (GYRO_CONFIG_1 = 0x01) so the following line should have no effect, but we'll include it anyway
1246+
result = enableDLPF(ICM_20948_Internal_Gyr, true); if (result > worstResult) worstResult = result;
1247+
12421248
// Enable interrupt for FIFO overflow from FIFOs through INT_ENABLE_2
12431249
// If we see this interrupt, we'll need to reset the FIFO
12441250
//result = intEnableOverflowFIFO( 0x1F ); if (result > worstResult) worstResult = result; // Enable the interrupt on all FIFOs
@@ -1262,7 +1268,10 @@ ICM_20948_Status_e ICM_20948::initializeDMP(void)
12621268
ICM_20948_smplrt_t mySmplrt;
12631269
mySmplrt.g = 19; // ODR is computed as follows: 1.1 kHz/(1+GYRO_SMPLRT_DIV[7:0]). 19 = 55Hz. InvenSense Nucleo example uses 19 (0x13).
12641270
mySmplrt.a = 19; // ODR is computed as follows: 1.125 kHz/(1+ACCEL_SMPLRT_DIV[11:0]). 19 = 56.25Hz. InvenSense Nucleo example uses 19 (0x13).
1265-
// ** Note: comment the next line to leave the sample rates at the maximum **
1271+
//mySmplrt.g = 4; // 225Hz
1272+
//mySmplrt.a = 4; // 225Hz
1273+
//mySmplrt.g = 8; // 112Hz
1274+
//mySmplrt.a = 8; // 112Hz
12661275
result = setSampleRate((ICM_20948_Internal_Acc | ICM_20948_Internal_Gyr), mySmplrt); if (result > worstResult) worstResult = result;
12671276

12681277
// Setup DMP start address through PRGM_STRT_ADDRH/PRGM_STRT_ADDRL
@@ -1345,17 +1354,20 @@ ICM_20948_Status_e ICM_20948::initializeDMP(void)
13451354

13461355
// Configure the Accel Only Gain: 15252014 (225Hz) 30504029 (112Hz) 61117001 (56Hz)
13471356
const unsigned char accelOnlyGain[4] = {0x03, 0xA4, 0x92, 0x49}; // 56Hz
1348-
//const unsigned char accelOnlyGain[4] = {0x00, 0xE8, 0xBA, 0x2E}; // InvenSense Nucleo example uses 225Hz
1357+
//const unsigned char accelOnlyGain[4] = {0x00, 0xE8, 0xBA, 0x2E}; // 225Hz
1358+
//const unsigned char accelOnlyGain[4] = {0x01, 0xD1, 0x74, 0x5D}; // 112Hz
13491359
result = writeDMPmems(ACCEL_ONLY_GAIN, 4, &accelOnlyGain[0]); if (result > worstResult) worstResult = result;
13501360

13511361
// Configure the Accel Alpha Var: 1026019965 (225Hz) 977872018 (112Hz) 882002213 (56Hz)
13521362
const unsigned char accelAlphaVar[4] = {0x34, 0x92, 0x49, 0x25}; // 56Hz
1353-
//const unsigned char accelAlphaVar[4] = {0x06, 0x66, 0x66, 0x66}; // Value taken from InvenSense Nucleo example
1363+
//const unsigned char accelAlphaVar[4] = {0x3D, 0x27, 0xD2, 0x7D}; // 225Hz
1364+
//const unsigned char accelAlphaVar[4] = {0x3A, 0x49, 0x24, 0x92}; // 112Hz
13541365
result = writeDMPmems(ACCEL_ALPHA_VAR, 4, &accelAlphaVar[0]); if (result > worstResult) worstResult = result;
13551366

13561367
// Configure the Accel A Var: 47721859 (225Hz) 95869806 (112Hz) 191739611 (56Hz)
13571368
const unsigned char accelAVar[4] = {0x0B, 0x6D, 0xB6, 0xDB}; // 56Hz
1358-
//const unsigned char accelAVar[4] = {0x39, 0x99, 0x99, 0x9A}; // Value taken from InvenSense Nucleo example
1369+
//const unsigned char accelAVar[4] = {0x02, 0xD8, 0x2D, 0x83}; // 225Hz
1370+
//const unsigned char accelAVar[4] = {0x05, 0xB6, 0xDB, 0x6E}; // 112Hz
13591371
result = writeDMPmems(ACCEL_A_VAR, 4, &accelAVar[0]); if (result > worstResult) worstResult = result;
13601372

13611373
// Configure the Accel Cal Rate

src/ICM_20948.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ A C++ interface to the ICM-20948
2020
class ICM_20948
2121
{
2222
private:
23-
Stream *_debugSerial; //The stream to send debug messages to if enabled
24-
boolean _printDebug = false; //Flag to print the serial commands we are sending to the Serial port for debug
23+
Stream *_debugSerial; //The stream to send debug messages to if enabled
24+
bool _printDebug = false; //Flag to print the serial commands we are sending to the Serial port for debug
2525

2626
const uint8_t MAX_MAGNETOMETER_STARTS = 10; // This replaces maxTries
2727

src/util/ICM_20948_C.c

+12-13
Original file line numberDiff line numberDiff line change
@@ -1297,10 +1297,9 @@ ICM_20948_Status_e inv_icm20948_firmware_load(ICM_20948_Device_t *pdev, const un
12971297
}
12981298

12991299
//Enable LP_EN since we disabled it at begining of this function.
1300-
1301-
// result = ICM_20948_low_power(pdev, true); // Put chip into low power state
1302-
// if (result != ICM_20948_Stat_Ok)
1303-
// return result;
1300+
result = ICM_20948_low_power(pdev, true); // Put chip into low power state
1301+
if (result != ICM_20948_Stat_Ok)
1302+
return result;
13041303

13051304
if (!flag)
13061305
{
@@ -1602,9 +1601,9 @@ ICM_20948_Status_e inv_icm20948_set_dmp_sensor_period(ICM_20948_Device_t *pdev,
16021601
break;
16031602
}
16041603

1605-
// result = ICM_20948_low_power(pdev, true); // Put chip into low power state
1606-
// if (result != ICM_20948_Stat_Ok)
1607-
// return result;
1604+
result = ICM_20948_low_power(pdev, true); // Put chip into low power state
1605+
if (result != ICM_20948_Stat_Ok)
1606+
return result;
16081607

16091608
if (result2 > result)
16101609
result = result2; // Return the highest error
@@ -1774,9 +1773,9 @@ ICM_20948_Status_e inv_icm20948_enable_dmp_sensor(ICM_20948_Device_t *pdev, enum
17741773
return result;
17751774
}
17761775

1777-
// result = ICM_20948_low_power(pdev, true); // Put chip into low power state
1778-
// if (result != ICM_20948_Stat_Ok)
1779-
// return result;
1776+
result = ICM_20948_low_power(pdev, true); // Put chip into low power state
1777+
if (result != ICM_20948_Stat_Ok)
1778+
return result;
17801779

17811780
return result;
17821781
}
@@ -1861,9 +1860,9 @@ ICM_20948_Status_e inv_icm20948_enable_dmp_sensor_int(ICM_20948_Device_t *pdev,
18611860
// Write the interrupt control bits into memory address DATA_INTR_CTL
18621861
result = inv_icm20948_write_mems(pdev, DATA_INTR_CTL, 2, (const unsigned char *)&data_intr_ctl);
18631862

1864-
// result = ICM_20948_low_power(pdev, true); // Put chip into low power state
1865-
// if (result != ICM_20948_Stat_Ok)
1866-
// return result;
1863+
result = ICM_20948_low_power(pdev, true); // Put chip into low power state
1864+
if (result != ICM_20948_Stat_Ok)
1865+
return result;
18671866

18681867
return result;
18691868
}

0 commit comments

Comments
 (0)