Calibration

If we rotate the board, the direction of the Earth’s magnetic field with respect to the magnetometershould change but its magnitude should not! Yet, the magnetometer indicates that the magnitude ofthe magnetic field changes as the board rotates.

Why’s that the case? Turns out the magnetometer needs to be calibrated to return the correct answer.

The calibration involves quite a bit of math (matrices) so we won’t cover it here but thisApplication Note describes the procedure if you are interested. Instead, what we’ll do in thissection is visualize how off we are.

Let’s try this experiment: Let’s record the readings of the magnetometer while we slowly rotate theboard in different directions. We’ll use the iprintln macro to format the readings as TabSeparated Values (TSV).

  1. #![deny(unsafe_code)]
  2. #![no_main]
  3. #![no_std]
  4. #[allow(unused_imports)]
  5. use aux15::{entry, iprint, iprintln, prelude::*, I16x3};
  6. #[entry]
  7. fn main() -> ! {
  8. let (_leds, mut lsm303dlhc, mut delay, mut itm) = aux15::init();
  9. loop {
  10. let I16x3 { x, y, z } = lsm303dlhc.mag().unwrap();
  11. iprintln!(&mut itm.stim[0], "{}\t{}\t{}", x, y, z);
  12. delay.delay_ms(100_u8);
  13. }
  14. }

You should get an output in the console that looks like this:

  1. $ # itmdump console
  2. -76 213 -54
  3. -76 213 -54
  4. -76 213 -54
  5. -76 213 -54
  6. -73 213 -55

You can pipe that to a file using:

  1. $ # Careful! Exit any running other `itmdump` instance that may be running
  2. $ itmdump -F -f itm.txt > emf.txt

Rotate the board in many different direction while you log data for a several seconds.

Then import that TSV file into a spreadsheet program (or use the Python script shown below) and plotthe first two columns as a scatter plot.

  1. #!/usr/bin/python
  2. import csv
  3. import math
  4. import matplotlib.pyplot as plt
  5. import numpy as np
  6. import seaborn as sns
  7. import sys
  8. # apply plot style
  9. sns.set()
  10. x = []
  11. y = []
  12. with open(sys.argv[1], 'r') as f:
  13. rows = csv.reader(f, delimiter='\t')
  14. for row in rows:
  15. # discard rows that are missing data
  16. if len(row) != 3 or not row[0] or not row[1]:
  17. continue
  18. x.append(int(row[0]))
  19. y.append(int(row[1]))
  20. r = math.ceil(max(max(np.abs(x)), max(np.abs(y))) / 100) * 100
  21. plt.plot(x, y, '.')
  22. plt.xlim(-r, r)
  23. plt.ylim(-r, r)
  24. plt.gca().set_aspect(1)
  25. plt.tight_layout()
  26. plt.savefig('emf.svg')
  27. plt.close

Calibration - 图1

If you rotated the board on a flat horizontal surface, the Z component of the magnetic field shouldhave remained relatively constant and this plot should have been a circumference (not a ellipse)centered at the origin. If you rotated the board in random directions, which was the case of plotabove, then you should have gotten a circle made of a bunch of points centered at the origin.Deviations from the circle shape indicate that the magnetometer needs to be calibrated.

Take home message: Don’t just trust the reading of a sensor. Verify it’s outputting sensible values.If it’s not, then calibrate it.