User Tools

Translations of this page:

Site Tools


en:lesson5

Lesson 05. Magnetometer calibration. Raw data acquisition

Getting acquainted with smartphone magnetometer

Almost every modern smartphone have the integrated magnetometer; let’s become acquainted with it. Download to the smartphone application for visualization of the data received from the integrated magnetometer – for example, MagnetMeter.

Open the application; you will see the blue arrow that shows the direction of magnetic field lines.

Move your smartphone and make sure that magnetic field lines are directed always in one way, approximately to the North.

Beside Earth magnetic field, the magnetometer’s readings are affected by other magnetic fields. Assure oneself of it – bring the magnet near the smartphone. By moving the magnet near the smartphone, identify the precise point of magnetometer’s location in smartphone’s body.

Please note the values of Earth magnetic field intensity and magnetic field intensity near magnet.

Magnetometer operability check

Connect Host Onboard Computer with Power System and magnetometer.

Do not fix the magnetometer to the board to make possible the moving of the magnetometer.

Download the program to OrbiCraft and run the program.

Python code.

mag_test_2.py
def control(): # Program’s main function which is calling all other functions
	mgn_result = [0,0,0,0] # Initialize mgn_result
	num = 1
	print "Enable magnetometer №", num
	magnetometer_turn_on(num)
	sleep(1)
	print "Get RAW data from magnetometer"
	for i in range(1000):
		mgn_result = magnetometer_request_raw(num)
		if not mgn_result[0]: # if error message
			print mgn_result[1], mgn_result[2], mgn_result[3]
		elif mgn_result[0] == 1:
			print "Fail because of access error, check the connection"
		elif mgn_result[0] == 2:
			print "Fail because of interface error, check your code"
		sleep(0.1)
 	print "Disable magnetometer №", num
	magnetometer_turn_off(num)

С code.

mag_test_2.c
#include <stdio.h>
#include <stdint.h>
#include "libschsat.h"
#define LSS_OK 0 
#define LSS_ERROR 1 
#define LSS_BREAK 2
 
void control(void) // Program’s main function which is calling all other functions
{
	int16_t mgn_result[] = {0, 0, 0, 0}; //Initialize mgn_result
	uint16_t num = 1; //Magnetometer number
	printf("Enable magnetometer № %d", num);
	magnetometer_turn_on(num); //Magnetometer turn on
	Sleep(1);
	printf("Get RAW data from magnetometer");
	int i;
	for (i = 0; i < 10; i++)
	{
		mgn_result[0] = magnetometer_request_raw(num, &mgn_result[1], &mgn_result[2], &mgn_result[3]);
		if (!mgn_result[0]) //if error message
		{
			printf("state: %d\n", i);
			printf(" x_raw = %d\n", mgn_result[1]);
			printf(" y_raw = %d\n", mgn_result[2]);
			printf(" z_raw = %d\n", mgn_result[3]);
		}
		else if (mgn_result[0] == 1)
		{
			printf("Fail because of access error, check the connection");
		}
		else if (mgn_result[0] == 2)
		{
			printf("Fail because of interface error, check your code");
		}
		Sleep(1);
	}
	printf("Disable magnetometer №%d", num);
	magnetometer_turn_off(num); //Magnetometer turn off
 
 
}

Run the program and check the program output values. If the magnetometer is not moving, the values will not change. If the magnetometer is moving, the values will be changing.

If the magnetometer will be rotated about its axis, there will be changed primarily the only one digital value; other two (of three in total) digital values will be changed less.

Bring the magnet near the magnetometer and see how the values will be changed during the magnet movement near the static magnetometer.

Azimuth value acquisition with the magnetometer

Print the angle protractor (the full-size drawing from Transportir.pdf file); affix the print-out to the desk via sticker pads that leave no marks (UHU Patafix or similiar); affix magnetometer to the ruler the same way.

Download to OrbiCraft the program that will perform 60 measurement readings with 1 sec steps:

Python code.

azimuth.py
import math
time_step = 1		# Measurement time step, sec
mag_num = 1		# Magnetometer number
def control(): # Program’s main function
	print "Enable magnetometer", mag_num	
	magnetometer_turn_on(mag_num)
	sleep(1)
	mag_state = 0 		# Initialize magnetometer status
	alpha_goal = 0		# Target angle
	omega_goal = 0 		# Target angular velocity
		for i in range(60):
		mag_state, magx_raw, magy_raw, magz_raw = magnetometer_request_raw(mag_num) # magnetometer data request
		if not mag_state: # if error code is 0, no error 
			mag_alpha = math.atan2(magy_raw, magx_raw)/math.pi*180
			print "mag_alpha atan2= ", mag_alpha
		elif mag_state == 1:
			print "Fail because of access error, check the connection"
		elif mag_state == 2:
			print "Fail because of interface error, check your code"
		sleep(time_step)
	print "Disable magnetometer", mag_num
	magnetometer_turn_off(mag_num)

С code.

azimuth.c
#include <stdio.h>
#include <stdint.h>
#include "libschsat.h"
#define LSS_OK 0 
#define LSS_ERROR 1 
#define LSS_BREAK 2
 
 
#include <math.h>
void control(void){
	int time_step = 1;
	uint16_t mag_num = 1;
	printf("Enable magnetometer %d\n", mag_num);
	magnetometer_turn_on(mag_num);
	Sleep(1);
	int mag_state = 0;
 
	int16_t p_dataX;
	int16_t p_dataY;
	int16_t p_dataZ;
	int16_t *pRAW_dataX = &p_dataX;
	int16_t *pRAW_dataY = &p_dataY;
	int16_t *pRAW_dataZ = &p_dataZ;
	int i;
	for (i = 0; i < 60; i++){
		mag_state = magnetometer_request_raw(mag_num, pRAW_dataX, pRAW_dataY, pRAW_dataZ);
		float mag_alpha;
		if (!mag_state){
			mag_alpha = atan2(p_dataY, p_dataX)/M_PI*180;
			printf("mag_alpha atan2 = %f\n", mag_alpha);
		}
		else if (mag_state == 1){
			printf("Fail because of access error, check the connection\n");
		}
		else if (mag_state == 2){
			printf("Fail because of interface error, check your code\n");
		}
		Sleep(time_step);
	}
	printf("Disable magnetometer %d\n", mag_num);
	magnetometer_turn_off(mag_num);
}

Turn the magnetometer with 30 degrees step, record the readings for the angle values to EXCEL sheet. There will be the table something like this:

Data Analysis with Excel

Please note: upon 30 degrees turn, the angle value from magnetometer will not be changed to 30 degrees preciously. Let us calculate these values with EXCEL tools.

Table Creation

Create the new column that will include the remainder of the adjacent numbers’ subtraction. Enter to empty С2 cell the equal mark, then click В1 with the mouse, enter the «-» sign, then click to В2 cell and press Enter.

At С2 cell there will be calculated the remainder of В1-В2. Drag the corner down, and the formula will be copied automatically to all lower cells.

The remainders will be automatically calculated.

Please note that “-326” value is certainly error value. Upon the transition over 180 value there changed the sign of the measured angle, consequently instead of -326 there must be entered the (180-155) value added together with (180-171) value. It will come to 25+9=34. Enter 34 value instead of -326.

Construction of diagrams

Now there required to plot the diagram that will show the distortions put into angle measurement via uncalibrated magnetometer. Enter the calculated remainders’ values.

Press Insert and choose Pie chart.

Right-click to color circle and choose white for filling and black for outline.

Now it is seen (even with the naked eye only) that magnetometer is not perfect: the sectors of a circle are not preciously 30. Some are narrow, others are wide.

Let us plot one more diagram that will show the magnetometer’s imperfection. Choose the calculated remainders’ values. Press Insert and choose Radar chart.

Now it is perfectly seen that values are far from perfect dodecagon with 30-radius.

Data Analysis with function

Now let’s calculate the average remainder between measured angles using EXCEL function AVERAGE. Choose any cell; enter the equal mark, the function name, the left bracket.

Choose with mouse the range of calculated remainder values upon which we plotted the diagrams, enter the right bracket. The function will be = AVERAGE(C2:C13).

Press Enter; the function will calculate the average for the given numbers.

Now let’s calculate the standard deviation of the calculated remainders from the average; it will show the dispersion of values in relation to average. We will use the STDEV function.

Choose any cell; enter the equal mark, the function name, the left bracket.

Choose with mouse the range of calculated remainder values upon which we plotted the diagrams, enter the right bracket.

The function will be = STDEV(C2:C13).

Press Enter; the function will calculate the standard deviation of the remainder range from the average.

Then calculate the percentage ration of the average and standard deviation.

Evidently, the dispersion is large; it is 17% from the average value.

The magnetometer requires calibration.

Raw Data Acquisition for Magnetometer Calibration

By default the magnetometer is not calibrated so it gives inaccurate readings. The adjusted values may be acquired from raw data by calibration that is the defining of the transformation matrix and vector of translation. The raw data from magnetometer may be acquired by running the Python code listed below. During the raw data collection the magnetometer must be chaotically rotated endeavoring to put it in all possible positions.

Python code.

raw_data.py
def control(): #Program’s main function 
	mgn_result = [0,0,0,0] 		#Initialize mgn_result
	num = 1
	magnetometer_turn_on(num) 	#Turn magnetometer on 
	sleep(1)
	for i in range(500):		#Perform 500 readings
		mgn_result = magnetometer_request_raw(num)
		if not mgn_result[0]: #If sensor has not returned error message
			print mgn_result[1], mgn_result[2], mgn_result[3]
		sleep(0.05)			#Delay five-hundredths of the second 
 	magnetometer_turn_off(num)	#Turn magnetometer off

С code.

raw_data.c
#include <stdio.h>
#include <stdint.h>
#include "libschsat.h"
#define LSS_OK 0 
#define LSS_ERROR 1 
#define LSS_BREAK 2
 
 
void control(void){ //Program’s main function
	int16_t mgn_result[] = {0, 0, 0, 0}; //Initialize mgn_result
	uint16_t num = 1;
	magnetometer_turn_on(num); //Turn magnetometer on 
	Sleep(1);
	int i;
	for (i = 0; i < 1000; i++) //Perform 500 readings
	{
		mgn_result[0] = magnetometer_request_raw(num, &mgn_result[1],&mgn_result[2],&mgn_result[3]);
		if(!mgn_result[0]){ //If sensor has not returned error message
			printf("%d, %d, %d\n", mgn_result[1], mgn_result[2], mgn_result[3]);
		}
		Sleep(0.5); //Delay five-hundredths of the second
	}
	magnetometer_turn_off(num); 
}

Connect Host Onboard Computer with Power System and magnetometer. Do not fix the magnetometer to the board to make possible the moving of the magnetometer. Download the program to OrbiCraft and run the program. Chaotically rotate the magnetometer to collect raw data from all possible magnetometer’s positions.

Save the acquired data to the file in .txt format. To do so, select all results with Ctrl+A shortcut, copy with Ctrl+C shortcut and save.

Program performance analysis

To work with magnetometer the program uses such functions: magnetometer_turn_on(num) – magnetometer switching’on function, where num is the number of the magnetometer.

magnetometer_request_raw(num) – the function that returns raw data measured with magnetometer with num number presented as list with 4 digit values. So the read values will be put into mgn_result list, including 4 values.

mgn_result = [0,0,0,0]

mgn_result = magnetometer_request_raw(num)

The first value of the list returns error message.

If the value returned is 0, there is no error; if it is 1, then sensor is not connected; if it is 2, it is the program error.

The program uses cycle statement for i in range(1000) which will be performed 1000 times; so there will be output 1000 values.

These values will be required for the next lesson for magnetometer calibration.

en/lesson5.txt · Last modified: 2019/11/13 11:47 by golikov