User Tools

Site Tools


en:lesson5

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

en:lesson5 [2019/11/13 11:45]
golikov
en:lesson5 [2020/03/25 16:28]
Line 1: Line 1:
-====== 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. 
- 
-{{::​05image001.png?​nolink&​400|}} 
- 
-Open the application;​ you will see the blue arrow that shows the direction of magnetic field lines. 
- 
-{{:​05image003.png?​nolink&​200|}} 
- 
-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. 
- 
- 
-{{::​05image004.png?​nolink&​200|}} 
- 
-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. 
-<file python 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) 
-</​file>​ 
- 
-С code. 
-<file c 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 
-  
-  
-} 
-</​file>​ 
- 
- 
-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. 
- 
-{{::​05image005.png?​nolink&​200|}} 
- 
-Download to OrbiCraft the program that will perform 60 measurement readings with 1 sec steps:  ​ 
- 
- 
-Python code. 
-<file python 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) 
- 
-</​file>​ 
- 
-С code. 
-<file c 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);​ 
-} 
-</​file>​ 
- 
-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: 
- 
- 
-{{:​05_image_101.png?​nolink&​200|}} 
- 
-===== 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. 
- 
-{{::​05_image007.png?​nolink&​200|}} 
- 
-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. ​ 
- 
-{{::​05_image008.png?​nolink&​200|}} 
- 
-The remainders will be automatically calculated. 
- 
-{{::​05image009.png?​nolink&​200|}} 
- 
-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. 
- 
-{{::​05_image010.png?​nolink&​200|}} 
- 
-Press **Insert** and choose Pie chart. 
- 
-{{:​en:​image_excel.png?​500|}} 
- 
-{{:​en:​excel_2_.png?​200|}} 
- 
-Right-click to color circle and choose white for filling and black for outline. 
- 
-{{:​en:​excel_3_.png?​300|}} 
- 
-{{:​en:​excel_4_.png?​300|}} 
- 
-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. 
- 
-{{::​05_image016.png?​nolink&​200|}} 
- 
-Let us plot one more diagram that will show the magnetometer’s imperfection. Choose the calculated remainders’ values. 
-Press **Insert** and choose Radar chart. 
- 
-{{:​en:​excel_5_.png?​200|}} 
- 
-{{::​05image018.png?​nolink&​200|}} 
- 
-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. 
- 
-{{:​en:​excel_6_.png?​200|}} 
- 
-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. 
- 
- 
-{{::​05image020.png?​nolink&​200|}} 
- 
- 
-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. 
- 
- 
-{{::​05image021.png?​nolink&​200|}} 
- 
-{{::​05image022.png?​nolink&​200|}} 
- 
-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. 
-<file python 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 
-</​file>​ 
- 
-С code. 
-<file c 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); ​ 
-} 
-</​file>​ 
- 
-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: 2020/03/25 16:28 (external edit)