用ASEK dll进行高级编程

用ASEK dll进行高级编程

下载版本

作者:k·罗伯特·贝特
雷竞技竞猜下载快板微系统公司有限责任公司

简介

从工业自动化和机器雷竞技最新网址人,到电子动力转向和电机位置传感,许多行业的应用都需要监测转轴在轴上或轴外的角度。

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

线性化的一种形式是A1332而且A1335谐波线性化采用线性化的形式,最多15个校正谐波,其相位和振幅由FFT(快速傅立叶变换)对围绕角度传感器IC旋转的磁铁收集的数据进行确定。该技术可以很容易地使用allegro提供的软件计算系数和芯片上的EEPROM程序来实现。当allegro提供的软件不够灵活或者需要使用定制软件时,此应用说明描述了客户可以使用的功能和流程。

编程需求

所有的软件都是在Microsoft Visual Studio 2010上使用。net 4.0开发的。下载您将要使用的设备的命令库(c# /. net),并向项目中添加对其中包含的三个dll的引用。

收集数据

首先,关闭所有后线性化算法处理;这包括零偏移,后线性化旋转(RO),短行程反转(IV)和旋转模位(RD)。预线性化调整可以保留,如oror设置,IIR滤镜(FI)和预线性化旋转(LR)。

向增加角度位置的方向移动编码器。如果角度传感器IC输出也没有增加,那么要么设置LR位以反转角度传感器IC输出的方向,要么将编码器向相反的方向旋转进行校准,在这种情况下,可能需要设置后线性化旋转位(RO)。有关更多细节,请参阅A1332/ A1335编程参考。

最佳的收集方法是以等间隔的步骤旋转目标,这样得到的数据点的数量是2的幂。通常,32或64个均匀间隔的数据点就足够了。如果不能做到这一点,那么就收集这些点,并且必须对数据进行预处理,这将在下一节中讨论。

收集所需数据点的另一种技术是多次旋转目标,以预定义的间隔收集数据。一旦收集了足够多的点以覆盖目标的整个旋转,那么必须对它们进行预处理,如下一节所讨论的那样。

预处理的数据

如果收集的数据点的数量不是2的幂,或者收集的数据不是等间隔的,那么必须调整点数组的大小和/或使其为等间隔的。要对数据执行此操作,请调用例程ResizePointArray。

x参数是编码器值的数组,y参数是在编码器值处收集的设备读数。参数newSize是调整后的数组所需的大小。如果x参数被设置为null,那么y值被假定以从0开始到以360结束的相等间距收集。如果x参数不为空,则在执行调整大小之前对输入数组进行排序。

double[] ResizePointArray(double[] x, double[] y, int newSize)

这个例程将对输入数组执行三次样条插值,以生成具有所需点数的等间距数组。

初步处理

一旦收集到数据并将其制成长度为2的幂的数组,就可以计算谐波系数了。要计算系数,调用例程CalculateHarmonicLinearCoefficients。

HarmonicCoefficients[] CalculateHarmonicLinearCoefficients (double[] points, out bool pointError)

它的输入是已收集的角度数组。该例程执行FFT并将返回系数数组和一个警告标志。当一个或多个输入角与例程的计算值相差超过20度时,点错误警告标志被设置。

例如,对于8项数组,该例程计算角度应为[0,45,90,135,180,225,270,315]。如果输入数组是[0,45,90,135,180,204,270,315],那么例程将设置pointError,因为第6个数组条目的误差大于20度。

选择谐波

一旦计算出所有的谐波系数,就必须选择所需的谐波。通常情况下,计算例程产生的谐波数量会超过设备所能支持的谐波数量,因此必须选择一些算法来选择相关的谐波。

所使用的谐波的数量也取决于所使用的设备和特性。对于A1332,最大的谐波数是15,但如果使用最大的谐波数,许多可编程功能将使用默认值,如短冲程配置和特定的I2C和SPI设置。对于那些可编程特性,不使用默认值的最大谐波数是9。对于A1335,最大谐波数是11,但为了得到这个数字,许多可编程功能将使用默认值,如短冲程设置。对于那些可编程特性,不使用默认值的最大谐波数是8。

最简单的算法是选择第一个谐波到所需的谐波数量。虽然很容易,但它将选择不会显著影响输出的谐波。

目前在Allegro A1335 Samples Programmer中使用的算法是选择振幅大于0.3的谐波。当前硬件中需要注意的一个限制是,只能在选定的谐波之间跳过4个谐波。如果有大于4的跳变,那么在最后选择的谐波和期望的谐波之间也需要选择任意多的谐波。

编程设备

一旦选择了谐波,那么可以通过调用GenerateHarmonicLinearizationDeviceValues例程来生成要写入设备的值。

HarmonicDeviceValues[]生成harmoniclinearizationdevicevalues (HarmonicCoefficients[] coefficients)

谐系数被传递到这个例程中,它返回一个数组的值需要对设备进行编程。这个例程唯一会抛出的例外情况是,在所选系数之间跳过了4个以上的谐波系数。

要为谐波线性化设备编程,必须设置HL标志,必须将HAR_MAX字段设置为要使用的系数的数量,必须写入HARMONIC_PHASE_n, ADV_n和HARMONIC_AMPLITUDE_n字段。

示例代码

使用系统;
使用Allegro.ASEK;

名称空间HarmonicLinearizationExample

公开课HarmonicLinearizationExample

公共HarmonicLinearizationExample ()



ProgramHarmonicLinearization(字符串filePath, ASEK asekProgrammer)

试一试

HarmonicCoefficients [] hc;
bool pointError = false;
双[]点= null;
string fieldBuffer = File.ReadAllText(filePath);
字符串行;
List encoderreads = new List();
List deviceReadings = new List();

// 1.1收集数据
//从文本文件中读取角度。空行或以#开头的行将被忽略。
如果(! string.IsNullOrEmpty (fieldBuffer))

使用(StringReader sr = new StringReader(fieldBuffer))

while ((line = sr.ReadLine()) != null)

行= line.Trim ();
if (string.IsNullOrEmpty(line) || line. startwith ("#"))

继续;


//每一行可以有两种形式。
//第一个包含编码器角度,然后是与设备的角度,用逗号分隔(22.125,23.543)
//或者只是设备的角度。(23.543)
//如果两个角的间隔不相等,则需要这两个值。
string[] values = line.Split(', ');

如果值。长度> 1)

双编码器= Convert.ToDouble(值[0]);
While (encoder >= 360.0)

编码器- = 360.0;

While(编码器< 0.0)

编码器+ = 360.0;

encoderReadings.Add(编码器);
deviceReadings.Add (Convert.ToDouble(值[1]));

其他的

deviceReadings.Add (Convert.ToDouble(值[0]));




// 1.2数据预处理
如果(! powerOfTwo (deviceReadings.Count ()))

//如果点数少了一个,就去掉最后一个,
if (powerOfTwo(deviceReadings.Count() - 1))

deviceReadings.RemoveAt (deviceReadings.Count () - 1);
点= deviceReadings.ToArray ();

其他的

//否则计算所需样本的数量。
//如果样本数小于64则舍入
//取上至2的最近次幂,否则取下。
int desiredSamples = 8;
while (desiredSamples < deviceReadings.Count())

desiredSamples * = 2;


if (deviceReadings.Count() > 64)

desiredSamples / = 2;


//如果没有编码器读数,假定设备读数是等间隔的。
if (encoderreads . count () != deviceReadings.Count())

//将角度列表转换为数组,然后调整它的大小。
点= ((IHarmonicLinearization) asekProgrammer)。desiredSamples ResizePointArray (null, deviceReadings.ToArray ());

其他的

//将角度列表转换为数组,然后调整它的大小。
points = ((IHarmonicLinearization)asekProgrammer).ResizePointArray(encoderreads . toarray (), deviceReadings.ToArray(), desiredSamples);



其他的

//将角度列表转换为数组
点= deviceReadings.ToArray ();


// 1.3初始处理
//从点数组中计算系数。
hc = ((IHarmonicLinearization) asekProgrammer)。CalculateHarmonicLinearCoefficients(点,pointError);

//当一个或多个角度与程序认为的角度相差超过20度时,就会发生点错误。
//例如,如果使用8个值的数组[0,45,90,135,180,204,270,315],calculate将为第6个标记一个警告
因为它应该比实际值更接近225。
如果(pointError)

对话框。显示(“其中一个角度与期望的角度相差超过20度。”);


// 1.4谐波的选择
//一旦计算出谐波系数数组,就需要选择这些系数。系数的个数
//计算例程返回通常会超过设备可以支持的系数数量,所以有一些限制的方法
//需要的系数。可以选择前8个,也可以使用其他方法。
int numberOfHarmonicComponents = hc.Length;
int numberOfSelectedHarmonicComponents = 0;
int lastHarmonicComponentSelected = 0;
int maxHarmonicComponentsSelected = 8;//在影响到设备上的其他特性之前可以使用的最大谐波数

//在这个例子中,选择振幅超过0.3的前8个谐波。
For (int index = 0;指数< numberOfHarmonicComponents;+ +指数)

如果(hc(指数)。&& (numberOfSelectedHarmonicComponents < maxHarmonicComponentsSelected))

//如果要选择的谐波之间的谐波数
//和最后选择的谐波大于4然后一些
//之间的谐波需要选择。
int skip = index - lastHarmonicComponentSelected;
If(跳过> 4)

//确定需要选择的谐波的数量
//不超过所需的数量。
int numberNeeded = skip / 4;
if ((numberNeeded + numberOfSelectedHarmonicComponents) <= maxHarmonicComponentsSelected)

For (int jndex = 1;jndex < = numberNeeded;+ + jndex)

hc [jndex]。选择= true;
+ + numberOfSelectedHarmonicComponents;

hc(指数)。选择= true;
+ + numberOfSelectedHarmonicComponents;

其他的

//代码无法选择所需的谐波而不超过
//选择的最大系数数,因此它将停止选择。
打破;


其他的

hc(指数)。选择= true;
+ + numberOfSelectedHarmonicComponents;

lastHarmonicComponentSelected =指数;



//如果没有选择谐波,则选择前8。
if (numberOfSelectedHarmonicComponents == 0)

For (int I = 0;(i < numberOfHarmonicComponents) && (numberOfSelectedHarmonicComponents < 8);+ + i)

hc[我]。选择= true;
+ + numberOfSelectedHarmonicComponents;



// 1.5设备编程
//生成写入eeprom所需的值。
HarmonicDeviceValues[] eepromValues = ((IHarmonicLinearization)asekProgrammer).GenerateHarmonicLinearizationDeviceValues(hc);

//确认设备的电源是打开的
asekProgrammer.SetVcc (5.0);

//允许写入设备的eeprom,这需要使SRAM可写,并停止处理器
((ISRAMWriteAccessMode) asekProgrammer) .SetSRAMWriteAccessMode ();
((IProcessorMode) asekProgrammer) .SetProcessorIdle ();

//打开eeprom中的谐波线性化
((IRegisterAccess) asekProgrammer) .WritePartialRegister (MemoryAccessType。扩展,0x306, 1,15,15);// hl = 1

//设置要使用的谐波数
((IRegisterAccess) asekProgrammer) .WritePartialRegister (MemoryAccessType。0 x309 eepromValues扩展。19岁的长度16);// HAR_MAX =谐波数

//对于谐波
For (uint index = 0;指数< eepromValues.Length;+ +指数)

uint registerValue = (uint)((eepromValues[index].)阶段<< 12)& 0x0FFF000) +
((eepromValues(指数)。advance << 10) & 0x0C00) +
(eepromValues(指数)。振幅& 0 x03ff));
((IRegisterAccess) asekProgrammer) .WriteRegister (MemoryAccessType。扩展,0x30C +索引,registerValue);// HARMONIC_PHASE, ADV和HARMONIC_AMPLITUDE


//关闭电源,然后重新打开,以确保设备正在使用新的线性化值。
asekProgrammer.SetVccOff ();
asekProgrammer.SetVcc (5.0);


捕获(异常交货)

MessageBox.Show (ex.Message);



private bool powerOfTwo(int值)

Int log2npoints = 0;
Int j = value;

while ((j > 0) && ((j & 1) == 0)) //计算输入值以2为底的对数

log2npoints + +;
j > > = 1;


If ((value < 2) || (value != (1 << log2npoints)))

返回错误;


返回true;



角度输入文件格式

这个文件包含一个角度值列表。如果用逗号分隔两个值,则第一个值是编码器角度,第二个值是设备角度。行可以为空,或者如果以#开头,则认为它们是注释。

输入文件:

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

有两列:

0123年
22.5,145.5
45168年
67.5,190.5
90213年
112.5,235.5
135258年
157.5,280.5
180303年
202.5,325.5
225348年
247.5, 10.5
270年,33
292.5, 55.5
315年,78年
337.5,100.5