【发布时间】:2019-02-20 18:19:56
【问题描述】:
我有一个绝对编码器,它以格雷码输出 10 位值(0 到 1023)。我要解决的问题是如何确定编码器是向前还是向后移动。
我认为“最佳”算法如下: 首先,我将格雷码转换为常规二进制(完全归功于:https://www.daniweb.com/programming/software-development/code/216355/gray-code-conversion 中的最后一个答案):
int grayCodeToBinaryConversion(int bits)
{
bits ^= bits >> 16; // remove if word is 16 bits or less
bits ^= bits >> 8; // remove if word is 8 bits or less
bits ^= bits >> 4;
bits ^= bits >> 2;
bits ^= bits >> 1;
return bits;
}
其次,我比较了两个相隔 250 毫秒的采样值。我认为比较两个值会让我知道我是向前还是向后。例如:
if((SampleTwo – SampleOne) > 1)
{
//forward motion actions
}
if((SampleTwo – SampleOne) < 1)
{
//reverse motion actions
}
if(SampleTwo == SampleOne)
{
//no motion action
}
就在我开始觉得自己很聪明的时候,令我失望的是,我意识到这个算法有一个致命的缺陷。当我将二进制值 824 与 1015 进行比较时,此解决方案效果很好。此时我知道编码器的移动方式。然而在某些时候,编码器会从 1023 翻转到 0 并爬升,然后当我去比较 1015 的第一个采样值和 44 的第二个采样值时,即使我在物理上朝同一个方向移动,我写的逻辑没有正确捕捉到这一点。另一个不行的是将格雷码值作为一个 int,并比较两个 int。
如何比较两个相隔 250 毫秒的格雷码值,并在考虑编码器翻转方面的情况下确定旋转方向?如果您愿意提供帮助,能否提供一个简单的代码示例?
【问题讨论】:
-
您希望编码器在 250 毫秒间隔内移动多少?
-
不超过 400 个脉冲(球场)。但是当它从 950 变为 250 时,我的算法就不起作用了。
-
一种方法是计算读数之间的差异,假设您要“向前”然后“向后”。然后,您假设编码器正朝着较小值的方向行进。当然,如果您的编码器要在 250 毫秒内移动超过一半的时间间隔,这将失败;在这种情况下,您将增加采样频率。
-
S2-S1的结果在-1023到+1023的范围内;在该范围内,-1023 ~ -512 和 +1 ~ +511 是向前的,-511 ~ -1 和 512 ~ 1023 是向后的。
-
@m69,没有负数范围。这些值限制在 0 到 1023 之间的范围内。根据值的差异,我试图找出旋转方向。