Skip to content

Commit d8661e6

Browse files
committed
Finished examples
1 parent 308debf commit d8661e6

File tree

5 files changed

+309
-655
lines changed

5 files changed

+309
-655
lines changed

examples/Arduino/Example1_Basics/Example1_Basics.ino

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,16 @@
1-
#include "ICM_20948.h"
1+
/****************************************************************
2+
* Example1_Basics.ino
3+
* ICM 20948 Arduino Library Demo
4+
* Use the default configuration to stream 9-axis IMU data
5+
* Owen Lyke @ SparkFun Electronics
6+
* Original Creation Date: April 17 2019
7+
*
8+
* This code is beerware; if you see me (or any other SparkFun employee) at the
9+
* local, and you've found our code helpful, please buy us a round!
10+
*
11+
* Distributed as-is; no warranty is given.
12+
***************************************************************/
13+
#include "ICM_20948.h" // Click here to get the library: http://librarymanager/All#SparkFun_ICM_20948_IMU
214

315
//#define USE_SPI // Uncomment this to use SPI
416

@@ -22,14 +34,14 @@
2234
void setup() {
2335

2436
SERIAL_PORT.begin(115200);
25-
while(!SERIAL_PORT){}; // NOTE: make sure while(!SERIAL_PORT) does not accidentally call Wire.begin a bunch of times
26-
37+
while(!SERIAL_PORT){};
38+
2739
bool initialized = false;
2840
while( !initialized ){
2941

3042
#ifdef USE_SPI
31-
SPI_PORT.begin( CS_PIN, SPI_PORT );
32-
myICM.begin();
43+
SPI_PORT.begin();
44+
myICM.begin( CS_PIN, SPI_PORT );
3345
#else
3446
WIRE_PORT.begin();
3547
WIRE_PORT.setClock(400000);

examples/Arduino/Example2_Advanced/Example2_Advanced.ino

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,16 @@
1-
#include "ICM_20948.h"
1+
/****************************************************************
2+
* Example2_Advanced.ino
3+
* ICM 20948 Arduino Library Demo
4+
* Shows how to use granular configuration of the ICM 20948
5+
* Owen Lyke @ SparkFun Electronics
6+
* Original Creation Date: April 17 2019
7+
*
8+
* This code is beerware; if you see me (or any other SparkFun employee) at the
9+
* local, and you've found our code helpful, please buy us a round!
10+
*
11+
* Distributed as-is; no warranty is given.
12+
***************************************************************/
13+
#include "ICM_20948.h" // Click here to get the library: http://librarymanager/All#SparkFun_ICM_20948_IMU
214

315
//#define USE_SPI // Uncomment this to use SPI
416

@@ -22,14 +34,14 @@
2234
void setup() {
2335

2436
SERIAL_PORT.begin(115200);
25-
while(!SERIAL_PORT){}; // NOTE: make sure while(!SERIAL_PORT) does not accidentally call Wire.begin a bunch of times
26-
37+
while(!SERIAL_PORT){};
38+
2739
bool initialized = false;
2840
while( !initialized ){
2941

3042
#ifdef USE_SPI
31-
SPI_PORT.begin( CS_PIN, SPI_PORT );
32-
myICM.begin();
43+
SPI_PORT.begin();
44+
myICM.begin( CS_PIN, SPI_PORT );
3345
#else
3446
WIRE_PORT.begin();
3547
WIRE_PORT.setClock(400000);
Lines changed: 275 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,275 @@
1+
/****************************************************************
2+
* Example999_Portable.ino
3+
* ICM 20948 Arduino Library Demo
4+
* Uses underlying portable C skeleton with user-defined read/write functions
5+
* Owen Lyke @ SparkFun Electronics
6+
* Original Creation Date: April 17 2019
7+
*
8+
* This code is beerware; if you see me (or any other SparkFun employee) at the
9+
* local, and you've found our code helpful, please buy us a round!
10+
*
11+
* Distributed as-is; no warranty is given.
12+
***************************************************************/
13+
#include "ICM_20948.h" // Click here to get the library: http://librarymanager/All#SparkFun_ICM_20948_IMU
14+
15+
#define SERIAL_PORT Serial
16+
17+
//#define USE_SPI // uncomment to use SPI instead
18+
19+
#ifdef USE_SPI
20+
#define SPI_PORT SPI
21+
#define CS_PIN 2
22+
#define SPI_CLK 1000000
23+
SPISettings mySettings(SPI_CLK, MSBFIRST, SPI_MODE3);
24+
#else
25+
#define WIRE_PORT Wire
26+
#define I2C_ADDR ICM_20948_I2C_ADDR_AD1
27+
#endif
28+
29+
30+
// These are the interface functions that you would define for your system. They can use either I2C or SPI,
31+
// or really **any** protocol as long as it successfully reads / writes the desired data into the ICM in the end
32+
#ifdef USE_SPI
33+
ICM_20948_Status_e my_write_spi(uint8_t reg, uint8_t* data, uint32_t len, void* user);
34+
ICM_20948_Status_e my_read_spi(uint8_t reg, uint8_t* buff, uint32_t len, void* user);
35+
#else
36+
ICM_20948_Status_e my_write_i2c(uint8_t reg, uint8_t* data, uint32_t len, void* user);
37+
ICM_20948_Status_e my_read_i2c(uint8_t reg, uint8_t* buff, uint32_t len, void* user);
38+
#endif
39+
40+
// You declare a "Serial Interface" (serif) type and give it the pointers to your interface functions
41+
#ifdef USE_SPI
42+
const ICM_20948_Serif_t mySerif = {
43+
my_write_spi, // write
44+
my_read_spi, // read
45+
NULL, // this pointer is passed into your functions when they are called.
46+
};
47+
#else
48+
const ICM_20948_Serif_t mySerif = {
49+
my_write_i2c, // write
50+
my_read_i2c, // read
51+
NULL,
52+
};
53+
#endif
54+
55+
// Now declare the structure that represents the ICM.
56+
ICM_20948_Device_t myICM;
57+
58+
void setup() {
59+
60+
// Perform platform initialization
61+
Serial.begin(115200);
62+
63+
#ifdef USE_SPI
64+
SPI_PORT.begin();
65+
pinMode(CS_PIN, OUTPUT);
66+
digitalWrite(CS_PIN, HIGH);
67+
// Aha! The SPI initialization monster bytes again! Let's send one byte out to 'set' the pins into a good starting state
68+
SPI_PORT.beginTransaction(mySettings);
69+
SPI_PORT.transfer( 0x00 );
70+
SPI_PORT.endTransaction();
71+
#else
72+
WIRE_PORT.begin();
73+
WIRE_PORT.setClock(400000);
74+
#endif
75+
76+
// Link the serif
77+
ICM_20948_link_serif(&myICM, &mySerif);
78+
79+
while(ICM_20948_check_id( &myICM ) != ICM_20948_Stat_Ok){
80+
Serial.println("whoami does not match. Halting...");
81+
delay(1000);
82+
}
83+
84+
ICM_20948_Status_e stat = ICM_20948_Stat_Err;
85+
uint8_t whoami = 0x00;
86+
while( (stat != ICM_20948_Stat_Ok) || (whoami != ICM_20948_WHOAMI) ) {
87+
whoami = 0x00;
88+
stat = ICM_20948_get_who_am_i(&myICM, &whoami);
89+
Serial.print("whoami does not match (0x");
90+
Serial.print(whoami, HEX);
91+
Serial.print("). Halting...");
92+
Serial.println();
93+
delay(1000);
94+
}
95+
96+
// Here we are doing a SW reset to make sure the device starts in a known state
97+
ICM_20948_sw_reset( &myICM );
98+
delay(250);
99+
100+
// Set Gyro and Accelerometer to a particular sample mode
101+
ICM_20948_set_sample_mode( &myICM, (ICM_20948_InternalSensorID_bm)(ICM_20948_Internal_Acc | ICM_20948_Internal_Gyr), ICM_20948_Sample_Mode_Continuous ); // optiona: ICM_20948_Sample_Mode_Continuous. ICM_20948_Sample_Mode_Cycled
102+
103+
// Set full scale ranges for both acc and gyr
104+
ICM_20948_fss_t myfss;
105+
myfss.a = gpm2; // (ICM_20948_ACCEL_CONFIG_FS_SEL_e)
106+
myfss.g = dps250; // (ICM_20948_GYRO_CONFIG_1_FS_SEL_e)
107+
ICM_20948_set_full_scale( &myICM, (ICM_20948_InternalSensorID_bm)(ICM_20948_Internal_Acc | ICM_20948_Internal_Gyr), myfss );
108+
109+
// Set up DLPF configuration
110+
ICM_20948_dlpcfg_t myDLPcfg;
111+
myDLPcfg.a = acc_d473bw_n499bw;
112+
myDLPcfg.g = gyr_d361bw4_n376bw5;
113+
ICM_20948_set_dlpf_cfg ( &myICM, (ICM_20948_InternalSensorID_bm)(ICM_20948_Internal_Acc | ICM_20948_Internal_Gyr), myDLPcfg );
114+
115+
// Choose whether or not to use DLPF
116+
ICM_20948_enable_dlpf ( &myICM, ICM_20948_Internal_Acc, false );
117+
ICM_20948_enable_dlpf ( &myICM, ICM_20948_Internal_Gyr, false );
118+
119+
120+
// Now wake the sensor up
121+
ICM_20948_sleep ( &myICM, false );
122+
ICM_20948_low_power ( &myICM, false );
123+
124+
}
125+
126+
void loop() {
127+
delay(1000);
128+
129+
ICM_20948_AGMT_t agmt = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0}};
130+
if(ICM_20948_get_agmt( &myICM, &agmt ) == ICM_20948_Stat_Ok){
131+
printRawAGMT( agmt );
132+
}else{
133+
Serial.println("Uh oh");
134+
}
135+
}
136+
137+
138+
///////////////////////////////////////////////////////////////
139+
/* Here's where you actually define your interface functions */
140+
///////////////////////////////////////////////////////////////
141+
142+
#ifdef USE_SPI
143+
ICM_20948_Status_e my_write_spi(uint8_t reg, uint8_t* data, uint32_t len, void* user){
144+
digitalWrite(CS_PIN, LOW);
145+
delayMicroseconds(5);
146+
SPI_PORT.beginTransaction(mySettings);
147+
SPI_PORT.transfer( ((reg & 0x7F) | 0x00) );
148+
for(uint32_t indi = 0; indi < len; indi++){
149+
SPI_PORT.transfer(*(data + indi));
150+
}
151+
SPI_PORT.endTransaction();
152+
delayMicroseconds(5);
153+
digitalWrite(CS_PIN, HIGH);
154+
155+
return ICM_20948_Stat_Ok;
156+
}
157+
158+
ICM_20948_Status_e my_read_spi(uint8_t reg, uint8_t* buff, uint32_t len, void* user){
159+
digitalWrite(CS_PIN, LOW);
160+
delayMicroseconds(5);
161+
SPI_PORT.beginTransaction(mySettings);
162+
SPI_PORT.transfer( ((reg & 0x7F) | 0x80) );
163+
for(uint32_t indi = 0; indi < len; indi++){
164+
*(buff + indi) = SPI_PORT.transfer(0x00);
165+
}
166+
SPI_PORT.endTransaction();
167+
delayMicroseconds(5);
168+
digitalWrite(CS_PIN, HIGH);
169+
170+
return ICM_20948_Stat_Ok;
171+
}
172+
173+
#else
174+
175+
ICM_20948_Status_e my_write_i2c(uint8_t reg, uint8_t* data, uint32_t len, void* user){
176+
WIRE_PORT.beginTransmission(I2C_ADDR);
177+
WIRE_PORT.write(reg);
178+
WIRE_PORT.write(data, len);
179+
WIRE_PORT.endTransmission();
180+
181+
return ICM_20948_Stat_Ok;
182+
}
183+
184+
ICM_20948_Status_e my_read_i2c(uint8_t reg, uint8_t* buff, uint32_t len, void* user){
185+
WIRE_PORT.beginTransmission(I2C_ADDR);
186+
WIRE_PORT.write(reg);
187+
WIRE_PORT.endTransmission(false); // Send repeated start
188+
189+
uint32_t num_received = WIRE_PORT.requestFrom(I2C_ADDR, len);
190+
if(num_received == len){
191+
for(uint32_t i = 0; i < len; i++){
192+
buff[i] = WIRE_PORT.read();
193+
}
194+
}
195+
WIRE_PORT.endTransmission();
196+
197+
return ICM_20948_Stat_Ok;
198+
}
199+
200+
#endif
201+
202+
203+
204+
205+
// Some helper functions
206+
207+
void printPaddedInt16b( int16_t val ){
208+
if(val > 0){
209+
SERIAL_PORT.print(" ");
210+
if(val < 10000){ SERIAL_PORT.print("0"); }
211+
if(val < 1000 ){ SERIAL_PORT.print("0"); }
212+
if(val < 100 ){ SERIAL_PORT.print("0"); }
213+
if(val < 10 ){ SERIAL_PORT.print("0"); }
214+
}else{
215+
SERIAL_PORT.print("-");
216+
if(abs(val) < 10000){ SERIAL_PORT.print("0"); }
217+
if(abs(val) < 1000 ){ SERIAL_PORT.print("0"); }
218+
if(abs(val) < 100 ){ SERIAL_PORT.print("0"); }
219+
if(abs(val) < 10 ){ SERIAL_PORT.print("0"); }
220+
}
221+
SERIAL_PORT.print(abs(val));
222+
}
223+
224+
void printRawAGMT( ICM_20948_AGMT_t agmt){
225+
SERIAL_PORT.print("RAW. Acc [ ");
226+
printPaddedInt16b( agmt.acc.axes.x );
227+
SERIAL_PORT.print(", ");
228+
printPaddedInt16b( agmt.acc.axes.y );
229+
SERIAL_PORT.print(", ");
230+
printPaddedInt16b( agmt.acc.axes.z );
231+
SERIAL_PORT.print(" ], Gyr [ ");
232+
printPaddedInt16b( agmt.gyr.axes.x );
233+
SERIAL_PORT.print(", ");
234+
printPaddedInt16b( agmt.gyr.axes.y );
235+
SERIAL_PORT.print(", ");
236+
printPaddedInt16b( agmt.gyr.axes.z );
237+
SERIAL_PORT.print(" ], Mag [ ");
238+
printPaddedInt16b( agmt.mag.axes.x );
239+
SERIAL_PORT.print(", ");
240+
printPaddedInt16b( agmt.mag.axes.y );
241+
SERIAL_PORT.print(", ");
242+
printPaddedInt16b( agmt.mag.axes.z );
243+
SERIAL_PORT.print(" ], Tmp [ ");
244+
printPaddedInt16b( agmt.tmp.val );
245+
SERIAL_PORT.print(" ]");
246+
SERIAL_PORT.println();
247+
}
248+
249+
float getAccMG( int16_t raw, uint8_t fss ){
250+
switch(fss){
251+
case 0 : return (((float)raw)/16.384); break;
252+
case 1 : return (((float)raw)/8.192); break;
253+
case 2 : return (((float)raw)/4.096); break;
254+
case 3 : return (((float)raw)/2.048); break;
255+
default : return 0; break;
256+
}
257+
}
258+
259+
float getGyrDPS( int16_t raw, uint8_t fss ){
260+
switch(fss){
261+
case 0 : return (((float)raw)/131); break;
262+
case 1 : return (((float)raw)/65.5); break;
263+
case 2 : return (((float)raw)/32.8); break;
264+
case 3 : return (((float)raw)/16.4); break;
265+
default : return 0; break;
266+
}
267+
}
268+
269+
float getMagUT( int16_t raw ){
270+
return (((float)raw)*0.15);
271+
}
272+
273+
float getTmpC( int16_t raw ){
274+
return (((float)raw)/333.87);
275+
}

0 commit comments

Comments
 (0)