九轴陀螺仪ICM20948磁力计校准

 ̄綄美尐妖づ 提交于 2019-12-01 13:50:11

九轴陀螺仪ICM20948磁力计校准

ICM20948九轴传感器目前应用广泛,是非常适合用于智能手机,平板电脑,可穿戴式传感器,物联网和应 用的全球功耗最低的9轴MotionTracking设备。其融合了3轴陀螺仪,3轴加速度计,3轴磁力计和数字运动处理器。其封装小,功耗低便于集成,融合了磁力计及内置DMP使其运动性能较MPU6050六轴传感器有很大提升。

在使用ICM20948的过程中发现使用磁力计后效果反而不如不使用好,于是决定把磁力计数据分析一下

采集数据

下位机代码

		OutData[0] = 0xB5;  //帧头,用于判断一组数据
		OutData[1] = rawData[7] & 0x00ff;  //低八位
		OutData[2] = rawData[7] >> 8;      //高八位
		OutData[3] = rawData[8] & 0x00ff;
		OutData[4] = rawData[8] >> 8;
		OutData[5] = rawData[9] & 0x00ff;
		OutData[6] = rawData[9] >> 8;			
		OutPut_Data(OutData);
        for(i=0; i<7; i++)
        {
            USART_SendData(USART3,OutData[i]);
            while(USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET);
        }
		
		

串口助手接收数据

在这里插入图片描述

将数据存到txt中
在这里插入图片描述

matlab处理数据

提取数据

[FileName,PathName] = uigetfile('*.txt','Select the Txt files');  %选择要处理的文件
fid=fopen([PathName FileName],'r');                               %读取文件
if fid == -1  
    ( 'Error opening the file'); end 
    
myword = textscan(fid, '%s');
array_num = numel(myword{1});
aim_num = zeros(1,8000);   %提前分配内存
dataFromMF = zeros(1000,7);
dataFromMFIndex = 1 ;
dataFromMFIndex_group = 1 ;
dataFromMFReadyFlag = 0 ;
x = zeros(1,1000);
y = zeros(1,1000);
z = zeros(1,1000);

for i = 1 : array_num
    aim_num(i) = hex2dec(myword{1,1}{i,1});
    switch dataFromMFIndex
			case 1
                if aim_num(i) == 181
                        dataFromMF(dataFromMFIndex_group,dataFromMFIndex)=aim_num(i);
                        dataFromMFIndex = dataFromMFIndex + 1;
                end
			case 7
                        dataFromMF(dataFromMFIndex_group,dataFromMFIndex)=aim_num(i);
                        dataFromMFIndex_group = dataFromMFIndex_group + 1;
                        dataFromMFIndex=1;
        otherwise
                        dataFromMF(dataFromMFIndex_group,dataFromMFIndex)=aim_num(i);
                        dataFromMFIndex = dataFromMFIndex + 1;
    end
                
end


在这里插入图片描述

发现每几组数据就会有一组异常值,于是把这些数据过滤掉,初步判断问题可能出在了这里,但是其他数据的分析还是要做滴

由于单片机中负数以补码的形式存储,所以需要把数据再处理一下


for i = 1 : (dataFromMFIndex_group - 1)
    x(i) = dataFromMF(i,2) + dataFromMF(i,3) * 256;
    y(i) = dataFromMF(i,4) + dataFromMF(i,5) * 256;
    z(i) = dataFromMF(i,6) + dataFromMF(i,7) * 256;    
end
for i = 1 : (dataFromMFIndex_group - 1)
    if x(i) >= 32786
        a = x(i);
        x(i) = bitcmp (uint16(a));    %转换成十进制
        x(i) = -x(i);
    end
    if y(i) >= 32786
        b = y(i);
        y(i) = bitcmp (uint16(b));
        y(i) = -y(i);
    end
    if z(i) >= 32786
        a = z(i);
        z(i) = bitcmp (uint16(a));
        z(i) = -z(i);
    end    
    if x(i)>1024 || y(i)>1024 || z(i)>1024 ||x(i)<-1024 || y(i)<-1024 || z(i)<-1024  %过滤掉不正常的值
        x(i) = 0;
        y(i) = 0;
        z(i) = 0;
    end

end

绘制三维图

scatter3(x,y,z);

在这里插入图片描述

发现并不是一个球体,建立x-y 、 x-z 、y-z坐标系再观察观察

cftool  %命令行下使用工具cftool

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

圆心不在坐标轴原点,和想象中差别有点大,因为觉得这个传感器挺贵的

校准

取每个轴的最大值最小值,相加除以2

x_dif =( max(x)+ min(x)) /2;
y_dif = ( max(y)+ min(y)) /2;
z_dif = ( max(z)+ min(z)) /2;
for i = 1 : (dataFromMFIndex_group - 1)
    x(i) =  x(i) - x_dif;
    y(i) =  y(i) - y_dif;
    z(i) =  z(i) - z_dif;
end

在这里插入图片描述

处理完之后发现圆心回到了坐标轴原点,但是还是个椭圆

等比例缩放

for i = 1 : (dataFromMFIndex_group - 1)
    x(i) =  x(i) ;
    y(i) =  y(i) * (max(x) - min(x)) / (max(y) - min(y));
    z(i) =  z(i) * (max(x) - min(x)) / (max(z) - min(z));
end

在这里插入图片描述

发现变成了一个圆,此时再绘制三维图

在这里插入图片描述

发现它比之前规则了很多,校准完成

之后就要解决数据突变的问题了,下次再说

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!