我有一个绝对编码器,它以格雷码形式输出一个 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,即使我在物理上朝相同的方向移动,我写的逻辑没有正确捕捉到这一点。另一个不可行的方法是将格雷码值作为一个整数,然后比较两个整数。
如何比较两个相隔 250 毫秒的格雷码值并确定旋转方向,同时考虑编码器的翻转方面?如果您愿意提供帮助,能否提供一个简单的代码示例?
最佳答案
假设 A 是您的初始读数,B 是 250 毫秒后的读数。
我们以 A = 950 和 B = 250 为例。
让我们假设编码器向前移动(它的值随时间增加)。
那么,经过的距离是(B - A + 1024) % 1024
。我们称其为 d_forward
。
对于这个例子,d_forward
结果是 (250 - 950 + 1024) % 1024
= 324。
向后移动的距离 (d_backward
) 为 1024 - d_forward
;这是 700
。
d_forward
和 d_backward
的最小值将给出编码器行进的方向。
如果编码器要在 250 毫秒内移动超过 1023/2 个单位,这将不起作用。在这种情况下,您应该缩短读数之间的间隔。
关于algorithm - 请建议一种算法来比较格雷码数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52357331/