ASEK-DLLs谐波线性化高级程序设计
ASEK-DLLs谐波线性化高级程序设计
作者:K.Robert Bate,
雷竞技竞猜下载Allegro微系统有限责任公司
Introduction
从工业自动化和机器雷竞技最新网址人技术,到电子动力转向和电机位置传感,工业中的许多应用都要求在轴上或轴外布置中监测转轴的角度。
在设计中使用磁铁时,磁输入很可能在整个旋转范围内不均匀,这将产生固有误差。这些磁输入误差会导致系统中的测量误差。线性化可以减少这些输入误差。
一种形式的线性化可在A1332型andA1335型,harmonic linearizationapplies linearization in the form of up to 15 correction harmonics whose phase and amplitude are determined by means of an FFT (fast Fourier transform) performed on the data collected from one rotation of the magnet around the angle sensor IC. This technique can be readily implemented using Allegro-provided software to calculate coefficients and program on-chip EEPROM. This application note describes the functions and the process flow the customer can use if the Allegro-provided software is not flexible enough or if custom software is to be used.
Programming Requirements
所有软件都是在Microsoft Visual Studio 2010上使用.NET 4.0开发的。下载要使用的设备的命令库(C#/.NET),并将对其中包含的三个dll的引用添加到项目中。
Collecting the Data
首先,关闭所有后线性化算法处理;这包括零偏移、后线性化旋转(RO)、短冲程反转(IV)和旋转模具位(RD)。预线性化调整可以保持开启状态,例如:初始设置、IIR滤波器(FI)和预线性化旋转(LR)。
向增加角度位置的方向移动编码器。如果角度传感器IC输出也没有增加,则设置LR位以反转角度传感器IC输出的方向,或以相反方向旋转编码器进行校准,在这种情况下,可能需要设置后线性化旋转位(RO)。有关更多详细信息,请参阅A1332/A1335编程参考。
最佳的采集方法是以等间距的步数旋转目标,这样得到的数据点的数量是2的幂。通常,32或64个均匀分布的数据点就足够了。如果这无法完成,则收集点,并且数据必须按照下一节中的讨论进行预处理。
另一种收集所需数据点的技术是多次旋转目标,以预定义的间隔收集数据。一旦收集到足够的点来覆盖目标的整个旋转,就必须对它们进行预处理,如下一节所述。
Preprocessing the Data
如果收集的数据点的数量不是2的幂,或者收集的数据不是等间距的,则必须调整点阵列的大小和/或使其等间距。要对数据执行此操作,请调用例程ResizePointArray。
x参数是编码器值的数组,y参数是在该编码器值处收集的设备读数。参数newSize是调整大小的数组所需的大小。如果x参数设置为null,则假设y值是以从0开始到360结束的相等间距收集的。如果x参数不为null,则在执行调整大小之前对输入数组进行排序。
double[]ResizePointArray(double[]x,double[]y,int newSize)
此例程将对输入阵列执行三次样条插值,以生成具有所需点数的等间距阵列。
初始处理
一旦数据被收集并形成一个长度为2的幂的数组,那么谐波系数就可以计算了。要计算系数,请调用例程CalculateHarmonicLinearCoefficients。
谐波效率[]计算谐波线性系数(双[]点,输出布尔点错误)
它的输入是已收集的角度数组。例程执行FFT并返回系数数组和警告标志。当一个或多个输入角度与例程计算的角度相差超过20度时,将设置点错误警告标志。
例如,对于8条目数组,例程计算角度应为[0、45、90、135、180、225、270、315]。如果输入数组为[0、45、90、135、180、204、270、315],则例程将设置pointError,因为第6个数组条目的误差大于20度。
谐波的选择
一旦计算了所有谐波系数,就必须选择所需的谐波。一般来说,计算程序产生的谐波数量会超过设备所能支持的谐波数量,因此必须选择一些算法来选择相关的谐波。
The number of harmonics used is also dependent on which device and which features are used. For the A1332, the maximum number of harmonics is 15, but if the maximum is used, a number of programmable features will use the defaults, such as short-stroke configurations and specific I2C and SPI settings. The maximum number of harmonics without using the defaults for those programmable features is 9. For the A1335, the maximum number of harmonics is 11, but to get this number, a number of programmable features will use the defaults, such as the short-stroke settings. The maximum number of harmonics without using the defaults for those programmable features is 8.
使用最简单的算法是选择一次谐波到所需的谐波数。虽然容易,它将选择谐波,将不会显着影响输出。
The current algorithm that is used in the Allegro A1335 Samples Programmer is to select the harmonic where the amplitude is greater than 0.3. One limitation in the current hardware to note is that only 4 harmonics can be skipped between selected harmonics. If there is a jump greater than 4, then as many harmonics as needed between the last harmonic selected and the desired harmonic also need to be selected.
对设备进行编程
Once the harmonics have been selected, then the values to be written into the device can be generated by calling the routine GenerateHarmonicLinearizationDeviceValues.
HarmonicDeviceValues[]GenerateHarmonicLinearizationDeviceValues(HarmonicEfficients[]系数)
谐波系数被传递到这个例程中,它返回编程设备所需的值的数组。此例程将抛出的唯一例外是在选定系数之间跳过的谐波系数超过4个的情况。
要对设备进行谐波线性化编程,必须设置HL标志,必须将HAR\u MAX字段设置为要使用的系数数,并且必须写入谐波相位、ADV\u n和谐波振幅字段。
Example Code
using System;
using Allegro.ASEK;
命名空间协调化示例
{
公共类协调示例
{
公共和谐实例()
{
}
public void ProgramHarmonicLinearization(字符串文件路径,ASEK asekProgrammer)
{
try
{
HarmonicCoefficients[] hc;
bool pointError = false;
double[]points=空;
string fieldBuffer = File.ReadAllText(filePath);
弦线;
List
List
//1.1收集数据
/ /读角从一个文本文件。空行s or lines starting with a # are ignored.
if (!string.IsNullOrEmpty(fieldBuffer))
{
使用(StringReader sr=new StringReader(fieldBuffer))
{
while((行=高级读线()) !=空)
{
直线=线条。修剪();
if (string.IsNullOrEmpty(line) || line.StartsWith("#"))
{
continue;
}
// Each line can be in 1 of 2 forms.
// The first contains an encoder angle then the angle from the device separated by a comma (22.125,23.543)
//或者只是设备的角度。(23.543)
//如果角度的间距不相等,则需要两个值。
string[] values = line.Split(‘,’);
如果(值。长度> 1)
{
双编码器=转换.ToDouble(值[0]);
while (encoder >= 360.0)
{
编码器-=360.0;
}
while(编码器<0.0)
{
编码器+=360.0;
}
encoderReadings.Add(encoder);
deviceReadings.添加(转换.ToDouble(值[1]);
}
其他的
{
deviceReadings.添加(转换.ToDouble(值[0]);
}
}
}
//1.2数据预处理
如果(!二的力量(恶魔之旅。数一数()))
{
//如果点数减少了一,就去掉最后一个,
if(两次幂)(恶魔之旅。数一数() - 1))
{
deviceReadings.RemoveAt设备(恶魔之旅。数一数() - 1);
points = deviceReadings.ToArray();
}
其他的
{
// otherwise calculate the number of desired samples.
// If the number of samples is less then 64 then round
//最接近二的幂,否则四舍五入。
int desiredSamples=8;
while(所需样品<恶魔之旅。数一数())
{
desiredSamples *= 2;
}
如果(恶魔之旅。数一数() > 64)
{
所需样品/=2;
}
// If there are no encoder readings, assume the devices readings are equally spaced.
如果(编码器读取计数() != 恶魔之旅。数一数())
{
//将角度列表转换为数组and then resize it.
points=((IHarmonicLinearization)asekProgrammer).ResizePointArray(null,deviceReadings.ToArray公司(),所需样品);
}
其他的
{
//将角度列表转换为数组and then resize it.
点=((IHarmonicLinearization)asekProgrammer).ResizePointArray(编码器Readings.ToArray(), deviceReadings.ToArray公司(),所需样品);
}
}
}
其他的
{
//将角度列表转换为数组
points = deviceReadings.ToArray();
}
//1.3初始处理
//从点阵列计算系数。
hc=((i谐波线性化)asekProgrammer)。计算谐波线性系数(点,输出点误差);
// A point error is what happens when one or more of the angles is more then 20 degrees different then what the routine thinks it should be.
// For example if an array of 8 values is to be used [0, 45, 90, 135, 180, 204, 270, 315] the calculate would flag a warning for the 6th
//因为它应该比实际值更接近225。
if(点错误)
{
MessageBox.显示(“其中一个角度与所需角度相差超过20度。”);
}
// 1.4 Selection of Harmonics
//一旦计算出谐波系数的数组,就需要选择系数。系数的个数
// the calculate routine returns will generally exceed the number of coefficients the devices can support so some method of limiting the number
//需要系数。可以选择前8个,也可以使用其他方法。
谐波分量的整数=hc.长度;
int numberOfSelectedHarmonicComponents = 0;
int lastHarmonicComponentSelected = 0;
int maxHarmonicComponentsSelected = 8; // maximum number of harmonics that can be used before impacting other features on the device
//对于本例,选择振幅超过0.3的前8个谐波。
for(int index=0;index
if((hc[指数]。振幅>0.3)&&(所选谐波分量数<所选最大谐波分量))
{
//如果要选择的谐波之间的谐波数
//最后选择的谐波大于4
//然后需要选择两者之间的谐波。
int skip=索引-最后选定的HarmonicComponent;
如果(跳过>4)
{
//确保需要选择的谐波数
//不超过所需的数量。
int numberNeeded = skip / 4;
if((numberneed+numberOfSelectedHarmonicComponents)<=maxHarmonicComponentsSelected)
{
for(int jndex=1;jndex<=numberneed;++jndex)
{
hc[jndex].select=true;
++所选谐波分量的数量;
}
hc[index].select=true;
++所选谐波分量的数量;
}
其他的
{
//代码无法选择所需的谐波而不超过
//选择的最大系数数,因此它将停止选择。
中断;
}
}
其他的
{
hc[index].select=true;
++所选谐波分量的数量;
}
lastHarmonicComponentSelected=索引;
}
}
// If there are no harmonics selected, then select the first 8.
if(numberOfSelectedHarmonicComponents==0)
{
对于(int i=0;(i
hc[i].select = true;
++所选谐波分量的数量;
}
}
//1.5设备编程
//生成需要写入eeprom的值。
HarmonicDeviceValues[]eepromValues=((IHarmonicLinearization)asekProgrammer).GenerateHarmonicLinearizationDeviceValues(hc);
//确保设备的电源已打开
asekProgrammer.SetVcc(5.0);
//启用写入设备的eeprom,这需要使SRAM可写并停止处理器
((ISRAMWriteAccessMode)asekProgrammer).设置ramWriteAccessMode();
((ipProcessorMode)asekProgrammer).SetProcessorIdle();
//在eeprom中开启谐波线性化
((IRegisterAccess)asekProgrammer).写入部分寄存器(MemoryAccessType.extended文件,0x306,1,15,15);//HL=1
//设置要使用的谐波数
((IRegisterAccess)asekProgrammer).写入部分寄存器(MemoryAccessType.extended文件,0x309,EEPROM值。长度,19,16);//HAR_MAX=谐波数
//对于谐波
for (uint index = 0; index < eepromValues.Length; ++index)
{
uint registerValue = (uint)(((eepromValues[index].phase << 12) & 0x0FFF000) +
((eepromValues[index].advance<<10)和0x0C00)+
(eepromValues[index].amplitude & 0x03FF));
((IRegisterAccess)asekProgrammer).WriteRegister(MemoryAccessType.extended, 0x30C + index, registerValue); // HARMONIC_PHASE, ADV and HARMONIC_AMPLITUDE
}
//关闭电源,然后重新打开,以确保设备使用新的线性化值。
asekProgrammer.SetVccOff文件();
asekProgrammer.SetVcc(5.0);
}
}
catch (Exception ex)
{
MessageBox.显示(例如消息);
}
}
私有bool powerOfTwo(int值)
{
int log2npoints = 0;
int j = value;
while((j>0)&&((j&1)==0))//计算输入值的对数基2
{
log2npoints++;
j>>=1;
}
if((值<2)| |(值!=(1<
返回false;
}
返回true;
}
}
}
角度输入文件格式
This file contains a list of angle values. If there are two values separated by a comma, then the first value is the encoder angle and the second value is the device angle. Lines can be blank, or if they start with #, then they are considered comments.
角度输入文件示例:
329.59
354.81
6.832
13.566
17.592
20.228
22.638
24.638
25.956
27.454
28.77
30.054
30.966
有两列:
0,123
22.5,145.5
45,168
67.5,190.5
90,213
112.5,235.5
135,258
157.5,280.5
180,303
202.5,325.5
225,348
247.5,10.5
270,33
292.5,55.5
315,78
337.5,100.5