2424 * Distributed as-is; no warranty is given.
2525 ***************************************************************/
2626
27- #include " ICM_20948.h" // Click here to get the library: http://librarymanager/All#SparkFun_ICM_20948_IMU
27+ #include " ICM_20948.h" // Click here to get the library: http://librarymanager/All#SparkFun_ICM_20948_IMU
2828
2929// #define USE_SPI // Uncomment this to use SPI
3030
3131#define SERIAL_PORT Serial
3232
33- #define SPI_PORT SPI // Your desired SPI port. Used only when "USE_SPI" is defined
34- #define CS_PIN 2 // Which pin you connect CS to. Used only when "USE_SPI" is defined
33+ #define SPI_PORT SPI // Your desired SPI port. Used only when "USE_SPI" is defined
34+ #define CS_PIN 2 // Which pin you connect CS to. Used only when "USE_SPI" is defined
3535
36- #define WIRE_PORT Wire // Your desired Wire port. Used when "USE_SPI" is not defined
37- #define AD0_VAL 1 // The value of the last bit of the I2C address.
38- // On the SparkFun 9DoF IMU breakout the default is 1, and when
39- // the ADR jumper is closed the value becomes 0
36+ #define WIRE_PORT Wire // Your desired Wire port. Used when "USE_SPI" is not defined
37+ #define AD0_VAL 1 // The value of the last bit of the I2C address. \
38+ // On the SparkFun 9DoF IMU breakout the default is 1, and when \
39+ // the ADR jumper is closed the value becomes 0
4040
4141#ifdef USE_SPI
42- ICM_20948_SPI myICM; // If using SPI create an ICM_20948_SPI object
42+ ICM_20948_SPI myICM; // If using SPI create an ICM_20948_SPI object
4343#else
44- ICM_20948_I2C myICM; // Otherwise create an ICM_20948_I2C object
44+ ICM_20948_I2C myICM; // Otherwise create an ICM_20948_I2C object
4545#endif
4646
47-
48- void setup () {
47+ void setup ()
48+ {
4949
5050 SERIAL_PORT.begin (115200 ); // Start the serial console
5151 SERIAL_PORT.println (F (" ICM-20948 Example" ));
@@ -61,31 +61,35 @@ void setup() {
6161 ;
6262
6363#ifdef USE_SPI
64- SPI_PORT.begin ();
64+ SPI_PORT.begin ();
6565#else
66- WIRE_PORT.begin ();
67- WIRE_PORT.setClock (400000 );
66+ WIRE_PORT.begin ();
67+ WIRE_PORT.setClock (400000 );
6868#endif
6969
7070 // myICM.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial
7171
7272 bool initialized = false ;
73- while ( !initialized ){
73+ while (!initialized)
74+ {
7475
7576 // Initialize the ICM-20948
7677 // If the DMP is enabled, .begin performs a minimal startup. We need to configure the sample mode etc. manually.
7778#ifdef USE_SPI
78- myICM.begin ( CS_PIN, SPI_PORT );
79+ myICM.begin (CS_PIN, SPI_PORT);
7980#else
80- myICM.begin ( WIRE_PORT, AD0_VAL );
81+ myICM.begin (WIRE_PORT, AD0_VAL);
8182#endif
8283
83- SERIAL_PORT.print ( F (" Initialization of the sensor returned: " ) );
84- SERIAL_PORT.println ( myICM.statusString () );
85- if ( myICM.status != ICM_20948_Stat_Ok ){
86- SERIAL_PORT.println ( F (" Trying again..." ) );
84+ SERIAL_PORT.print (F (" Initialization of the sensor returned: " ));
85+ SERIAL_PORT.println (myICM.statusString ());
86+ if (myICM.status != ICM_20948_Stat_Ok)
87+ {
88+ SERIAL_PORT.println (F (" Trying again..." ));
8789 delay (500 );
88- }else {
90+ }
91+ else
92+ {
8993 initialized = true ;
9094 }
9195 }
@@ -103,12 +107,12 @@ void setup() {
103107
104108 // Enable accel and gyro sensors through PWR_MGMT_2
105109 // Enable Accelerometer (all axes) and Gyroscope (all axes) by writing zero to PWR_MGMT_2
106- success &= (myICM.setBank (0 ) == ICM_20948_Stat_Ok); // Select Bank 0
107- uint8_t pwrMgmt2 = 0x40 ; // Set the reserved bit 6
110+ success &= (myICM.setBank (0 ) == ICM_20948_Stat_Ok); // Select Bank 0
111+ uint8_t pwrMgmt2 = 0x40 ; // Set the reserved bit 6
108112 success &= (myICM.write (AGB0_REG_PWR_MGMT_2, &pwrMgmt2, 1 ) == ICM_20948_Stat_Ok); // Write one byte to the PWR_MGMT_2 register
109113
110114 // Configure I2C_Master/Gyro/Accel in Low Power Mode (cycled) with LP_CONFIG
111- success &= (myICM.setSampleMode ( (ICM_20948_Internal_Mst | ICM_20948_Internal_Acc | ICM_20948_Internal_Gyr), ICM_20948_Sample_Mode_Cycled ) == ICM_20948_Stat_Ok);
115+ success &= (myICM.setSampleMode ((ICM_20948_Internal_Mst | ICM_20948_Internal_Acc | ICM_20948_Internal_Gyr), ICM_20948_Sample_Mode_Cycled) == ICM_20948_Stat_Ok);
112116
113117 // Disable the FIFO
114118 success &= (myICM.enableFIFO (false ) == ICM_20948_Stat_Ok);
@@ -118,18 +122,18 @@ void setup() {
118122
119123 // Set Gyro FSR (Full scale range) to 2000dps through GYRO_CONFIG_1
120124 // Set Accel FSR (Full scale range) to 4g through ACCEL_CONFIG
121- ICM_20948_fss_t myFSS; // This uses a "Full Scale Settings" structure that can contain values for all configurable sensors
122- myFSS.a = gpm4; // (ICM_20948_ACCEL_CONFIG_FS_SEL_e)
123- // gpm2
124- // gpm4
125- // gpm8
126- // gpm16
127- myFSS.g = dps2000; // (ICM_20948_GYRO_CONFIG_1_FS_SEL_e)
128- // dps250
129- // dps500
130- // dps1000
131- // dps2000
132- success &= (myICM.setFullScale ( (ICM_20948_Internal_Acc | ICM_20948_Internal_Gyr), myFSS ) == ICM_20948_Stat_Ok);
125+ ICM_20948_fss_t myFSS; // This uses a "Full Scale Settings" structure that can contain values for all configurable sensors
126+ myFSS.a = gpm4; // (ICM_20948_ACCEL_CONFIG_FS_SEL_e)
127+ // gpm2
128+ // gpm4
129+ // gpm8
130+ // gpm16
131+ myFSS.g = dps2000; // (ICM_20948_GYRO_CONFIG_1_FS_SEL_e)
132+ // dps250
133+ // dps500
134+ // dps1000
135+ // dps2000
136+ success &= (myICM.setFullScale ((ICM_20948_Internal_Acc | ICM_20948_Internal_Gyr), myFSS) == ICM_20948_Stat_Ok);
133137
134138 // Enable interrupt for FIFO overflow from FIFOs through INT_ENABLE_2
135139 // If we see this interrupt, we'll need to reset the FIFO
@@ -154,8 +158,8 @@ void setup() {
154158 ICM_20948_smplrt_t mySmplrt;
155159 mySmplrt.g = 4 ; // ODR is computed as follows: 1.1 kHz/(1+GYRO_SMPLRT_DIV[7:0]). 4 = 220Hz
156160 mySmplrt.a = 4 ; // ODR is computed as follows: 1.125 kHz/(1+ACCEL_SMPLRT_DIV[11:0]). 4 = 225Hz
157- myICM.setSampleRate ( (ICM_20948_Internal_Acc | ICM_20948_Internal_Gyr), mySmplrt );
158-
161+ myICM.setSampleRate ((ICM_20948_Internal_Acc | ICM_20948_Internal_Gyr), mySmplrt);
162+
159163 // Setup DMP start address through PRGM_STRT_ADDRH/PRGM_STRT_ADDRL
160164 success &= (myICM.setDMPstartAddress () == ICM_20948_Stat_Ok); // Defaults to DMP_START_ADDRESS
161165
@@ -169,12 +173,12 @@ void setup() {
169173 success &= (myICM.setBank (0 ) == ICM_20948_Stat_Ok); // Select Bank 0
170174 uint8_t fix = 0x48 ;
171175 success &= (myICM.write (AGB0_REG_HW_FIX_DISABLE, &fix, 1 ) == ICM_20948_Stat_Ok);
172-
176+
173177 // Set the Single FIFO Priority Select register to 0xE4
174178 success &= (myICM.setBank (0 ) == ICM_20948_Stat_Ok); // Select Bank 0
175179 uint8_t fifoPrio = 0xE4 ;
176180 success &= (myICM.write (AGB0_REG_SINGLE_FIFO_PRIORITY_SEL, &fifoPrio, 1 ) == ICM_20948_Stat_Ok);
177-
181+
178182 // Configure Accel scaling to DMP
179183 // The DMP scales accel raw data internally to align 1g as 2^25
180184 // In order to align internal accel raw data 2^25 = 1g write 0x04000000 when FSR is 4g
@@ -194,7 +198,7 @@ void setup() {
194198 // The AK09916 produces a 16-bit signed output in the range +/-32752 corresponding to +/-4912uT. 1uT = 6.66 ADU.
195199 // 2^30 / 6.66666 = 161061273 = 0x9999999
196200 const unsigned char mountMultiplierZero[4 ] = {0x00 , 0x00 , 0x00 , 0x00 };
197- const unsigned char mountMultiplierPlus[4 ] = {0x09 , 0x99 , 0x99 , 0x99 }; // Value taken from InvenSense Nucleo example
201+ const unsigned char mountMultiplierPlus[4 ] = {0x09 , 0x99 , 0x99 , 0x99 }; // Value taken from InvenSense Nucleo example
198202 const unsigned char mountMultiplierMinus[4 ] = {0xF6 , 0x66 , 0x66 , 0x67 }; // Value taken from InvenSense Nucleo example
199203 success &= (myICM.writeDMPmems (CPASS_MTX_00, 4 , &mountMultiplierPlus[0 ]) == ICM_20948_Stat_Ok);
200204 success &= (myICM.writeDMPmems (CPASS_MTX_01, 4 , &mountMultiplierZero[0 ]) == ICM_20948_Stat_Ok);
@@ -225,7 +229,7 @@ void setup() {
225229 // 10=102.2727Hz sample rate, ... etc.
226230 // @param[in] gyro_level 0=250 dps, 1=500 dps, 2=1000 dps, 3=2000 dps
227231 success &= (myICM.setGyroSF (4 , 3 ) == ICM_20948_Stat_Ok); // 0 = 225Hz (see above), 3 = 2000dps (see above)
228-
232+
229233 // Configure the Gyro full scale
230234 // 2000dps : 2^28
231235 // 1000dps : 2^27
@@ -238,17 +242,17 @@ void setup() {
238242 // const unsigned char accelOnlyGain[4] = {0x03, 0xA4, 0x92, 0x49}; // 56Hz
239243 const unsigned char accelOnlyGain[4 ] = {0x00 , 0xE8 , 0xBA , 0x2E }; // InvenSense Nucleo example uses 225Hz
240244 success &= (myICM.writeDMPmems (ACCEL_ONLY_GAIN, 4 , &accelOnlyGain[0 ]) == ICM_20948_Stat_Ok);
241-
245+
242246 // Configure the Accel Alpha Var: 1026019965 (225Hz) 977872018 (112Hz) 882002213 (56Hz)
243247 // const unsigned char accelAlphaVar[4] = {0x34, 0x92, 0x49, 0x25}; // 56Hz
244248 const unsigned char accelAlphaVar[4 ] = {0x3D , 0x27 , 0xD2 , 0x7D }; // 225Hz
245249 success &= (myICM.writeDMPmems (ACCEL_ALPHA_VAR, 4 , &accelAlphaVar[0 ]) == ICM_20948_Stat_Ok);
246-
250+
247251 // Configure the Accel A Var: 47721859 (225Hz) 95869806 (112Hz) 191739611 (56Hz)
248252 // const unsigned char accelAVar[4] = {0x0B, 0x6D, 0xB6, 0xDB}; // 56Hz
249253 const unsigned char accelAVar[4 ] = {0x02 , 0xD8 , 0x2D , 0x83 }; // 225Hz
250254 success &= (myICM.writeDMPmems (ACCEL_A_VAR, 4 , &accelAVar[0 ]) == ICM_20948_Stat_Ok);
251-
255+
252256 // Configure the Accel Cal Rate
253257 const unsigned char accelCalRate[4 ] = {0x00 , 0x00 }; // Value taken from InvenSense Nucleo example
254258 success &= (myICM.writeDMPmems (ACCEL_CAL_RATE, 2 , &accelCalRate[0 ]) == ICM_20948_Stat_Ok);
@@ -257,7 +261,7 @@ void setup() {
257261 // in startupMagnetometer. We need to set CPASS_TIME_BUFFER to 100 too.
258262 const unsigned char compassRate[2 ] = {0x00 , 0x64 }; // 100Hz
259263 success &= (myICM.writeDMPmems (CPASS_TIME_BUFFER, 2 , &compassRate[0 ]) == ICM_20948_Stat_Ok);
260-
264+
261265 // Enable DMP interrupt
262266 // This would be the most efficient way of getting the DMP data, instead of polling the FIFO
263267 // success &= (myICM.intEnableDMP(true) == ICM_20948_Stat_Ok);
@@ -310,7 +314,7 @@ void setup() {
310314 success &= (myICM.resetFIFO () == ICM_20948_Stat_Ok);
311315
312316 // Check success
313- if ( success )
317+ if ( success)
314318 {
315319 SERIAL_PORT.println (F (" DMP enabled!" ));
316320 }
@@ -335,15 +339,15 @@ void loop()
335339 icm_20948_DMP_data_t data;
336340 myICM.readDMPdataFromFIFO (&data);
337341
338- if (( myICM.status == ICM_20948_Stat_Ok ) || ( myICM.status == ICM_20948_Stat_FIFOMoreDataAvail )) // Was valid data available?
342+ if (( myICM.status == ICM_20948_Stat_Ok) || (myICM.status == ICM_20948_Stat_FIFOMoreDataAvail)) // Was valid data available?
339343 {
340344 // SERIAL_PORT.print(F("Received data! Header: 0x")); // Print the header in HEX so we can see what data is arriving in the FIFO
341345 // if ( data.header < 0x1000) SERIAL_PORT.print( "0" ); // Pad the zeros
342346 // if ( data.header < 0x100) SERIAL_PORT.print( "0" );
343347 // if ( data.header < 0x10) SERIAL_PORT.print( "0" );
344348 // SERIAL_PORT.println( data.header, HEX );
345349
346- if ( (data.header & DMP_header_bitmap_Quat6) > 0 ) // Check for GRV data (Quat6)
350+ if ((data.header & DMP_header_bitmap_Quat6) > 0 ) // Check for GRV data (Quat6)
347351 {
348352 // Q0 value is computed from this equation: Q0^2 + Q1^2 + Q2^2 + Q3^2 = 1.
349353 // In case of drift, the sum will not add to 1, therefore, quaternion data need to be corrected with right bias values.
@@ -355,7 +359,7 @@ void loop()
355359 double q1 = ((double )data.Quat6 .Data .Q1 ) / 1073741824.0 ; // Convert to double. Divide by 2^30
356360 double q2 = ((double )data.Quat6 .Data .Q2 ) / 1073741824.0 ; // Convert to double. Divide by 2^30
357361 double q3 = ((double )data.Quat6 .Data .Q3 ) / 1073741824.0 ; // Convert to double. Divide by 2^30
358-
362+
359363 SERIAL_PORT.print (F (" Q1:" ));
360364 SERIAL_PORT.print (q1, 3 );
361365 SERIAL_PORT.print (F (" Q2:" ));
@@ -364,12 +368,12 @@ void loop()
364368 SERIAL_PORT.println (q3, 3 );
365369 }
366370
367- if ( (data.header & DMP_header_bitmap_Accel) > 0 ) // Check for Accel
371+ if ((data.header & DMP_header_bitmap_Accel) > 0 ) // Check for Accel
368372 {
369373 float acc_x = (float )data.Raw_Accel .Data .X ; // Extract the raw accelerometer data
370- float acc_y = (float )data.Raw_Accel .Data .Y ;
371- float acc_z = (float )data.Raw_Accel .Data .Z ;
372-
374+ float acc_y = (float )data.Raw_Accel .Data .Y ;
375+ float acc_z = (float )data.Raw_Accel .Data .Z ;
376+
373377 SERIAL_PORT.print (F (" Accel: X:" ));
374378 SERIAL_PORT.print (acc_x);
375379 SERIAL_PORT.print (F (" Y:" ));
@@ -378,37 +382,36 @@ void loop()
378382 SERIAL_PORT.println (acc_z);
379383 }
380384
381- // if ( (data.header & DMP_header_bitmap_Gyro) > 0 ) // Check for Gyro
382- // {
383- // float x = (float)data.Raw_Gyro.Data.X; // Extract the raw gyro data
384- // float y = (float)data.Raw_Gyro.Data.Y;
385- // float z = (float)data.Raw_Gyro.Data.Z;
386- //
387- // SERIAL_PORT.print(F("Gyro: X:"));
388- // SERIAL_PORT.print(x);
389- // SERIAL_PORT.print(F(" Y:"));
390- // SERIAL_PORT.print(y);
391- // SERIAL_PORT.print(F(" Z:"));
392- // SERIAL_PORT.println(z);
393- // }
394- //
395- // if ( (data.header & DMP_header_bitmap_Compass) > 0 ) // Check for Compass
396- // {
397- // float x = (float)data.Compass.Data.X; // Extract the compass data
398- // float y = (float)data.Compass.Data.Y;
399- // float z = (float)data.Compass.Data.Z;
400- //
401- // SERIAL_PORT.print(F("Compass: X:"));
402- // SERIAL_PORT.print(x);
403- // SERIAL_PORT.print(F(" Y:"));
404- // SERIAL_PORT.print(y);
405- // SERIAL_PORT.print(F(" Z:"));
406- // SERIAL_PORT.println(z);
407- // }
408-
385+ // if ( (data.header & DMP_header_bitmap_Gyro) > 0 ) // Check for Gyro
386+ // {
387+ // float x = (float)data.Raw_Gyro.Data.X; // Extract the raw gyro data
388+ // float y = (float)data.Raw_Gyro.Data.Y;
389+ // float z = (float)data.Raw_Gyro.Data.Z;
390+ //
391+ // SERIAL_PORT.print(F("Gyro: X:"));
392+ // SERIAL_PORT.print(x);
393+ // SERIAL_PORT.print(F(" Y:"));
394+ // SERIAL_PORT.print(y);
395+ // SERIAL_PORT.print(F(" Z:"));
396+ // SERIAL_PORT.println(z);
397+ // }
398+ //
399+ // if ( (data.header & DMP_header_bitmap_Compass) > 0 ) // Check for Compass
400+ // {
401+ // float x = (float)data.Compass.Data.X; // Extract the compass data
402+ // float y = (float)data.Compass.Data.Y;
403+ // float z = (float)data.Compass.Data.Z;
404+ //
405+ // SERIAL_PORT.print(F("Compass: X:"));
406+ // SERIAL_PORT.print(x);
407+ // SERIAL_PORT.print(F(" Y:"));
408+ // SERIAL_PORT.print(y);
409+ // SERIAL_PORT.print(F(" Z:"));
410+ // SERIAL_PORT.println(z);
411+ // }
409412 }
410413
411- if ( myICM.status != ICM_20948_Stat_FIFOMoreDataAvail ) // If more data is available then we should read it right away - and not delay
414+ if (myICM.status != ICM_20948_Stat_FIFOMoreDataAvail) // If more data is available then we should read it right away - and not delay
412415 {
413416 delay (1 ); // Keep this short!
414417 }
0 commit comments