Skip to content

Commit 273ed57

Browse files
authored
Add files via upload
New version of the LSM9DS1 library for the IMU chip. It was tested on a Nano 33 BLE Sense board and should be backwards compatible with V1.01.0. New for all 9 DOF is the possibility: to give it calibration zero offset and slope factors. to change the output unit to set and get the ODR sample rate frequency , to set and get the internal full scale setting of the chip (IFS) giving it more accuracy at the expense of the range. Several fixed values in version 1.01 are replaced by functions that produce the value according to the current chip register setting. As a result there are a lot of new set... and get... functions. Offset and Slope are organised in such way that they can be calibrated separately or together. Their values are independent of the full scale setting or the output unit. Copy their values in a new sketch and it will return calibrated output even when you choose to view it in a different setting. The voids set...Offset and set...Slope are made for calibration purposes only. To store their values from read measurements according to the above features. Perhaps they need a better name to reflect this.
1 parent f7f0af2 commit 273ed57

File tree

8 files changed

+966
-55
lines changed

8 files changed

+966
-55
lines changed

CHANGELOG.txt

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
Arduino_LSM9DS1 ?.?.? - ????.??.??
2+
3+
Arduino_LSM9DS1 1.0.0 - 2019.07.31
4+
5+
* Initial release
6+
7+
Arduino_LSM9DS1 1.1.0 - 2020.02.11
8+
9+
* Added support for FIFO continuous reading of values
10+
11+
Arduino_LSM9DS1 2.0.0 - 2020.05.15
12+
13+
* Offset, Full scale, sample rate on all DOF.
14+
* Calibration parameters integrated

LSM9DS1_V2 notes and manual.txt

+385
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*Test program for Arduino__LSM9DS1 Library version 2.0 extensions
2+
* Written by Femme Verbeek Pijnacker the Netherlands 23 may 2020.
3+
* Run through all the new set and get functions
4+
*/
5+
6+
#include <Arduino_LSM9DS1.h>
7+
8+
void setup() {
9+
Serial.begin(115200);
10+
while(!Serial);
11+
Serial.println();
12+
if (!IMU.begin()) {
13+
Serial.println("Failed to initialize IMU!");
14+
while (1); }
15+
16+
for (int i = 0;i<=3;i++){
17+
if (IMU.setAccelFS(i))
18+
printResult ("Accelleration Full Scale range param = ", i ,IMU.getAccelFS()," g ");
19+
else Serial.println ("failed setting accelleration scale value "); }
20+
21+
for (int i = 0;i<=3;i++){
22+
if (IMU.setGyroFS(i))
23+
printResult ("Gyroscope Full Scale range param = ",i,IMU.getGyroFS()," deg/s ");
24+
else Serial.println ("failed setting gyroscope scale value ");}
25+
26+
for (int i = 0;i<=3;i++){
27+
if (IMU.setMagnetFS(i))
28+
printResult ("magnetic range param = ", i ,IMU.getMagnetFS()," µT ");
29+
else Serial.println ("failed setting magnetic field scale value "); }
30+
31+
for (int i = 0;i<=7;i++){
32+
if (IMU.setAccelODR(i))
33+
{ printResult ("accelleration sample rate param = ", i , IMU.getAccelODR()," Hz ");
34+
// printResult ("Gyroscope sample rate param = ", i , IMU.getGyroODR()," Hz ");
35+
Serial.println(" automatic bandwidth setting (Hz) "+ String (IMU.getAccelBW()));
36+
for (int j = 0;j<=3;j++)
37+
{ IMU.setAccelBW(j); // override automatic bandwith
38+
printResult("Accel bandwidth override ", j ,IMU.getAccelBW(), "Hz " );
39+
}
40+
}
41+
else Serial.println ("failed setting accelleration sample rate ");}
42+
43+
for (int i = 0;i<=7;i++){
44+
if (IMU.setGyroODR(i)){
45+
printResult ("gyroscope sample rate param = ", i , IMU.getGyroODR()," Hz" );
46+
for (int j = 0;j<=3;j++)
47+
{ IMU.setGyroBW(j); // override automatic bandwith
48+
printResult("Gyro bandwidth setting ", j ,IMU.getGyroBW(), "Hz " );
49+
}
50+
}
51+
else Serial.println ("failed setting gyroscope sample rate "); }
52+
53+
for (int i = 0;i<=7;i++){
54+
if (IMU.setMagnetODR(i))
55+
printResult ("magnetic field sample rate param = ", i , IMU.getMagnetODR()," Hz ");
56+
else Serial.println ("failed setting magnetic field sample rate ");}
57+
}
58+
59+
void loop() {
60+
61+
}
62+
63+
void printResult (String msg, int nr,float value, String dimension)
64+
{ Serial.print (msg+String(nr));
65+
// Serial.print (nr);
66+
Serial.print(" setting "+String(value));
67+
// Serial.print(value);
68+
Serial.println(dimension);}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*Example program for Arduino__LSM9DS1 Library version 2.0
2+
* Tested on Arduino Nano 33 BLE SENSE
3+
* Written by Femme Verbeek 15 may 2020.
4+
*
5+
* Measures the gyroscope offset and sets the IMU.gyroOffset parameters for X,Y,Z
6+
* To start the calibration measurement, open the serial monitor.
7+
* For a good result the board must be held still during the calibration measurements
8+
* During the calibration the onboard LED's are blinking
9+
* When finished the program prints the calibration result
10+
* The program pauses till you press enter
11+
* Next the program will continue measuring and print the now calibrated results.
12+
* Best close the serial monitor first, open the serial monitor and send the character from there.
13+
*
14+
* To see a graphic result of the measurements, close the serial monitor when the program pauses,
15+
* open the serial plotter, type any character and press "send".
16+
*/
17+
const int averageNSamples=10; //average output over N measurements
18+
19+
#include <Arduino_LSM9DS1.h>
20+
//unsigned long timer;
21+
void setup()
22+
{ Serial.begin(115200);
23+
while(!Serial);
24+
delay(1);
25+
if (!IMU.begin()) {
26+
Serial.println("Failed to initialize IMU!");
27+
while (1); }
28+
IMU.setGyroODR(4); //Sampling Rate 0:off, 1:10Hz, 2:50Hz, 3:119Hz, 4:238Hz, 5:476Hz, 6:952Hz, 7:NA
29+
IMU.setGyroBW(0); // bandwidth see table 47 datasheet
30+
Serial.print("Gyro ODR "+String( IMU.getGyroODR() ) );
31+
Serial.println(" BW setting "+String( IMU.getGyroBW() ) );
32+
Serial.println("Calibrating. Just a moment. ");
33+
Serial.println("Keep the sensor still as long as the LED's are flashing");
34+
35+
calibrateGyroOffset(12000); // do calibration measurements during 12000 ms.
36+
37+
Serial.println("calibration results");
38+
Serial.print("Content of IMU.gyroOffset : ");
39+
for (int i= 0; i<=2 ; i++) {Serial.print(IMU.gyroOffset[i],6);Serial.print(" ");}
40+
Serial.println();
41+
Serial.println("Press enter to start mesuring");
42+
Serial.println("To see a graph of the measurements, close this serial monitor, open the serial plotter type any character and click the send button");
43+
while (!Serial.available()); // pause the program, enter continues
44+
while (Serial.available()) Serial.read(); // clear the read buffer
45+
Serial.println(" X \t Y \t Z ");
46+
}
47+
48+
// continue doing calibrated measurements, this is best viewed in the serial plotter
49+
void loop()
50+
{ float x, y, z, averX=0, averY=0, averZ=0;
51+
for (int i=1;i<=averageNSamples;i++)
52+
{ while (!IMU.gyroAvailable());
53+
IMU.readGyro(x, y, z);
54+
averX += x; averY += y; averZ += z;
55+
}
56+
Serial.print(String(averX/averageNSamples,6)+'\t');
57+
Serial.print(String(averY/averageNSamples,6)+'\t');
58+
Serial.println(averZ/averageNSamples,6);
59+
}
60+
61+
void calibrateGyroOffset(unsigned int duration){ // don't move the board during calibration
62+
unsigned long count = 0, start = millis();
63+
float x, y, z, addX=0, addY=0, addZ=0 ;
64+
IMU.setGyroOffset(0,0,0); // Offsets must be zero when calibrating
65+
while ((millis()-start) < duration)
66+
{ if (IMU.gyroscopeAvailable())
67+
{ IMU.readGyroscope(x, y, z);
68+
count++;
69+
addX += x; addY += y; addZ += z;
70+
digitalWrite(LED_BUILTIN, (millis()/125)%2); // blink onboard led every 250ms
71+
}
72+
}
73+
IMU.setGyroOffset(addX/count, addY/count, addZ/count); // Store the average measurements as offset
74+
digitalWrite(LED_BUILTIN, 0); // onboard led off
75+
Serial.println("nr of samples "+String(count));
76+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/* Calibrated compass example for the Nano 33 BLE Sense
2+
* You need version 2.0 or higher of the LMS9DS1 library to run this example
3+
*
4+
* The compass must be calibrated for the magnetic disturbance of the environment.
5+
* Calibration starts automaticlly when the serial monitor is opened and stops after a given time.
6+
* Calibration in progress is indicated by the flashing onboard LED.
7+
*
8+
* During calibration the board must be turned slowly over a full 360 deg.
9+
* When finished calibrating the program stores and prints the offset and slope factors.
10+
*
11+
* After pressing "enter" the program continues working as a compass.
12+
*
13+
* Written by Femme Verbeek 2020
14+
* Released to the public domain
15+
*/
16+
17+
#include <Arduino_LSM9DS1.h>
18+
19+
float EarthMagField = 49000; //= nT For local value see https://en.wikipedia.org/wiki/Earth%27s_magnetic_field
20+
int averageCompassByN = 10; //number of samples per compass reading. Higher number = more accurate but slower
21+
int averageCalibrationByN = 10; //goldielocs number too high = fewer measurements in 360deg turn, to low = more noise
22+
int calibrationTime = 20; //s
23+
void setup() {
24+
pinMode(LED_BUILTIN,OUTPUT);
25+
Serial.begin(115200);
26+
while(!Serial); // wait till the serial monitor connects
27+
delay(1);
28+
if (!IMU.begin()) {
29+
Serial.println("Failed to initialize IMU!");
30+
while (1); }
31+
IMU.setMagnetODR(7); // Sample Rate (0..7) corresponds to {0.625,1.25,2.5,5.0,10.0,20.0,40.0,80.0}Hz
32+
IMU.magnetUnit = NANOTESLA; // calibrate in nanotesla as this corresponds to the local field strenth number we found.
33+
Serial.println("Calibrating. Just a moment. ");
34+
Serial.println("Keep the compass sensor horizontal.");
35+
Serial.print("In the next "+String(calibrationTime));
36+
Serial.println(" seconds the compass must be turned slowly over a full 360 degrees!");
37+
38+
calibrateMagnet(calibrationTime*1000);
39+
40+
Serial.println("calibration results");
41+
Serial.print("IMU.magnetOffset[] : ");
42+
for (int i= 0; i<=2 ; i++){ Serial.print(IMU.magnetOffset[i],4);Serial.print(" ");}
43+
Serial.println();
44+
Serial.print("IMU.magnetSlope[] : ");
45+
for (int i= 0; i<=2 ; i++){ Serial.print(IMU.magnetSlope[i],4);Serial.print(" ");}
46+
Serial.println();
47+
Serial.println("Press enter to start the compass");
48+
while (!Serial.available()); // pause the program, enter continues, use the serial plotter to view a graph
49+
while (Serial.available()) Serial.read(); // clear the read buffer
50+
Serial.println("Direction\tFieldStrength\tmagX\tmagY"); // legend for serial plotter
51+
IMU.magnetUnit = MICROTESLA; // Switch to microtesla as this looks better in the graph
52+
53+
}
54+
55+
void loop ()
56+
{ float magY,magX;
57+
doNMeasurements (averageCompassByN,magX,magY,false);
58+
float heading= atan2(magY,magX)*180/PI +180;
59+
float fieldStrength = sqrt(magX*magX +magY * magY);
60+
Serial.print(heading); Serial.print("\t"); Serial.print(fieldStrength);Serial.print("\t");
61+
Serial.print(magX); Serial.print("\t"); Serial.print(magY);Serial.print("\t");
62+
Serial.println();
63+
}
64+
65+
void doNMeasurements(unsigned int N, float& averX, float& averY, boolean showLeds)
66+
{ float x, y, z;
67+
averX=0; averY =0;
68+
for (int i=1;i<=N;i++)
69+
{ digitalWrite(LED_BUILTIN, bitRead(millis(),7)&& showLeds ); // blink onboard led
70+
while (!IMU.magneticFieldAvailable());
71+
IMU.readMagneticField(x, y, z);
72+
averX += x/N;
73+
averY += y/N;
74+
}
75+
}
76+
77+
void calibrateMagnet(unsigned int duration) // measure Offset and Slope of XY
78+
{ float x, y, Xmin, Xmax, Ymin, Ymax ;
79+
IMU.setMagnetOffset(0,0,0); // Offsets must be 0 when calibrating
80+
IMU.setMagnetSlope(1,1,1); // slopes must be 1 when calibrating
81+
doNMeasurements(averageCalibrationByN,Xmin, Ymin, true ); // find some starting values
82+
Xmax = Xmin; Ymax = Ymin;
83+
unsigned long start = millis();
84+
while ((millis()-start) < duration)
85+
{ doNMeasurements(averageCompassByN ,x, y ,true);
86+
Xmax = max (Xmax, x); Xmin = min (Xmin, x);
87+
Ymax = max (Ymax, y); Ymin = min (Ymin, y);
88+
}
89+
IMU.setMagnetOffset( (Xmax+Xmin)/2,(Ymax+Ymin)/2, 0 ) ; // store offset
90+
IMU.setMagnetSlope ( (2*EarthMagField)/(Xmax-Xmin),(2*EarthMagField)/(Ymax-Ymin),1) ; // store slope
91+
// Serial.print("Xmin = ");Serial.print(Xmin); Serial.print(" Xmax = ");Serial.println(Xmax);
92+
// Serial.print("Ymin = ");Serial.print(Ymin); Serial.print(" Ymax = ");Serial.println(Ymax);
93+
}

keywords.txt

+69-3
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,85 @@ IMU KEYWORD1
1414

1515
begin KEYWORD2
1616
end KEYWORD2
17+
setContinuousMode KEYWORD2
18+
setOneShotMode KEYWORD2
1719

1820
readAcceleration KEYWORD2
1921
readGyroscope KEYWORD2
2022
readMagneticField KEYWORD2
21-
gyroscopeAvailable KEYWORD2
23+
24+
readAccel KEYWORD2
25+
readGyro KEYWORD2
26+
readMagnet KEYWORD2
27+
2228
accelerationAvailable KEYWORD2
29+
gyroscopeAvailable KEYWORD2
2330
magneticFieldAvailable KEYWORD2
31+
32+
accelAvailable KEYWORD2
33+
gyroAvailable KEYWORD2
34+
magnetAvailable KEYWORD2
35+
2436
accelerationSampleRate KEYWORD2
2537
gyroscopeSampleRate KEYWORD2
2638
magneticFieldSampleRate KEYWORD2
27-
setContinuousMode KEYWORD2
28-
setOneShotMode KEYWORD2
39+
40+
setAccelerationSampleRate KEYWORD2
41+
setGyroscopeSampleRate KEYWORD2
42+
setMagneticFieldSampleRate KEYWORD2
43+
44+
accelOffset KEYWORD2
45+
gyroOffset KEYWORD2
46+
magnetOffset KEYWORD2
47+
48+
accelScale KEYWORD2
49+
gyroScale KEYWORD2
50+
magnetScale KEYWORD2
51+
52+
accelUnit KEYWORD2
53+
gyroUnit KEYWORD2
54+
magnetUnit KEYWORD2
55+
56+
accelerationFullScale KEYWORD2
57+
gyroscopeFullScale KEYWORD2
58+
magneticFieldFullScale KEYWORD2
59+
60+
setAccelerationFullScale KEYWORD2
61+
setGyroscopeFullScale KEYWORD2
62+
setMagneticFieldFullScale KEYWORD2
63+
64+
getAccelODR KEYWORD2
65+
getGyroODR KEYWORD2
66+
getMagnetODR KEYWORD2
67+
setAccelODR KEYWORD2
68+
setGyroODR KEYWORD2
69+
setMagnetODR KEYWORD2
70+
71+
getAccelFS KEYWORD2
72+
getGyroFS KEYWORD2
73+
getMagnetFS KEYWORD2
74+
setAccelFS KEYWORD2
75+
setGyroFS KEYWORD2
76+
setMagnetFS KEYWORD2
77+
78+
setAccelBW KEYWORD2
79+
getAccelBW KEYWORD2
80+
setGyroBW KEYWORD2
81+
getGyroBW KEYWORD2
82+
83+
readAccel KEYWORD2
84+
readGyro KEYWORD2
85+
readMagnet KEYWORD2
86+
87+
2988

3089
#######################################
3190
# Constants
3291
#######################################
92+
93+
GAUSS LITERAL1
94+
MICROTESLA LITERAL1
95+
GRAVITY LITERAL1
96+
METERPERSECOND2 LITERAL1
97+
DEGREEPERSECOND LITERAL1
98+
RADIANSPERSECOND LITERAL1

0 commit comments

Comments
 (0)