forked from nanoframework/nanoFramework.IoT.Device
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Program.cs
161 lines (147 loc) · 7.22 KB
/
Program.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Device.I2c;
using System.Diagnostics;
using System.Threading;
using Iot.Device.Imu;
using Iot.Device.Magnetometer;
Debug.WriteLine("Hello MPU9250!");
//////////////////////////////////////////////////////////////////////
// when connecting to an ESP32 device, need to configure the I2C GPIOs
// used for the bus
//Configuration.SetPinFunction(21, DeviceFunction.I2C1_DATA);
//Configuration.SetPinFunction(22, DeviceFunction.I2C1_CLOCK);
Debug.WriteLine("This will run the calibration on 1000, comment if you've done it already.");
Debug.WriteLine("Note that you'll be able to copy/paste the data easily from the debug output and create a csv file that you'll be able to exploit in Excel for example.");
MagnetometerCalibrationDeepDive(1000);
MainTest();
void MagnetometerCalibrationDeepDive(int calibrationCount)
{
I2cConnectionSettings mpui2CConnectionSettingmpus = new(1, Mpu9250.DefaultI2cAddress);
using Mpu9250 mpu9250 = new(I2cDevice.Create(mpui2CConnectionSettingmpus));
// In case you have an exception with AK8963. In some configuration AK8963 has its I2C address exposed
// So you can try the following:
// using Mpu9250 mpu9250 = new(I2cDevice.Create(mpui2CConnectionSettingmpus), i2CDeviceAk8963: I2cDevice.Create(new I2cConnectionSettings(1, Ak8963.DefaultI2cAddress)));
mpu9250.MagnetometerOutputBitMode = OutputBitMode.Output16bit;
mpu9250.MagnetometerMeasurementMode = MeasurementMode.ContinuousMeasurement100Hz;
Debug.WriteLine("Please move the magnetometer during calibration");
// First we read the data without calibration at all
Debug.WriteLine("Reading magnetometer data without calibration");
Debug.WriteLine($"X;Y;Z");
for (int i = 0; i < calibrationCount; i++)
{
try
{
var magne = mpu9250.ReadMagnetometerWithoutCorrection();
Debug.WriteLine($"{magne.X};{magne.Y};{magne.Z}");
// 10 ms = 100Hz, so waiting to make sure we have new data
Thread.Sleep(10);
}
catch (TimeoutException)
{
Debug.WriteLine("Error reading");
}
}
Debug.WriteLine("Performing calibration");
// then we calibrate
var magnetoBias = mpu9250.CalibrateMagnetometer(calibrationCount);
Debug.WriteLine("");
Debug.WriteLine("Factory calibration data");
Debug.WriteLine($"X;Y;Z");
Debug.WriteLine($"{magnetoBias.X};{magnetoBias.Y};{magnetoBias.Z}");
Debug.WriteLine("");
Debug.WriteLine("Magnetometer bias calibration data");
Debug.WriteLine($"X;Y;Z");
Debug.WriteLine($"{mpu9250.MagnometerBias.X};{mpu9250.MagnometerBias.Y};{mpu9250.MagnometerBias.Z}");
Debug.WriteLine("");
// Finally we read the data again
Debug.WriteLine("Reading magnetometer data including calibration");
Debug.WriteLine($"X corr;Y corr;Z corr");
for (int i = 0; i < calibrationCount; i++)
{
try
{
var magne = mpu9250.ReadMagnetometer();
Debug.WriteLine($"{magne.X};{magne.Y};{magne.Z}");
// 10 ms = 100Hz, so waiting to make sure we have new data
Thread.Sleep(10);
}
catch (TimeoutException)
{
Debug.WriteLine("Error reading");
}
}
Debug.WriteLine("Calibration deep dive over, file name is mag.csv");
}
void MainTest()
{
I2cConnectionSettings mpui2CConnectionSettingmpus = new(1, Mpu9250.DefaultI2cAddress);
using Mpu9250 mpu9250 = new Mpu9250(I2cDevice.Create(mpui2CConnectionSettingmpus));
Debug.WriteLine($"Check version magnetometer: {mpu9250.GetMagnetometerVersion()}");
Debug.WriteLine(
"Magnetometer calibration is taking couple of seconds, please be patient! Please make sure you are not close to any magnetic field like magnet or phone.");
Debug.WriteLine(
"Please move your sensor as much as possible in all direction in space to get as many points in space as possible");
var mag = mpu9250.CalibrateMagnetometer();
Debug.WriteLine($"Hardware bias multiplicative:");
Debug.WriteLine($"Mag X = {mag.X}");
Debug.WriteLine($"Mag Y = {mag.Y}");
Debug.WriteLine($"Mag Z = {mag.Z}");
Debug.WriteLine($"Calculated corrected bias:");
Debug.WriteLine($"Mag X = {mpu9250.MagnometerBias.X}");
Debug.WriteLine($"Mag Y = {mpu9250.MagnometerBias.Y}");
Debug.WriteLine($"Mag Z = {mpu9250.MagnometerBias.Z}");
var resSelfTest = mpu9250.RunGyroscopeAccelerometerSelfTest();
Debug.WriteLine($"Self test:");
Debug.WriteLine($"Gyro X = {resSelfTest.Gyroscope.X} vs >0.005");
Debug.WriteLine($"Gyro Y = {resSelfTest.Gyroscope.Y} vs >0.005");
Debug.WriteLine($"Gyro Z = {resSelfTest.Gyroscope.Z} vs >0.005");
Debug.WriteLine($"Acc X = {resSelfTest.Accelerometer.X} vs >0.005 & <0.015");
Debug.WriteLine($"Acc Y = {resSelfTest.Accelerometer.Y} vs >0.005 & <0.015");
Debug.WriteLine($"Acc Z = {resSelfTest.Accelerometer.Z} vs >0.005 & <0.015");
Debug.WriteLine("Running Gyroscope and Accelerometer calibration");
mpu9250.CalibrateGyroscopeAccelerometer();
Debug.WriteLine("Calibration results:");
Debug.WriteLine($"Gyro X bias = {mpu9250.GyroscopeBias.X}");
Debug.WriteLine($"Gyro Y bias = {mpu9250.GyroscopeBias.Y}");
Debug.WriteLine($"Gyro Z bias = {mpu9250.GyroscopeBias.Z}");
Debug.WriteLine($"Acc X bias = {mpu9250.AccelerometerBias.X}");
Debug.WriteLine($"Acc Y bias = {mpu9250.AccelerometerBias.Y}");
Debug.WriteLine($"Acc Z bias = {mpu9250.AccelerometerBias.Z}");
mpu9250.GyroscopeBandwidth = GyroscopeBandwidth.Bandwidth0250Hz;
mpu9250.AccelerometerBandwidth = AccelerometerBandwidth.Bandwidth0460Hz;
Debug.WriteLine("This will read 200 positions in a row");
for(int i=0; i<200; i++)
{
var gyro = mpu9250.GetGyroscopeReading();
Debug.WriteLine($"Gyro X = {gyro.X,15}");
Debug.WriteLine($"Gyro Y = {gyro.Y,15}");
Debug.WriteLine($"Gyro Z = {gyro.Z,15}");
var acc = mpu9250.GetAccelerometer();
Debug.WriteLine($"Acc X = {acc.X,15}");
Debug.WriteLine($"Acc Y = {acc.Y,15}");
Debug.WriteLine($"Acc Z = {acc.Z,15}");
Debug.WriteLine($"Temp = {mpu9250.GetTemperature().DegreesCelsius.ToString("0.00")} °C");
var magne = mpu9250.ReadMagnetometer();
Debug.WriteLine($"Mag X = {magne.X,15}");
Debug.WriteLine($"Mag Y = {magne.Y,15}");
Debug.WriteLine($"Mag Z = {magne.Z,15}");
Thread.Sleep(100);
}
// SetWakeOnMotion
mpu9250.SetWakeOnMotion(300, AccelerometerLowPowerFrequency.Frequency0Dot24Hz);
// You'll need to attach the INT pin to a GPIO and read the level. Once going up, you have
// some data and the sensor is awake
// In order to simulate this without a GPIO pin, you will see that the refresh rate is very low
// Setup here at 0.24Hz which means, about every 4 seconds
Debug.WriteLine("This will read 10 positions in a row");
for (int i = 0; i < 10; i++)
{
var acc = mpu9250.GetAccelerometer();
Debug.WriteLine($"Acc X = {acc.X,15}");
Debug.WriteLine($"Acc Y = {acc.Y,15}");
Debug.WriteLine($"Acc Z = {acc.Z,15}");
Thread.Sleep(100);
}
}