Skip to content

Commit cd55844

Browse files
committed
First version of ICM42670P Arduino library
3 sketches available: Polling_I2C, Polling_SPI, FIFO_Interrupt_SPI
1 parent 61347ed commit cd55844

23 files changed

+7755
-1
lines changed

LICENSE

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
Copyright (c) 2022 InvenSense, Inc All rights reserved.
2+
3+
This software, related documentation and any modifications thereto (collectively "Software") is subject
4+
to InvenSense, Inc and its licencors' intellectual property rights under U.S. and international copyright
5+
and other intellectual property rights laws.
6+
7+
InvenSense, Inc and its licencors retain all intellectual property and proprietary rights in and to the Software
8+
and any use, reproduction, disclosure or distribution of the Software without an express license agreement
9+
from InvenSense, Inc is strictly prohibited.
10+
11+
EXCEPT AS OTHERWISE PROVIDED IN A LICENSE AGREEMENT BETWEEN THE PARTIES, THE SOFTWARE IS
12+
PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
13+
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
14+
EXCEPT AS OTHERWISE PROVIDED IN A LICENSE AGREEMENT BETWEEN THE PARTIES, IN NO EVENT SHALL
15+
InvenSense, Inc BE LIABLE FOR ANY DIRECT, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY
16+
DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
17+
NEGLIGENCE OR OTHER TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
18+
OF THE SOFTWARE.

README.md

Lines changed: 214 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,214 @@
1-
# sweng.ICM42670P
1+
![TDKInvensense](doc/pictures/TDKInvensense.jpg)
2+
3+
# ICM42670P Arduino library
4+
This arduino library for the [TDK/Invensense ICM42670P High Performance 6-Axis MotionTracking<sup>(TM)</sup> IMU](https://invensense.tdk.com/products/motion-tracking/6-axis/icm-42670-p).
5+
The ICM-42670-P is a high performance 6-axis MEMS MotionTracking device that combines a 3-axis gyroscope and a 3-axis accelerometer. It has a configurable host interface that supports I3C<sup>SM</sup>, I2C, and SPI serial communication, features up to 2.25 Kbytes FIFO and 2 programmable interrupts with ultra-low-power wake-on-motion support to minimize system power consumption.
6+
This library supports both I2C and SPI commmunication with the ICM42670P.
7+
8+
# Software setup
9+
Use Arduino Library manager to find and install the ICM42670P library.
10+
11+
# Hardware setup
12+
There is currenlty no Arduino shield for the ICM42670P.
13+
The wiring must be done manually between the Arduino motherboard and the ICM42670P daughter board.
14+
The below wiring description is given for an Arduino Zero board, it depends on the interface to be used:
15+
* I2C
16+
17+
|Arduino Zero|ICM42670P daughter board|
18+
| --- | --- |
19+
| 3V3 | CN4.9 & CN5.10 |
20+
| GND | CN5.9 |
21+
| SDA | CN5.4 |
22+
| SCL | CN5.6 |
23+
24+
* SPI
25+
26+
|Arduino Zero|ICM42670P daughter board|
27+
| --- | --- |
28+
| 3V3 | CN4.9 & CN5.10 |
29+
| GND | CN5.9 |
30+
| MISO=SPI.1 | CN4.7 |
31+
| MOSI=SPI.4 | CN5.4 |
32+
| SCK=SPI.3 | CN5.6 |
33+
| CS=DIG.8 | CN5.8 |
34+
35+
Note: SPI Chip Select can be mapped on any free digital IO, updating the sketches accordingly
36+
37+
* Interrupt
38+
39+
|Arduino Zero|ICM42670P daughter board|
40+
| --- | --- |
41+
| DIG.2 | CN4.1 |
42+
43+
Note: Interrupt pin can be mapped on any free interruptable IO, updating the sketches accordingly
44+
45+
## Orientation of axes
46+
47+
The diagram below shows the orientation of the axes of sensitivity and the polarity of rotation. Note the pin 1 identifier (•) in the
48+
figure.
49+
50+
![Orientation of Axes](doc/pictures/OrientationOfAxes.jpg)
51+
52+
# Library API
53+
54+
## Create ICM42670P instance
55+
56+
**ICM42670P(TwoWire &i2c,bool lsb)**
57+
Create an instance of the ICM42670P that will be accessed using the specified I2C. The LSB of the I2C address can be set to 0 or 1.
58+
59+
```C++
60+
ICM42670P IMU(Wire,0);
61+
```
62+
63+
**ICM42670P(SPIClass &spi,uint8_t cs_id)**
64+
Create an instance of the ICM42670P that will be accessed using the specified SPI. The IO number to be used as chip select must be specified.
65+
66+
```C++
67+
ICM42670P IMU(SPI,10);
68+
```
69+
70+
**/!\ This library does NOT support multiple instances of ICM42670P.**
71+
72+
73+
## Initialize the ICM42670P
74+
Call the begin method to execute the ICM42670P initialization routine.
75+
76+
**int begin()**
77+
78+
Initializes all the required parameters in order to communicate and use the ICM42670P.
79+
80+
```C++
81+
IMU.begin();
82+
```
83+
84+
## Log sensor data
85+
86+
**int startAccel(uint16_t odr, uint16_t fsr)**
87+
88+
This method starts logging with the accelerometer, using the specified full scale range and output data rate.
89+
Supported ODR are: 12, 25, 50, 100, 200, 400, 800, 1600 Hz (any other value defaults to 100 Hz).
90+
Supported full scale ranges are: 2, 4, 8, 16 G (any other value defaults to 16 G).
91+
92+
```C++
93+
IMU.startAccel(100,16);
94+
```
95+
96+
**int startGyro(uint16_t odr, uint16_t fsr)**
97+
98+
This method starts logging with the gyroscope, using the specified full scale range and output data rate.
99+
Supported ODR are: 12, 25, 50, 100, 200, 400, 800, 1600 Hz (any other value defaults to 100 Hz).
100+
Supported full scale ranges are: 250, 500, 1000, 2000 dps (any other value defaults to 2000 dps).
101+
102+
```C++
103+
IMU.startGyro(100,2000);
104+
```
105+
106+
**int getDataFromRegisters(inv_imu_sensor_event_t&ast; evt)**
107+
108+
This method reads the ICM42670P sensor data from registers and fill the provided event structure with sensor raw data.
109+
Raw data can be translated to International System using the configured FSR for each sensor. Temperature in Degrees Centigrade = (TEMP_DATA / 128) + 25
110+
111+
```C++
112+
inv_imu_sensor_event_t event;
113+
IMU.getDataFromRegisters(&event);
114+
Serial.print("Accel X = ");
115+
Serial.println(imu_event.accel[0]);
116+
Serial.print("Accel Y = ");
117+
Serial.print(imu_event.accel[1]);
118+
Serial.print("Accel Z = ");
119+
Serial.print(imu_event.accel[2]);
120+
Serial.print("Gyro X = ");
121+
Serial.print(imu_event.gyro[0]);
122+
Serial.print("Gyro Y = ");
123+
Serial.print(imu_event.gyro[1]);
124+
Serial.print("Gyro Z = ");
125+
Serial.print(imu_event.gyro[2]);
126+
Serial.print("Temperature = ");
127+
Serial.println(imu_event.temperature);
128+
```
129+
130+
**int enableFifoInterrupt(uint8_t intpin, ICM42670P_irq_handler handler, uint8_t fifo_watermark)**
131+
132+
This method initializes the fifo and the interrupt of the ICM42670P. The interrupt is triggered each time there is enough samples in the fifo (as specified by fifo_watermark), and the provided handler is called.
133+
Any interuptable pin of the Arduino can be used for intpin.
134+
135+
```C++
136+
uint8_t irq_received = 0;
137+
138+
void irq_handler(void)
139+
{
140+
irq_received = 1;
141+
}
142+
...
143+
144+
// Enable interrupt on pin 2
145+
IMU.enableFifoInterrupt(2,irq_handler);
146+
```
147+
148+
**int getDataFromFifo(ICM42670P_sensor_event_cb event_cb)**
149+
150+
This method reads the ICM42670P sensor data samples stored in the FIFO and call the provided event handler with the sample event as parameter.
151+
Raw data can be translated to International System using the configured FSR for each sensor. Temperature in Degrees Centigrade = (TEMP_DATA / 128) + 25
152+
153+
```C++
154+
void event_cb(inv_imu_sensor_event_t *evt)
155+
{
156+
Serial.print(evt->accel[0]);
157+
Serial.print(",");
158+
Serial.print(evt->accel[1]);
159+
Serial.print(",");
160+
Serial.print(evt->accel[2]);
161+
Serial.print(",");
162+
Serial.print(evt->gyro[0]);
163+
Serial.print(",");
164+
Serial.print(evt->gyro[1]);
165+
Serial.print(",");
166+
Serial.print(evt->gyro[2]);
167+
Serial.print(",");
168+
Serial.println(evt->temperature);
169+
}
170+
171+
void loop() {
172+
// Wait for interrupt to read data from fifo
173+
if(irq_received)
174+
{
175+
irq_received = 0;
176+
IMU.getDataFromFifo(event_cb);
177+
}
178+
}
179+
```
180+
181+
**inv_imu_sensor_event_t**
182+
183+
This structure is used by the ICM42670P driver to return raw sensor data. Available data is:
184+
|Field name|description|
185+
| --- | --- |
186+
| sensor_mask | Mask describing available data |
187+
| timestamp_fsync | Timestamp in us |
188+
| accel[3] | 3-axis accel raw data |
189+
| gyro[3] | 3-axis gyro raw data |
190+
| temperature | Temperature raw data (on 1 or 2 bytes) |
191+
| accel_high_res[3] | 3- axis accel lsb in high resolution |
192+
| gyro_high_res[3] | 3- axis gyro LSB in high resolution |
193+
194+
195+
# Available Sketches
196+
197+
**Polling_I2C**
198+
199+
This sketch initializes the ICM42670P with the I2C interface, and starts logging raw sensor data from IMU registers. Sensor data can be monitored on Serial monitor or Serial plotter
200+
201+
**Polling_SPI**
202+
203+
This sketch initializes the ICM42670P with the SPI interface, and starts logging raw sensor data from IMU registers. Sensor data can be monitored on Serial monitor or Serial plotter
204+
205+
**FIFO_Interrupt**
206+
207+
This sketch initializes the ICM42670P with the SPI interface and interrupt PIN2, and starts logging raw sensor data from IMU FIFO. Sensor data can be monitored on Serial monitor or Serial plotter
208+
209+
**IMU data monitoring**
210+
211+
When the ICM42670P IMU is logging, the Accelerometer, Gyroscope and Temperature raw data can be monitored with the Arduino Serial Plotter (Tools->Serial Plotter).
212+
213+
![Serial Plotter](doc/pictures/SerialPlotter.jpg)
214+

doc/DS-000451-ICM-42670-P-v1.0.pdf

1.85 MB
Binary file not shown.

doc/pictures/OrientationOfAxes.jpg

19.8 KB
Loading

doc/pictures/SerialPlotter.jpg

55.3 KB
Loading

doc/pictures/TDKInvensense.jpg

11.8 KB
Loading
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#include "ICM42670P.h"
2+
3+
// Instantiate an ICM42670P with SPI interface and CS on pin 8
4+
ICM42670P IMU(SPI,8);
5+
6+
uint8_t irq_received = 0;
7+
8+
void irq_handler(void) {
9+
irq_received = 1;
10+
}
11+
12+
void event_cb(inv_imu_sensor_event_t *evt) {
13+
// Format data for Serial Plotter
14+
Serial.print(evt->accel[0]);
15+
Serial.print(",");
16+
Serial.print(evt->accel[1]);
17+
Serial.print(",");
18+
Serial.print(evt->accel[2]);
19+
Serial.print(",");
20+
Serial.print(evt->gyro[0]);
21+
Serial.print(",");
22+
Serial.print(evt->gyro[1]);
23+
Serial.print(",");
24+
Serial.print(evt->gyro[2]);
25+
Serial.print(",");
26+
Serial.println(evt->temperature);
27+
}
28+
29+
void setup() {
30+
int ret;
31+
Serial.begin(115200);
32+
while(!Serial) {}
33+
34+
// Initializing the ICM42670P
35+
ret = IMU.begin();
36+
if (ret != 0) {
37+
Serial.print("ICM42670P initialization failed: ");
38+
Serial.println(ret);
39+
while(1);
40+
}
41+
// Enable interrupt on pin 2, Fifo watermark=10
42+
IMU.enableFifoInterrupt(2,irq_handler,10);
43+
// Accel ODR = 100 Hz and Full Scale Range = 16G
44+
IMU.startAccel(100,16);
45+
// Gyro ODR = 100 Hz and Full Scale Range = 2000 dps
46+
IMU.startGyro(100,2000);
47+
// Plotter axis header
48+
Serial.println("AccelX,AccelY,AccelZ,GyroX,GyroY,GyroZ,Temperature");
49+
}
50+
51+
void loop() {
52+
// Wait for interrupt to read data from fifo
53+
if(irq_received) {
54+
irq_received = 0;
55+
IMU.getDataFromFifo(event_cb);
56+
}
57+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#include "ICM42670P.h"
2+
3+
// Instantiate an ICM42670P with LSB address set to 0
4+
ICM42670P IMU(Wire,0);
5+
6+
void setup() {
7+
int ret;
8+
Serial.begin(115200);
9+
while(!Serial) {}
10+
11+
// Initializing the ICM42670P
12+
ret = IMU.begin();
13+
if (ret != 0) {
14+
Serial.print("ICM42670P initialization failed: ");
15+
Serial.println(ret);
16+
while(1);
17+
}
18+
// Accel ODR = 100 Hz and Full Scale Range = 16G
19+
IMU.startAccel(100,16);
20+
// Gyro ODR = 100 Hz and Full Scale Range = 2000 dps
21+
IMU.startGyro(100,2000);
22+
// Plotter axis header
23+
Serial.println("AccelX,AccelY,AccelZ,GyroX,GyroY,GyroZ,Temperature");
24+
}
25+
26+
void loop() {
27+
28+
inv_imu_sensor_event_t imu_event;
29+
30+
// Get last event
31+
IMU.getDataFromRegisters(&imu_event);
32+
33+
// Format data for Serial Plotter
34+
Serial.print(imu_event.accel[0]);
35+
Serial.print(",");
36+
Serial.print(imu_event.accel[1]);
37+
Serial.print(",");
38+
Serial.print(imu_event.accel[2]);
39+
Serial.print(",");
40+
Serial.print(imu_event.gyro[0]);
41+
Serial.print(",");
42+
Serial.print(imu_event.gyro[1]);
43+
Serial.print(",");
44+
Serial.print(imu_event.gyro[2]);
45+
Serial.print(",");
46+
Serial.println(imu_event.temperature);
47+
48+
// Run @ ODR 100Hz
49+
delay(10);
50+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#include "ICM42670P.h"
2+
3+
// Instantiate an ICM42670P with SPI interface and CS on pin 8
4+
ICM42670P IMU(SPI,8);
5+
6+
void setup() {
7+
int ret;
8+
Serial.begin(115200);
9+
while(!Serial) {}
10+
11+
// Initializing the ICM42670P
12+
ret = IMU.begin();
13+
if (ret != 0) {
14+
Serial.print("ICM42670P initialization failed: ");
15+
Serial.println(ret);
16+
while(1);
17+
}
18+
// Accel ODR = 100 Hz and Full Scale Range = 16G
19+
IMU.startAccel(100,16);
20+
// Gyro ODR = 100 Hz and Full Scale Range = 2000 dps
21+
IMU.startGyro(100,2000);
22+
// Plotter axis header
23+
Serial.println("AccelX,AccelY,AccelZ,GyroX,GyroY,GyroZ,Temperature");
24+
}
25+
26+
void loop() {
27+
28+
inv_imu_sensor_event_t imu_event;
29+
30+
// Get last event
31+
IMU.getDataFromRegisters(&imu_event);
32+
33+
// Format data for Serial Plotter
34+
Serial.print(imu_event.accel[0]);
35+
Serial.print(",");
36+
Serial.print(imu_event.accel[1]);
37+
Serial.print(",");
38+
Serial.print(imu_event.accel[2]);
39+
Serial.print(",");
40+
Serial.print(imu_event.gyro[0]);
41+
Serial.print(",");
42+
Serial.print(imu_event.gyro[1]);
43+
Serial.print(",");
44+
Serial.print(imu_event.gyro[2]);
45+
Serial.print(",");
46+
Serial.println(imu_event.temperature);
47+
48+
// Run @ ODR 100Hz
49+
delay(10);
50+
}

0 commit comments

Comments
 (0)