SensorLib 0.5.0
Multi-platform sensor driver library for Arduino, PlatformIO, and ESP-IDF
Loading...
Searching...
No Matches
mag_interface_get_data.ino
Go to the documentation of this file.
1
30#include <MagnetometerDrv.hpp>
31#include <SensorWireHelper.h>
32
33#ifdef ARDUINO_T_BEAM_S3_SUPREME
34#include <XPowersAXP2101.tpp> //PMU Library https://github.com/lewisxhe/XPowersLib.git
35#endif
36
37#ifndef SENSOR_SDA
38#define SENSOR_SDA 17
39#endif
40
41#ifndef SENSOR_SCL
42#define SENSOR_SCL 18
43#endif
44
46void calibrate();
47
48#if defined(ARDUINO_T_BEAM_S3_SUPREME)
49XPowersAXP2101 power;
50#endif
51
53{
54#if defined(ARDUINO_T_BEAM_S3_SUPREME)
55 Wire.begin(SENSOR_SDA, SENSOR_SCL);
56 SensorWireHelper::dumpDevices(Wire);
57 power.begin(Wire1, AXP2101_SLAVE_ADDRESS, 42, 41);
58 power.disableALDO1();
59 power.disableALDO2();
60 delay(250);
61 power.setALDO1Voltage(3300);
62 power.enableALDO1();
63 power.setALDO2Voltage(3300);
64 power.enableALDO2();
65 power.setChargingLedMode(XPOWERS_CHG_LED_OFF);
66#endif
67}
68
69void setup()
70{
71
72 // The desired output data rate in Hz. Allowed values are 1.0, 10.0, 50.0, 100.0 and 200.0HZ.
73 float data_rate_hz = 200.0f;
74 // op_mode: Allowed values are SUSPEND, NORMAL, SINGLE_MEASUREMENT, CONTINUOUS_MEASUREMENT
76 // full_scale: Allowed values are FS_8G, FS_16G ,FS_32G
78 // over_sample_ratio: Allowed values are OSR_1, OSR_2, OSR_4, OSR_8
80 // down_sample_ratio: QMC6309 does not support downsampling rate settings; this parameter is ignored.
82
83
84 Serial.begin(115200);
85 while (!Serial);
86
87 // LilyGo T-Beam-Supreme sensor requires a power source to function.
88 beginPower();
89
90 if (magnetometer == nullptr) {
92 if (!static_cast<SensorQMC6310*>(magnetometer)->begin(Wire, QMC6310U_SLAVE_ADDRESS)) {
93 Serial.println("Failed to find QMC6310U - check your wiring!");
94 delete magnetometer;
95 magnetometer = nullptr;
96 } else {
97 Serial.println("QMC6310U found!");
98 // The desired output data rate in Hz. Allowed values are 10.0, 50.0, 100.0 and 200.0HZ.
99 data_rate_hz = 200.0f;
100 // op_mode: Allowed values are SUSPEND, NORMAL, SINGLE_MEASUREMENT, CONTINUOUS_MEASUREMENT
102 // full_scale: Allowed values are FS_2G, FS_8G, FS_12G ,FS_30G
103 full_scale = MagFullScaleRange::FS_8G;
104 // over_sample_ratio: Allowed values are OSR_1, OSR_2, OSR_4, OSR_8
105 over_sample_ratio = MagOverSampleRatio::OSR_1;
106 // down_sample_ratio: Allowed values are DSR_1, DSR_2, DSR_4, DSR_8
107 down_sample_ratio = MagDownSampleRatio::DSR_1;
108 }
109 }
110
111 if (magnetometer == nullptr) {
113 if (!static_cast<SensorQMC6310*>(magnetometer)->begin(Wire, QMC6310N_SLAVE_ADDRESS)) {
114 Serial.println("Failed to find QMC6310 - check your wiring!");
115 delete magnetometer;
116 magnetometer = nullptr;
117 } else {
118 Serial.println("QMC6310N found!");
119 // The desired output data rate in Hz. Allowed values are 10.0, 50.0, 100.0 and 200.0HZ.
120 data_rate_hz = 200.0f;
121 // op_mode: Allowed values are SUSPEND, NORMAL, SINGLE_MEASUREMENT, CONTINUOUS_MEASUREMENT
123 // full_scale: Allowed values are FS_2G, FS_8G, FS_12G ,FS_30G
124 full_scale = MagFullScaleRange::FS_8G;
125 // over_sample_ratio: Allowed values are OSR_1, OSR_2, OSR_4, OSR_8
126 over_sample_ratio = MagOverSampleRatio::OSR_1;
127 // down_sample_ratio: Allowed values are DSR_1, DSR_2, DSR_4, DSR_8
128 down_sample_ratio = MagDownSampleRatio::DSR_1;
129 }
130 }
131
132 if (magnetometer == nullptr) {
134 if (!static_cast<SensorQMC6309*>(magnetometer)->begin(Wire, QMC6309_SLAVE_ADDRESS)) {
135 Serial.println("Failed to find QMC6309 - check your wiring!");
136 delete magnetometer;
137 magnetometer = nullptr;
138 } else {
139 Serial.println("QMC6309 found!");
140 // The desired output data rate in Hz. Allowed values are 1.0, 10.0, 50.0, 100.0 and 200.0HZ.
141 data_rate_hz = 200.0f;
142 // op_mode: Allowed values are SUSPEND, NORMAL, SINGLE_MEASUREMENT, CONTINUOUS_MEASUREMENT
144 // full_scale: Allowed values are FS_8G, FS_16G ,FS_32G
145 full_scale = MagFullScaleRange::FS_8G;
146 // over_sample_ratio: Allowed values are OSR_1, OSR_2, OSR_4, OSR_8
147 over_sample_ratio = MagOverSampleRatio::OSR_1;
148 // down_sample_ratio: QMC6309 does not support downsampling rate settings; this parameter is ignored.
149 down_sample_ratio = MagDownSampleRatio::DSR_1;
150 }
151 }
152
153 while (magnetometer == nullptr) {
154 Serial.println("No magnetometer found!");
155 delay(1000);
156 }
157
158 /* Config Magnetometer */
160 op_mode,
161 full_scale,
162 data_rate_hz,
163 over_sample_ratio,
164 down_sample_ratio)) {
165 Serial.println("Magnetometer configured successfully.");
166 } else {
167 Serial.println("Magnetometer configuration failed.");
168 while (1);
169 }
170
171 // Calibration algorithm reference from
172 // https://github.com/CoreElectronics/CE-PiicoDev-QMC6310-MicroPython-Module
173 calibrate();
174
175 Serial.println("Calibration done.");
176 delay(5000);
177 // magnetometer->setOffset(1295,-1478,398);
178
179
181 Serial.print("Manufacturer: "); Serial.println(info.manufacturer);
182 Serial.print("Model: "); Serial.println(info.model);
183 Serial.print("I2C Address: 0x"); Serial.println(info.i2c_address, HEX);
184 Serial.print("Version: "); Serial.println(info.version);
185 Serial.print("UID: 0x"); Serial.println(info.uid);
186 Serial.print("Type: "); Serial.println(SensorUtils::typeToString(info.type));
187
189 Serial.print("DataRate: "); Serial.println(cfg.sample_rate);
190 Serial.print("FullScaleRange: "); Serial.println(cfg.range);
191 Serial.print("Mode: "); Serial.println((uint8_t)cfg.mode);
192 Serial.println();
193
194 //Find the magnetic declination : https://www.magnetic-declination.com/
195 float declination_deg = MagnetometerUtils::dmsToDecimalDegrees(-3, 20); // -3.3333
196
197 magnetometer->setDeclination(declination_deg);
198
199 Serial.print(" Magnetic Declination: ");
200 Serial.print(declination_deg, 2);
201 Serial.println("°");
202
203 Serial.print(" Sensitivity: ");
204 Serial.print(magnetometer->getSensitivity(), 6);
205 Serial.println(" Gauss/LSB");
206
207 delay(3000);
208
209 Serial.println("Read data now...");
210}
211
212void loop()
213{
214
215 MagnetometerData data;
216
217 if (magnetometer->readData(data)) {
218
219 // Gauss to μT
223
224 Serial.print("Mag:");
225 Serial.print(" X:"); Serial.print(x);
226 Serial.print(" Y:"); Serial.print(y);
227 Serial.print(" Z:"); Serial.print(z);
228 Serial.print(" μT");
229
230 Serial.print(" Metadata:");
231 Serial.print(" X:");
232 Serial.print(data.raw.x);
233 Serial.print(" Y:");
234 Serial.print(data.raw.y);
235 Serial.print(" Z:");
236 Serial.print(data.raw.z);
237
238 Serial.print(" Heading (rad): ");
239 Serial.print(data.heading, 6);
240 Serial.print(" rad");
241
242 Serial.print(" Heading (deg): ");
243 Serial.print(data.heading_degrees, 2);
244 Serial.print("°");
245
247 strength = MagnetometerUtils::gaussToMicroTesla(strength);
248 Serial.print(" Magnetic Strength: ");
249 Serial.print(strength, 2);
250 Serial.println(" μT");
251
252 if (data.overflow) {
253 Serial.println("\tWarning: Data Overflow occurred!");
254 }
255 }
256 delay(10);
257}
258
259
261{
262 if (!magnetometer)return;
263
264 if (!magnetometer->setOutputDataRate(200.0f)) {
265 Serial.println("Failed to set output data rate");
266 return ;
267 }
268
269 Serial.println("========================================");
270 Serial.println("Calibration Instructions:");
271 Serial.println("1. Rotate sensor in FIGURE-8 pattern");
272 Serial.println("2. Cover all axes (X, Y, Z directions)");
273 Serial.println("3. Rotate slowly and completely");
274 Serial.println("4. Wait for progress bar to complete");
275 Serial.println("5. Expected: Magnetic Strength ~25-65 uT");
276 Serial.println("========================================");
277 Serial.println();
278
279 Serial.println("Place the sensor on the plane and slowly rotate the sensor...");
280 Serial.println("Rotate in FIGURE-8 pattern to cover all directions!");
281 Serial.println("If the heading angle does not change with the direction, please rerun the calibration until it is normal.");
282 Serial.println();
283 delay(3000);
284
285
286#if defined(ARDUINO_T_BEAM_S3_SUPREME)
287 power.setChargingLedMode(XPOWERS_CHG_LED_BLINK_4HZ);
288#endif
289
290 int32_t x_min = 65535;
291 int32_t x_max = -65535;
292 int32_t y_min = 65535;
293 int32_t y_max = -65535;
294 int32_t z_min = 65535;
295 int32_t z_max = -65535;
296
297 int32_t range = 1000;
298 int32_t i = 0;
299 int32_t x = 0, y = 0, z = 0;
300 int16_t x_offset = 0;
301 int16_t y_offset = 0;
302 int16_t z_offset = 0;
303
304 MagnetometerData data;
305 while (i < range) {
306 i += 1;
307
308 if (magnetometer->isDataReady()) {
309
310 magnetometer->readData(data);
311
312 x = (data.raw.x + x) / 2;
313 y = (data.raw.y + y) / 2;
314 z = (data.raw.z + z) / 2;
315 if (x < x_min) {
316 x_min = x;
317 i = 0;
318 }
319 if (x > x_max) {
320 x_max = x;
321 i = 0;
322 }
323 if (y < y_min) {
324 y_min = y;
325 i = 0;
326 }
327 if (y > y_max) {
328 y_max = y;
329 i = 0;
330 }
331 if (z < z_min) {
332 z_min = z;
333 i = 0;
334 }
335 if (z > z_max) {
336 z_max = z;
337 i = 0;
338 }
339 int j = round(10 * i / range);
340
341 Serial.print("[");
342 for (int k = 0; k < j; ++k) {
343 Serial.print("*");
344 }
345 Serial.println("]");
346 }
347 delay(5);
348 }
349
350 x_offset = (x_max + x_min) / 2;
351 y_offset = (y_max + y_min) / 2;
352 z_offset = (z_max + z_min) / 2;
353
354 Serial.print("x_min:");
355 Serial.println(x_min);
356
357 Serial.print("x_max:");
358 Serial.println(x_max);
359
360 Serial.print("y_min:");
361 Serial.println(y_min);
362
363 Serial.print("y_max:");
364 Serial.println(y_max);
365
366 Serial.print("z_min:");
367 Serial.println(z_min);
368
369 Serial.print("z_max:");
370 Serial.println(z_max);
371
372 Serial.print("x_offset:");
373 Serial.println(x_offset);
374
375 Serial.print("y_offset:");
376 Serial.println(y_offset);
377
378 Serial.print("z_offset:");
379 Serial.println(z_offset);
380
381
382 // Set the calibration value and the user calculates the deviation
383 magnetometer->setOffset(x_offset, y_offset, z_offset);
384
385 Serial.println();
386 Serial.println("Calibration complete!");
387 Serial.println("Check if Magnetic Strength is ~25-65 uT");
388 Serial.println("If too low, repeat calibration with better rotation");
389
390#if defined(ARDUINO_T_BEAM_S3_SUPREME)
391 power.setChargingLedMode(XPOWERS_CHG_LED_ON);
392#endif
393}
@license MIT License
OperationMode
Enumeration of sensor operation modes.
MagFullScaleRange
Enumeration defining full-scale range settings for the sensor.
MagDownSampleRatio
Enumeration defining down-sample ratios for the sensor.
@ DSR_1
1x down-sample ratio
MagOverSampleRatio
Enumeration defining over-sample ratios for the sensor.
@ OSR_1
1x over-sample ratio
@license MIT License
virtual bool setOutputDataRate(float odr)=0
Sets the output data rate for the magnetometer.
bool readData(MagnetometerData &data) override=0
Checks if new data is available from the magnetometer.
virtual bool configMagnetometer(OperationMode mode, MagFullScaleRange range, float data_rate_hz, MagOverSampleRatio osr, MagDownSampleRatio dsr)=0
Configures the magnetometer with the specified settings.
virtual void setDeclination(float declination_deg)
Set the magnetic declination correction value.
bool isDataReady() override=0
Checks if new data is available from the magnetometer.
void setOffset(int16_t x, int16_t y, int16_t z)
Set sensor calibration offsets.
virtual SensorConfig getConfig() const
Get current sensor configuration.
float getSensitivity() const
Get sensor sensitivity.
SensorInfo getSensorInfo() const
Get sensor information.
static const char * typeToString(SensorType type)
Convert sensor type enumeration to string representation.
void setup()
#define SENSOR_SCL
#define SENSOR_SDA
void beginPower()
void calibrate()
MagnetometerBase * magnetometer
float dmsToDecimalDegrees(int degrees, int minutes, float seconds=0.0f)
Convert degrees-minutes-seconds to decimal degrees.
float calculateMagneticStrength(const MagnetometerData &data)
Calculate total magnetic field strength.
float gaussToMicroTesla(float gauss)
Converts Gauss to microTesla.
uint8_t i
SensorQSTMagnetic SensorQMC6310
Typedef to create an alias for SensorQSTMagnetic specifically for QMC6310 compatibility.
Structure representing magnetometer data.
RawVector raw
raw data
float heading_degrees
heading angle (degrees)
float heading
heading angle (radians)
SensorVector magnetic_field
magnetic field strength (Gauss)
bool overflow
data overflow flag
int16_t x
X-axis raw value.
int16_t y
Y-axis raw value.
int16_t z
Z-axis raw value.
Structure representing sensor configuration parameters.
float sample_rate
Sample rate in Hz.
float range
Measurement range.
OperationMode mode
Operation mode.
Structure containing sensor identification information.
uint8_t version
Hardware/firmware version.
uint8_t i2c_address
Default I2C address.
uint32_t uid
Unique identifier.
SensorType type
Sensor type.
const char * manufacturer
Manufacturer name.
const char * model
Model name/identifier.
float x
X-axis component.
float y
Y-axis component.
float z
Z-axis component.
int16_t x[5]
int16_t y[5]