具有ASEK DLL谐波线性化的高级编程

具有ASEK DLL谐波线性化的高级编程

Download PDF Version

By K. Robert Bate,
Allegro MicroSystems, LLC

Introduction

Numerous applications in industries spanning from industrial automation and robotics, to electronic power steering and motor position sensing require monitoring the angle of a rotating shaft either in an on-axis or off-axis arrangement.

在设计中使用磁铁时,磁性输入很可能在整个旋转范围内均匀 - 它将具有固有的误差。这些磁输入误差会导致系统中的测量误差。线性化可以减少这些输入错误。

可提供一种形式的线性化A1332A1335harmonic 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

All of the software was developed on Microsoft Visual Studio 2010 using .NET 4.0. Download the Command Library (C#/.NET) for the device that you are going to use and add to the project references to the three DLLs that it contains.

Collecting the Data

First, turn off all post-linearization algorithmic processing; this includes ZeroOffset, Post-Linearization Rotation (RO), Short Stroke Inversion (IV), and the Rotate Die bit (RD). Prelinearization adjustments may be left on, such as ORATE settings, IIR filter (FI), and Prelinearization Rotation (LR).

Move the encoder in the direction of increasing angle position. If the angle sensor IC output does not also increase, then either set the LR bit to reverse the direction of the angle sensor IC output or rotate the encoder in the opposite direction for calibration, in which case the Post-Linearization Rotate bit (RO) will likely need to be set. See the A1332/ A1335 programming reference for more details.

最佳收集方法是以等间隔的步骤旋转目标,使得所得到的数据点的数量是2.通常,32或64个均匀间隔的数据点足够。如果无法完成此操作,则收集点,并且如下一部分中所讨论的,必须预处理数据。

Another technique to gather the required data points is to rotate the target many times, collecting the data at a predefined interval. Once enough points have been gathered to cover the entire rotation of the target, then they must be preprocessed as discussed in the next section.

Preprocessing the Data

如果收集的数据点的数量不是两个的功率,或者收集的数据不等等地间隔,则必须调整点阵列和/或使得恰好间隔。要对数据执行此操作,请调用例程resizepointarray。

x参数是编码器值阵列,y参数是在该编码器值收集的设备读数。参数Newsize是调整大小阵列的所需大小。如果x参数设置为null,则假定y值以0开始于0开始,并在360处结束。如果x参数未为空,则在执行调整大小之前将排序输入阵列。

Double [] ResizePointarray(Double [] x,Double [] Y,Int Newsize)

This routine will perform a cubic-spline interpolation on the input arrays to generate an equal-spaced array with the desired number of points.

初始处理

Once the data has been collected and made into an array of a length which is a power of 2, then the harmonic coefficients are ready to be calculated. To calculate the coefficients, call the routine CalculateHarmonicLinearCoefficients.

HarmonicCoeffient [] CalculateHarmonicLoceAlcofience(Double []点,Bool PigetError)

其输入是已收集的角度阵列。例程执行FFT,并将返回系数数组和警告标志。当一个或多个输入角度大于20度不同的输入角度与例程计算它应该是相差时,设置点错误警告标志。

For example, for an 8 entry array, the routine calculates that the angles should be [0, 45, 90, 135, 180, 225, 270, 315]. If the input array is [0, 45, 90, 135, 180, 204, 270, 315], then the routine will set the pointError because the 6th array entry has an error greater than 20 degrees.

选择谐波

一旦计算了所有谐波系数,必须选择所需的谐波。通常,计算例程生成的谐波数将超过设备可以支持的谐波数量,因此必须选择一些选择相关谐波的算法。

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 simplest algorithm to use is to select the first harmonic through to the desired number of harmonics. While easy, it will select harmonics that will not significantly influence the output.

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 []生成哈卡卡猴弹性DeviceValues(HasbonicCoefients []系数)

谐波系数被传递到该例程中,并且它返回编程设备所需的值的数组。此例程将抛出的唯一例外情况是在所选系数之间跳过超过4个谐波系数的情况。

要为谐波线性化进行编程,必须设置HL标志,必须将HAR_MAX字段设置为要使用的系数数,并且必须写入谐波_PUSE_N,ADV_N和HARMONIC_AMPLUTION_N字段。

示例代码

using System;
using Allegro.ASEK;

namespace HarmonicLinearizationExample
{
public class HarmonicLinearizationExample
{
public HarmonicLinearizationExample()
{
}

公共void程序armonearization(String Filepath,Asek Asekprogrammer)
{
try
{
HarmonicCoefficients[] hc;
bool pointError = false;
double[] points = null;
string fieldBuffer = File.ReadAllText(filePath);
string line;
List encoderReadings = new List();
List deviceReadings = new List();

// 1.1 Collecting the data
// Read in the angles from a text file. Blank lines or lines starting with a # are ignored.
if (!string.IsNullOrEmpty(fieldBuffer))
{
使用(stringReader SR = New StringReader(FieldBuffer))
{
而((line = sr.readline())!= null)
{
line = line.trim();
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(‘,’);

if(值.Length> 1)
{
double encoder = Convert.ToDouble(values[0]);
while (encoder >= 360.0)
{
编码器 - = 360.0;
}
而(编码器<0.0)
{
encoder += 360.0;
}
encoderReadings.Add(encoder);
devicereadings.add(convert.todouble(值[1]));
}
else
{
devicereadings.add(convert.todouble(值[0]));
}
}
}

// 1.2预处理数据
if(!Poweroftwo(devicereadings.count()))
{
//如果点数为OFF,则只需删除最后一个,
if(poweroftwo(devicereadings.count.count() - 1))
{
deviceReadings.RemoveAt(deviceReadings.Count() - 1);
点= devicereadings.toArray();
}
else
{
// otherwise calculate the number of desired samples.
// If the number of samples is less then 64 then round
//最多两个,否则圆润。
int iscandsamples = 8;
while (desiredSamples < deviceReadings.Count())
{
desiredSamples *= 2;
}

if(devicereadings.count()> 64)
{
jailenceSamples / = 2;
}

// If there are no encoder readings, assume the devices readings are equally spaced.
if(encoderreadings.count()!= devicereadings.count())
{
// Convert the list of angles to an array and then resize it.
点=((iHarmoniclineArization)ASekprogrammer).resizepointarray(null,devicereadings.toArray(),希望的arample);
}
else
{
// Convert the list of angles to an array and then resize it.
points = ((IHarmonicLinearization)asekProgrammer).ResizePointArray(encoderReadings.ToArray(), deviceReadings.ToArray(), desiredSamples);
}
}
}
else
{
// Convert the list of angles to an array
点= devicereadings.toArray();
}

// 1.3初始处理
// Calculate the coefficients from the array of points.
hc = ((IHarmonicLinearization)asekProgrammer).CalculateHarmonicLinearCoefficients(points, out pointError);

// 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
/ /条目数组中,因为它应该更紧密to 225 than it is.
if (pointError)
{
MessageBox.show(“其中一个角度从所需的内容越多20度。”);
}

// 1.4 Selection of Harmonics
//一旦计算了谐波系数阵列,需要选择系数。系数的数量
//计算例程返回通常超过设备可以支持的系数数量,这使得一些限制数量的方法
// of coefficents is needed. The first 8 could be picked or another method could be used.
int numberOfHarmonicComponents = hc.Length;
int numberOfSelectedHarmonicComponents = 0;
int lastHarmonicComponentSelected = 0;
int maxHarmonicComponentsSelected = 8; // maximum number of harmonics that can be used before impacting other features on the device

// For this example, the first 8 harmonics where the amplitude exceed 0.3 are selected.
for(int index = 0; index {
if((hc [index] .amplitude> 0.3)&&(numberofselectedharmoniccomponents {
//如果要选择的谐波之间的谐波数量
//选择的最后一个谐波更大,然后4然后一些
//需要选择谐波。
int skip = index - lastharmoniccomponentselect;
如果(跳过> 4)
{
//确保需要选择的谐波数量
// does not exceed the number that is desired.
int numberNeeded = skip / 4;
if((numberneededed + numberofselectedharmoniccomponents)<= maxharmoniccomponentsselect)
{
for(int jndex = 1; jndex <= number4eded; ++ jndex)
{
hc [jndex] .select = true;
++numberOfSelectedHarmonicComponents;
}
hc [index] .select = true;
++numberOfSelectedHarmonicComponents;
}
else
{
//代码无法在不超过的情况下选择所需的谐波
//选择的最大系数数,因此它将停止选择。
break;
}
}
else
{
hc [index] .select = true;
++numberOfSelectedHarmonicComponents;
}
LastharmonicComponentselect =指数;
}
}

//如果没有选择谐波,则选择前8个。
if (numberOfSelectedHarmonicComponents == 0)
{
for (int i = 0; (i < numberOfHarmonicComponents) && (numberOfSelectedHarmonicComponents < 8); ++i)
{
hc[i].select = true;
++numberOfSelectedHarmonicComponents;
}
}

// 1.5编程设备
//生成要写入EEPROM所需的值。
HarmonicDeviceValues [] EEPROMVALUES =((IHARMONICLINARIZEARIZE)ASEKPROGGRAMMAMER).generateHarmonicLIZAZEVICEVALUES(HC);

//确保设备上的电源
asekProgrammer.SetVcc(5.0);

// Enable writing to the device’s eeprom, this requires making the SRAM writable and to stop the processor
((ISRAMWriteAccessMode)asekProgrammer).SetSRAMWriteAccessMode();
((iProcessorMode)ASekprogrammer).setprocessoridle();

//在EEPROM中打开谐波线性化
((iRegisterAccess)ASekprogrammer).writepartialRegister(MeminityAccessType.extended,0x306,15,15);// hl = 1

// Set the number of harmonics to be used
((IRegisterAccess)asekProgrammer).WritePartialRegister(MemoryAccessType.extended, 0x309, eepromValues.Length, 19, 16); // HAR_MAX = number of harmonics

// For the harmonics
for (uint index = 0; index < eepromValues.Length; ++index)
{
uint registerValue = (uint)(((eepromValues[index].phase << 12) & 0x0FFF000) +
((EEPROMVALUES [INDEX] .Advance << 10)&0x0C00)+
(EEPROMVALUES [索引] .AMPLUTY&0x03FF));
((IRegisterAccess)asekProgrammer).WriteRegister(MemoryAccessType.extended, 0x30C + index, registerValue); // HARMONIC_PHASE, ADV and HARMONIC_AMPLITUDE
}

// Turn the power off then back on to make sure the device is using the new linearization values.
asekprogrammer.setvccoff();
asekProgrammer.SetVcc(5.0);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}

私人BOOL Poweroftwo(INT值)
{
int log2npoints = 0;
int j = value;

while ((j > 0) && ((j & 1) == 0)) // Compute log base 2 of input value
{
log2npoints ++;
j >> = 1;
}

if ((value < 2) || (value != (1 << log2npoints)))
{
返回false;
}

return 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

With two columns:

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