Allegro AAS33001和AAS33051角度传感器ic的线性化参数计算

Allegro AAS33001和AAS33051角度传感器ic的线性化参数计算

下载PDF格式

多米尼克·盖斯勒,
亚博棋牌游戏Allegro MicroSystems, LLC

简介

磁性角度传感器通常是快速、可靠、非接触式测量系统角度位置的好选择,特别是在光学编码器可能不太适合的肮脏环境中。

亚博棋牌游戏Allegro MicroSystems, LLC提供广泛的角度传感器集成电路适用于不同的应用。亚博尊贵会员这些传感器ic可以测量侧轴或轴端设置中直径磁化编码器磁体的角度,如图1所示。

图1:侧轴测量角(左)和轴端角测量(右)
图1:侧轴测量角(左)和
轴端角测量(右)

测量误差

所有Allegro角度传感器ic都在工厂使用均匀磁场进行最终测试时进行校准。这样做是为了尽量减少传感器的固有误差。然而,特别是在侧轴应用中,传感器换能器处的磁场角度与待测轴的机械角度亚博尊贵会员并不相同。造成这种差异的主要原因是编码器磁铁发出的磁场的形状。

机械和磁场角不匹配的其他来源是磁体不对中,磁体缺陷,剩余传感器不准确和漂移,以及铁磁性材料的存在。

可以得出结论,所有系统,特别是侧轴系统,遭受编码器角度和测量角度之间的不匹配。侧轴应用的典型传递曲线如图2所示。

图2:模拟传感器读数与编码器角度在侧轴设置
图2:模拟传感器读数与编码器
在侧轴设置角度

这些测量误差被称为非线性,可以通过线性化过程进行补偿。

线性化

一些Allegro传感器ic,如A1335,AAS33001,以及AAS33051具有允许输入数据线性化的嵌入式逻辑。本应用说明将解释如何使用AAS33001和AAS33051的线性化特性。为了简化对这些部分的引用,今后将两者统称为AAS330x1。

本申请须知将:

  • 解释线性化的基本原理
  • 解释AAS330x1的线性化特征
  • 演示如何处理测量数据以计算校正数据
  • 说明如何计算传感器参数
  • 显示线性化后的精度

定义

编码器角度

由精确、高分辨率的外部编码器报告的角度。

传感器的角度

由角度传感器IC报告的角度。

角误差

角度误差是磁体实际位置与角度传感器IC测得的磁体位置之差,由传感器角度减去编码器角度计算得出:

错误= (α_sensor - α_encoder)。

但是,如果传感器角度为359°,编码器角度为0°,则误差应为-1°,而不是+359°。要对±180°以外的任何误差进行环绕,可以使用模运算符:

误差= mod[(α_sensor - α_encoder) + 180,360] - 180。

图3给出了侧轴应用中角度误差的示例图。

最大绝对角度误差

最大绝对角度误差是磁体的实际位置与由角度传感器IC测量的磁体位置之间的最大绝对差。
在图3中,当编码器角度为56°时,最大角度误差为21.46°。

图3:角度误差与传感器输出图的比较
图3:角度误差与传感器输出图的比较


线性化的目标

线性化的目标是确定、存储和应用一个函数,使测量的传感器角度误差与编码器角度值相比最小。这使得测量的传感器角度和实际编码器角度之间的差异最小化。

图4:线性化的目标:从传感器角度到编码器角度
图4:线性化的目标:从传感器获取
角度到编码器的角度

这个目标可以通过不同的方式来实现。本文将详细介绍三种常用技术。亚博尊贵会员

所介绍的技术依赖于单个校准阶段(通常在客户的线尾测试中执行),在此之后应用固定的校正功能。

线性化的先决条件

使用这里详细介绍的技术进行线性化的先决条件如下:

  • 在生产过程中,需要将已知的角度应用到传感器系统中。
  • 在生产过程中,需要读出传感器角度。
  • 要线性化的系统需要一个微控制器,在生产过程中将线性化信息写入微控制器,并在应用中执行线性化。

线性化的限制

使用这里描述的方法进行线性化有一些限制:

  • 传感器噪声不能通过线性化来校正。
  • 传感器校准后的任何漂移都不会被修正。
  • 校准后机械系统的变化不会通过线性化来校正。一个常见的例子是由于振动和转矩而引起的磁铁位置的动态变化。
  • 如果在校准过程中没有准确记录输入位置,校正的准确性也会受到同样的限制。

线性化方法

1.数据记录

为了生成线性化所需的数据,测量传感器输出[y0y……n]在已知的编码器角度[x .0x……n].这些编码器角度不需要等距,尽管通常使用等距角度。

值的记录如图5所示。

图5:数据记录
图5:数据记录

2.坐标变换到传感器角度

由于校正功能必须基于传感器数据工作,因此需要将记录的数据点转换为传感器坐标系。这意味着不再将传感器角度表示为实角度的函数,而是要求将实角度表示为传感器角度的函数。因此,传感器角度[y'0y……”n],对应的编码器角度为[x'0…x 'n需要确定。为此,需要通过数据点应用拟合。这可以通过样条插值来实现,如图6所示。

图6:坐标转换为传感器角度
图6:坐标转换为传感器角度

3.修正曲线计算

为了创建一个将传感器测量的角度转换为编码器角度的函数,需要计算修正值。这些修正值计算为[c0c…n= [x'0…x 'n] - [y'0y……”n].

图7:校正值计算
图7:校正值计算

最后,这些值描述了修正曲线c,其中给出了修正值作为传感器角度的函数。图8显示了c除以传感器角度的曲线。

图8:修正曲线
图8:修正曲线

4.修正曲线在数据中的应用

为了对测量的传感器数据点进行修正,需要根据修正曲线C计算出传感器数据点Y的修正值C,如图9所示。

图9:在修正曲线C上求值C = f(Y
图9:在修正曲线C上求值C = f(Y

然后确定正确的角度值X为X = Y + c,如图10所示。
图10:使用修正曲线求值X = Y + C
图10:使用X = Y + C求值
修正曲线

修正曲线的确定

本文档中的实现是在MathWorks MATLAB™中实现的。由于这是商业软件,使用它需要许可费用,这可能会阻碍在生产环境中使用。一个可以替代MATLAB的免费软件是GNU Octave,它可以在GNU GPLv3许可证下免费获得。

本文档中使用的所有函数都得到MATLAB和GNU Octave的支持。

传感器输出捕获

传感器角度输出的初始数据必须由用户捕获。这是通过设置特定的已知角度来实现的,在本文档中称为编码器角度。然后记录传感器角度。传感器角度是传感器测得的角度。所记录的点数可以大于或小于线性校正点的数。如果可能的话,记录更多的分数总是更好的。

一般来说,在轴上情况下,记录至少16个数据点就足以获得良好的校正性能。在离轴情况下,建议至少32个点。

要应用n段分段线性校正(例如32段),记录至少n个点将很好地利用可用的校正点。记录大约2 × n个点可以获得近乎理想的性能。表1给出了一个真实的记录点示例。

表1:记录的编码器和输出角度

图11:表1的数据图
图11:表1的数据图

传感器输出溢出清除

传感器数据在100°输入角附近的跳变会给接下来的处理步骤带来困难。在跳转到负方向后,通过对所有值添加360°来删除它。同时,数据的平均值应在±180°以内,以免后期处理出现其他问题。这是通过以下几行实现的:

% %预处理
%检查是否连续上升/下降,最大溢出一次
If any(diff(sensor_data_2) == 0)
错误('传感器数据必须是单调增加或减少')
Elseif sum(diff(sensor_data_2) < 0) <= 1
%上升角数据有零或一次溢出,溢出将被纠正
Sensor_data_2 = Sensor_data_2 (:) + 360*cumsum([false;diff (sensor_data_2 (:))
< 0]);
Elseif sum(diff(sensor_data_2) > 0) <= 1
%下降角数据有零或一次溢出,溢出将被纠正
Sensor_data_2 = Sensor_data_2 (:) - 360*cumsum([false;diff (sensor_data_2 (:))
> 0]);
其他的
错误('只允许一个数据溢出')
结束
输入数据的方向可能需要颠倒。这是由以下几行检测和执行的:
%倒角方向,如果需要
If all(diff(sensor_data_2) < 0)
Disp('反转角度方向…')
Sensor_data_2 = -sensor_data_2;
Raw_direction = -1;
Elseif all(diff(sensor_data_2) > 0)
Raw_direction = +1;
其他的
错误(“检测到非单调角度变化”)
结束
数据的平均值应在±180°以内,以免后期处理出现其他问题。这是通过以下几行实现的:
%正确包装传感器数据
rolovercorrection = round((mean(sensor_data_2) - 180)/360) * 360;
Sensor_data_2 = Sensor_data_2 -翻转校正;
结果值如表2所示。

表2:除去溢出后的编码器和输出角度

图12:表2的数据图
图12:表2的数据图

数据复制

最后,需要基于传感器角度0°到360°的校正数据。为了避免任何边缘效应,传感器数据将被复制三次。这避免了在所有情况下的边缘效应,始终可以安全地提取从传感器角度360°到720°的值。
扩展传感器数据

Sensor_data_ext = [sensor_data_2(:);sensor_data_2 (:) + 360;...
sensor_data_2 (:) + 720];
扩展输入数据
Angle_input_ext = [angle_input(:);angle_input (:) + 360;...
angle_input (:) + 720];

投影到传感器数据网格

在下一步中,计算与传感器输出360°和720°之间对应的编码器角度输入(在下面的代码中称为“intermediategrid”)。这需要4096个步骤,因为中间步骤的高分辨率有利于最终的输出质量。

%%使用样条从有序的输入网格中移动数据
%到有序的输出网格上:
Ordered_output_grid = 0:(360/4096):(360-360/4096);
Intermediategrid = ordered_output_grid + 360;
投影=样条(sensor_data_ext, angle_input_ext,…
intermediategrid);
这一步如图13所示。

图13:寻找编码器角度(“投影”)作为固定网格传感器角度(“intermediategrid”)的投影
图13:查找编码器角度(“投影”)为
固定网格传感器角度的投影(“中间网格”)
角度编码器值和传感器输出之间的差异是修正曲线,可以通过从计算的匹配编码器角度中减去固定网格传感器角度来计算。
%计算所需的数据修正:
Correction_curve = projection - intermediategrid;
Correction_curve = Correction_curve (:);
修正曲线如图14所示。
图14:本例的修正曲线
图14:本例的修正曲线

可以做一个简单的检查,看看这条曲线是否正确。由表1可以看出,当传感器角度为137.46°时,编码器角度为213.75°。从图14的修正曲线可以看出,当传感器角度为137.5°时,需要进行+76.29°的修正。137.46 + 76.26 = 213.72°≅213.75°,计算出的修正曲线适用。

下一步,需要将修正曲线存储在AAS330x1中。为了解释传感器如何应用校正,首先将解释分段线性校正的概念,然后介绍AAS330x1硬件功能,以确定实际的校正值。

线性插值

概念

修正曲线可用分段线性函数近似表示。为了实现这个功能,需要以传感器坐标和修正值对的形式存储支撑点。

在图8中,这些对是[(y'0c0,)…(y'ncn)]。

在支撑点之间进行线性插值。

在角度传感器线性化应用中,使用等距的传感器角度网格是很有用的亚博尊贵会员。这样,不需要存储传感器角度值[y'0…y'n],线性校正的实现变得更加容易。例如,它可以存储32个修正值,然后应用于0°、11.25°、22.50°等传感器角度。

存储的点可以通过不同的标准来确定。确定它们的最简单的方法是通过在校正曲线上选择所述传感器角度的点,这将被称为“曲线上”线性插值。然而,这些点也可以优化存储修正曲线的最小二乘误差。这将被称为“最小二乘”线性插值。

其他优化策略也是可能的,但在本文中不做描述。

本例曲线的曲线上和最小二乘修正参数之间的差异如图15所示。

图15:用曲线上最小二乘法确定参数的理想修正曲线与线性插值的比较
图15:理想修正曲线与线性插值的比较,参数由
曲线上和最小二乘法

最小二乘方法在相同的最大误差下减少了约50%的存储参数量,并且对单个测量异常值不太敏感。因此,这里将采用最小二乘法来确定线性插值支撑点。

实现

校正曲线需要用分段线性函数逼近。由于支撑点的选择应采用最小二乘误差方式,因此支撑点前后的数据也有助于确定其最终值。

这就给第一点和最后一点带来了问题。在0°处的第一个支撑点只有对该点右侧的修正曲线,因此不考虑接近360°的数据。为了避免这个问题,修正曲线将重复三次,并计算该曲线的分段线性最小二乘近似值。然后只使用中心部分来选择使用的参数。这个概念如图16所示。

图16:修正曲线复制三次,最小二乘拟合,使用中心点
图16:修正曲线复制三次,最小二乘拟合,使用中心点

适合计算

复制修正曲线并计算拟合的代码如下:

%%修正曲线的分段线性逼近
Lin_sup_nodes = 32;
%重复修正表三次以避免
%角影响校正计算。
Triple_correction_curve = repmat(correction_curve,3,1);
Triple_correction_curve (end+1) = Triple_correction_curve (1);
%做同样的角度输入
Triple_output_grid = 0:(360/4096):(3*360);
%计算支撑点

YI_lin_triple = lsq_lut_piecewise(triple_output_grid(:),…

%仅使用中心点来计算修正:
(lin_sup_nodes+1: 2*lin_sup_nodes+1);

lsq_lut_piecewise函数在附录A中重述。

32点线性插值的修正参数列表如下:

表3:线性插值参数

请注意,360°的校正参数也显示出来了,尽管它与0°的校正参数相同。这是为了在MATLAB脚本中校正348.75°和360°之间的角度。然而,AAS330x1不单独存储360°值,而是使用0°值。

图17显示了线性化后的输出误差如何随着线性化点数量的增加而减小。当使用32个线性化点时,角度误差变得非常小,表明在AAS330x1中实现的数量是足够的。

图17:本文示例中,随着线性支持节点数量的增加,线性化后的剩余角度误差
图17:线性化后的剩余角度误差
随着线性支持节点数量的增加
本文档中的例子

为了了解如何确定AAS330x1编程参数,我们将首先讨论AAS330x1的硬件功能。

AAS330x1线性化特征

AAS330x1使用32段分段线性逼近存储校正曲线。修正值应用于等距传感器角度0°,11.25°,22.50°,…,348.75°。在这些点之间,在相邻的两个支撑点之间进行线性插值。该传感器在188 ns内执行线性化,这比大多数微控制器快得多
实现。

硬件特性

AAS330x1包含一个偏置级、一个线性化级和一个旋转方向逆变器。如图18所示,偏移量调整可以在线性化之前进行,也可以在线性化之后进行。在本文档中,假设“zal”(线性化后的零点)被设置为“1”,这意味着将在线性化后执行偏移量调整。

图18:简化后的AAS330x1信号路径,“zal”设为“1”
图18:简化后的AAS330x1信号路径,“zal”设为“1”

转动方向

传感器的旋转方向可以反转。如果启用,角度值反转:

分段线性化

分段线性化可以通过将“eli”设置为“1”来启用。如果启用,值“LIN##”从传感器输出以(## / 32)× 360°的角度减去。例如,“LIN10”的值应用于(10 / 32)× 360°= 112.5°。这些角度之间的值在相邻支撑点之间线性插值。例如,115°的修正值将根据“LIN10”和“LIN11”的值来确定。

LIN字段是12位有符号值,以2的补码形式写入。分辨率取决于位“ls”,当“ls”=“0”时分辨率为22.5°/ 2048 LSB,当“ls”=“1”时分辨率为45°/ 2048 LSB。因为它们是从角度中减去的,LIN字段中的负值增加了传感器的角度输出。详情见下表:

表4:为sensor_data记录的编码器和输出角度

例如,如果LIN00的值设置为0xD0F,则这表示十进制值3343 - 212 = - 753。如果“ls”设置为“0”,这等于角度值22.5°/ 2048 LSB × (753 LSB) = -8.27°。这个值将从测量角度中减去,因此对于0°的输入,线性化块将输出0°-(- 8.27°)= +8.27°。

偏移量调整

传感器的偏移调整级将传感器的零值对准外部编码器的零值。它由EEPROM字段“zero_offset”控制,允许写入一个12位的值。这个无符号值表示0°到(4095 / 4096)× 360°之间的角度,从原始角度值中减去360°。



180°旋转

在最后的处理步骤中,传感器输出可以旋转180°:

此功能由偏置级同样可以很好地执行,因此将不使用本文档中的模具旋转功能。

参数计算

了解了传感器的工作原理,表3中描述的修正曲线现在可以用传感器参数表示。这是通过首先使用从数据确定的旋转方向和偏移量的信息来完成的。然后选择线性化参数尺度,确定全线性化值表。

计算AAS330x1参数
% "zal":线性化后的零始终为零
disp(['*** AAS330x1 "zal"参数在EEPROM中应设置为1']);
% "eli":启用线性化始终为1
disp(['*** AAS330x1 EEPROM中的"eli"参数应设置为1']);
%“ro”:如果传感器角度方向为,则应使能模具旋转
减少。
If (raw_direction == -1)
sensor_EEPROM_val_ro = 1;
其他的
sensor_EEPROM_val_ro = 0;
结束
disp(['*** AAS330x1 ' ro '参数在EEPROM中应该设置为'
num2str (sensor_EEPROM_val_ro)]);
% "zero_offset":偏移量设置为最小偏移量和最大偏移量的平均值。
这将充分利用+/-45度的范围
线性化参数。
zero_offset = mean([min(YI_lin) max(YI_lin)]);
从角度数据中减去%传感器偏移量。如果传感器方向为
反转,这发生在角度反转之前,
%,因此在这种情况下传感器偏移量符号必须颠倒
sensor_EEPROM_val_zero_offset = uint16(mod(round(-zero_
抵消/ 360 * 4096),4096));
*** AAS330x1 EEPROM中的"zero_offset"参数应该设置为'
num2str (sensor_EEPROM_val_zero_offset)]);
% "ls":必须根据最大参数设置线性化尺度
值。
线性化_range_small = 22.5 * (2047/2048);
线性化_range_large = 45.0 * (2047/2048);
if round(max(abs(YI_lin - zero_offset))) < linearization_range_small
sensor_EEPROM_val_ls = uint16(0);
elseif round(max(abs(YI_lin - zero_offset))) < linearization_range_large
sensor_EEPROM_val_ls = uint16(1);
其他的
误差('线性化参数在+/-45°范围之外;
线性化不可能’)
结束
disp(['*** AAS330x1 EEPROM中的' ls '参数应该设置为'
num2str (sensor_EEPROM_val_ls)]);
% "LIN_##"参数
if (sensor_EEPROM_val_ls == 0) %小范围为+/- 22.5°
sensor_EEPROM_val_LIN = int16(round((zero_offset-YI_lin(1:lin_sup_ . 0)
节点))/ 22.5 * 2048));
其他%较大范围的+/- 45.0°
sensor_EEPROM_val_LIN = int16(round((zero_offset-YI_lin(1:lin_sup_ . 0)
节点))/ 45.0 * 2048));
结束
dip (['*** AAS330x1 "LIN_##"参数在EEPROM中应设置为
以下值:']);
disp (num2str (sensor_EEPROM_val_LIN));
为Allegro AAS330x1 Samples Programmer编写csv表
EEPtable = cell(38,2);
EEPtable(1,1:2) = {'EEPROM', "};
EEPtable(2,1:2) = {'zal',1};
EEPtable(3,1:2) = {'eli',1};
EEPtable(4,1:2) = {'ro',sensor_EEPROM_val_ro};
EEPtable(5,1:2) = {'zero_offset',sensor_EEPROM_val_zero_offset};
EEPtable(6,1:2) = {'ls',sensor_EEPROM_val_ls};
I = 1:32
EEPtable{6+i,1} = num2str(['线性化错误段' num2str(i- . 1
1, ' % 2 d '));
EEPtable{6+i,2} = num2str(sensor_EEPROM_val_LIN(i));
结束
cell2csv (EEP_table.csv, EEPtable);
在这段代码的最后,函数cell2csv用于编写一个CSV表,该表可以由Allegro AAS33001 / AAS33051 Samples Programmer导入。函数cell2csv在附录b中重印,许多类似的函数都在流传,但提供的函数应该足够了。我们示例的结果表如下:
eepm,
zal 1
伊莱,1
罗依,0
zero_offset 3103
ls, 0
线性化错误段00,-973
线性化误差段01,-1009
线性化误差段02,-981
线性化误差段03,-881
线性化误差段04,-701
线性化误差段05,-492
线性化误差段06,-278
线性化误差段07,-18
线性化误差段08245
线性化误差段09,487
线性化误差段10,701
线性化误差段11,875
线性化误差段12994
线性化误差段13,1009
线性化误差段14,924
线性化误差段15699
线性化误差段16323
线性化误差段17,-54
线性化错误段18,-402
线性化误差段19,-600
线性化误差段20,-707
线性化误差段21,-744
线性化误差段22,-694
线性化误差段23,-627
线性化误差段24,-558
线性化误差段25,-474
线性化误差段26,-428
线性化误差段27,-411
线性化误差段28,-494
线性化误差段29,-578
线性化误差段30,-748
线性化误差段31,-865

性能评估

在仿真中可以估计使用参数线性化后的精度。为此,需要将确定的线性化参数应用到仿真中,并可选择方向反转:

在MATLAB中执行线性化
Restored_linear_signal = mod(raw_direction*sensor_data(:) +…

%%绘制MATLAB中线性化后的剩余误差
图;
情节(angle_input(:),国防部(180 + restored_linear_signal (:) -angle_input (:), 360)
180年,'。');
图例('线性插值(32段)');
xlim (360 [0]);ylim ([1]);
xlabel('测量角度[度]');
ylabel('线性化后的预期误差[deg]');
图19为AAS330x1线性化后的预期角度误差:
图19:使用本文档中描述的AAS330x1线性化后的剩余角度误差,以本文档中的示例为准
图19:线性化后的剩余角度误差
使用本文档中描述的AAS330x1,
对于本文档中的示例

结论

本文解释了线性化背后的理论,并描述了如何进行校正的线性逼近。

AAS33001和AAS33051允许分段线性化。这种线性化方法在0.2 μs内由传感器完成,在32段内具有很好的精度。

使用本文档,任何用户都应该能够确定AAS33001和AAS33051的最佳线性化参数。

如有任何问题或支持,请联系Allegro代表。

附录a:函数lsq_lut_piecewise

https://uk.mathworks.com/matlabcentral/fileexchange/40913-piecewise-linear-least-square-fit。

版权所有(c) 2013, Guido Albertin

版权所有。

在满足以下条件的前提下,允许以源代码和二进制形式重新分发和使用,无论是否修改:

*重新发布源代码必须保留上述版权声明、此条件列表和以下免责声明。

*以二进制形式重新发布必须在发布时提供的文件和/或其他材料中复制上述版权声明、此条件列表和以下免责声明

本软件由版权所有者和贡献者“按原样”提供,任何明示或默示保证,包括但不限于对适销性和适合特定目的的默示保证。在任何情况下,版权所有者或贡献者都不对任何直接、间接、附带、特殊、惩戒性或后果性损害负责(包括但不限于采购替代商品或服务;丧失使用、数据或利润;或业务中断),无论造成何种原因,并在任何责任理论,无论是在合同,严格责任,或侵权行为(包括疏忽或其他),以任何方式使用本软件,即使被告知这种损害的可能性。


用于1-D插值的分段线性插值(查找表)

%向量用于线性插值例程。
目标是在给定X的条件下求函数的最小值。


%的输入
% x测量数据向量
% y测量数据向量


%输出
YI个1-D表插值点


如果size(x,2) ~= 1
错误('向量x必须具有n x 1的维数');
Elseif size(y,2) ~= 1
错误('向量y必须有维数n x 1.');
Elseif size(x,1) ~= size(x,1)
错误('向量x和y必须具有n x 1的维数');
结束
%矩阵定义由x个测量值
A = sparse([]);
%向量为y的测量值
Y = [];



%检查bin中是否有数据点
如果~(第九)
sprintf('Bin [%f %f]没有数据点,请检查估计。

结束
%获取x和y数据子集
X_ = x(ix);
Y_ = y(ix);
%创建临时矩阵添加到A

建立约束条件下的测量矩阵
(m1, n1) = (A)大小;
(m2, n2) = (tmp)大小;
A = [A零(m1, n1-1)];[零(m2,n1-1) tmp]];
连接bin的y个测量值
Y = [Y;y_];
结束
得到Y的最小二乘估计
易= \ Y;

附录b:函数cell2csv

基于https://uk.mathworks.com/matlabcentral/fileexchange/7601-cell2csv

函数cell2csv(文件名、cellArray分隔符)
将单元格数组内容写入*.csv文件。

% CELL2CSV(文件名、cellArray分隔符)

% filename =要保存的文件名。(即。' text.csv ']
% cellarray =数据所在的单元格数组的名称
% delimiter =分隔符,通常为','(默认值)

Sylvain Fiedler, KA, 2004
%由Rob Kohr修改,Rutgers, 2005 -更改为英语和固定分隔符
%由Dominik Geisler修改,Allegro Mic亚博棋牌游戏roSystems, 2018年-删除“eval”功能
如果输入参数个数< 3
分隔符= ',';
结束
File = fopen(filename,'w');
对z = 1:尺寸(cellArray, 1)
s = 1:尺寸(cellArray, 2)
var = cellArray{z,s};
如果size(var,1) == 0
Var = ";
结束
如果isnumeric(var) == 1
Var = num2str(Var);
结束
流(文件,var);
if s ~= size(cellArray,2)
流(文件,(分隔符));
结束
结束
流(文件,' \ n ');
结束
文件关闭(文件);

附录c:本应用注释中使用的功能完整脚本

版权所有(c) 2018, Dominik Geisler, Allegr亚博棋牌游戏o MicroSystems Germany GmbH

版权所有。

在满足以下条件的前提下,允许以源代码和二进制形式重新分发和使用,无论是否修改:

*重新发布源代码必须保留上述版权声明、此条件列表和以下免责声明。

*以二进制形式重新发布必须在发布时提供的文件和/或其他材料中复制上述版权声明、此条件列表和以下免责声明

本软件由版权所有者和贡献者“按原样”提供,任何明示或默示保证,包括但不限于对适销性和适合特定目的的默示保证。在任何情况下,版权所有者或贡献者都不对任何直接、间接、附带、特殊、惩戒性或后果性损害负责(包括但不限于采购替代商品或服务;丧失使用、数据或利润;或业务中断),无论造成何种原因,并在任何责任理论,无论是在合同,严格责任,或侵权行为(包括疏忽或其他),以任何方式使用本软件,即使被告知这种损害的可能性。

%%传感器数据定义
Angle_input = [0:11. 25:38 .75];
Sensor_data = [266.31 278.61 290.39 301.99 312.45 323.00 332.75 342.69 352.79 3.16 14.24 26.02 38.94 52.91 67.15 82.18 97.12 111.45 124.98 137.46 148.62 158.82 .
167.96 176.48 184.48 192.92 201.27 210.50 220.43 230.98 242.31 254.36];
检查上升参考角
If any(angle_input<0) || any(angle_input>360) || any(diff(angle_input)<=0)
误差('参考角度必须在0到360之间单调上升');
结束
检查正确的传感器角度范围
If any(sensor_data<0) || any(sensor_data>360)
错误('传感器角度必须在0到360之间');
结束
% %预处理
Sensor_data_2 = sensor_data(:);
%检查是否连续上升/下降,最大溢出一次
If any(diff(sensor_data_2) == 0)
错误('传感器数据必须是单调增加或减少')
Elseif sum(diff(sensor_data_2) < 0) <= 1
%上升角数据有零或一次溢出,溢出将被纠正
Sensor_data_2 = Sensor_data_2 (:) + 360*cumsum([false;Diff (sensor_data_2(:)) < 0]);
Elseif sum(diff(sensor_data_2) > 0) <= 1
%下降角数据有零或一次溢出,溢出将被纠正
Sensor_data_2 = Sensor_data_2 (:) - 360*cumsum([false;Diff (sensor_data_2(:)) > 0]);
其他的
错误('只允许一个数据溢出')
结束
%倒角方向,如果需要
If all(diff(sensor_data_2) < 0)
Disp('反转角度方向…')
Sensor_data_2 = -sensor_data_2;
Raw_direction = -1;
Elseif all(diff(sensor_data_2) > 0)
Raw_direction = +1;
其他的
错误(“检测到非单调角度变化”)
结束
%正确包装传感器数据
rolovercorrection = round((mean(sensor_data_2) - 180)/360) * 360;
Sensor_data_2 = Sensor_data_2 -翻转校正;
扩展传感器数据
Sensor_data_ext = [sensor_data_2(:);sensor_data_2 (:) + 360;...
sensor_data_2 (:) + 720];
扩展输入数据
Angle_input_ext = [angle_input(:);angle_input (:) + 360;...
angle_input (:) + 720];
%%绘图磁铁测量后,预处理完成
人物,情节([angle_input (:)), [sensor_data_2(:)),“啊——”);
xlabel('编码器角度[deg]');
ylabel('输出角度[deg]');
网格;
xlim (360 [0]);
If (raw_direction == +1)
title('输出字段方向高于编码器方向');
其他的
title('方向反转后输出字段方向超过编码器方向');
结束
%%使用样条从有序的输入网格中移动数据
%到有序的输出网格上:
Ordered_output_grid = 0:(360/4096):(360-360/4096);
Intermediategrid = ordered_output_grid + 360;
投影=样条(sensor_data_ext, angle_input_ext,…
intermediategrid);
%计算所需的数据修正:
Correction_curve = projection - intermediategrid;
Correction_curve = Correction_curve (:);
%%修正曲线的分段线性逼近
Lin_sup_nodes = 32;
%重复修正表三次以避免
%角影响校正计算。
Triple_correction_curve = repmat(correction_curve,3,1);
Triple_correction_curve (end+1) = Triple_correction_curve (1);
%做同样的角度输入
Triple_output_grid = 0:(360/4096):(3*360);
%计算支撑点

YI_lin_triple = lsq_lut_piecewise(triple_output_grid(:),…

%仅使用中心点来计算修正:
(lin_sup_nodes+1: 2*lin_sup_nodes+1);

计算AAS330x1参数
% "zal":线性化后的零始终为零
disp(['*** AAS330x1 "zal"参数在EEPROM中应设置为1']);
% "eli":启用线性化始终为1
disp(['*** AAS330x1 EEPROM中的"eli"参数应设置为1']);
%“ro”:如果传感器角度方向减小,则应启用模具旋转。
If (raw_direction == -1)
sensor_EEPROM_val_ro = 1;
其他的
sensor_EEPROM_val_ro = 0;
结束
disp(['*** AAS330x1 "ro"参数在EEPROM中应该设置为' num2str(sensor_EEPROM_val_ro)]);
% "zero_offset":偏移量设置为最小偏移量和最大偏移量的平均值。
这将充分利用线性化参数的+/-45度范围。
zero_offset = mean([min(YI_lin) max(YI_lin)]);
从角度数据中减去%传感器偏移量。如果传感器方向反转,则这发生在角度反转之前,
%,因此在这种情况下传感器偏移量符号必须颠倒
sensor_EEPROM_val_zero_offset = uint16(mod(round(-zero_offset/360*4096),4096));
disp(['*** AAS330x1 "zero_offset"参数在EEPROM应该设置为' num2str(sensor_EEPROM_val_zero_offset)]);
% "ls":必须根据最大参数值设置线性化尺度。
线性化_range_small = 22.5 * (2047/2048);
线性化_range_large = 45.0 * (2047/2048);
if round(max(abs(YI_lin - zero_offset))) < linearization_range_small
sensor_EEPROM_val_ls = uint16(0);
elseif round(max(abs(YI_lin - zero_offset))) < linearization_range_large
sensor_EEPROM_val_ls = uint16(1);
其他的
误差('线性化参数在+/-45°范围之外;线性化不可能’)
结束
disp(['*** AAS330x1 "ls"参数在EEPROM应该设置为' num2str(sensor_EEPROM_val_ls)]);
% "LIN_##"参数
if (sensor_EEPROM_val_ls == 0) %小范围为+/- 22.5°
sensor_EEPROM_val_LIN = int16(round((zero_offset-YI_lin(1:lin_sup_nodes))/22.5*2048));
其他%较大范围的+/- 45.0°
sensor_EEPROM_val_LIN = int16(round((zero_offset-YI_lin(1:lin_sup_nodes))/45.0*2048));
结束
disp(['*** AAS330x1 "LIN_##"在EEPROM中的参数应设置为以下值:']);
disp (num2str (sensor_EEPROM_val_LIN));
为Allegro AAS330x1 Samples Programmer编写csv表
EEPtable = cell(38,2);
EEPtable(1,1:2) = {'EEPROM', "};
EEPtable(2,1:2) = {'zal',1};
EEPtable(3,1:2) = {'eli',1};
EEPtable(4,1:2) = {'ro',sensor_EEPROM_val_ro};
EEPtable(5,1:2) = {'zero_offset',sensor_EEPROM_val_zero_offset};
EEPtable(6,1:2) = {'ls',sensor_EEPROM_val_ls};
I = 1:32
EEPtable{6+i,1} = num2str(['线性化错误段' num2str(i-1,'%02d')]);
EEPtable{6+i,2} = num2str(sensor_EEPROM_val_LIN(i));
结束
cell2csv (EEP_table.csv, EEPtable);
在Matlab中执行线性化
Restored_linear_signal = mod(raw_direction*sensor_data(:) +…

%%绘制Matlab中线性化后的剩余误差
图;
情节(angle_input(:),国防部(180 + restored_linear_signal (:) -angle_input(:), 360) -180年,'。');
图例('线性插值(32段)');
xlim (360 [0]);ylim([-1 1]);xlabel('测量角度[deg]');
ylabel('线性化后的预期误差[deg]');

版权所有©2018,Allegro亚博棋牌游戏 MicroSystems, LLC

本文件中包含的信息不构成Allegro就本文件主题事项对客户的任何陈述、保证、保证、担保或诱导。所提供的信息并不能保证基于这些信息的流程是可靠的,也不能保证Allegro已经探索了所有可能的故障模式。客户有责任对最终产品进行充分的合格测试,以确保其可靠并满足所有设计要求。