1

我有一个连接到 6 轴机械臂的 Arduino Mega。所有 6 个中断都连接到编码器(一个编码器引脚在中断上,另一个在普通数字输入上)。使用以下代码处理中断:

void readEncoder1(){
//encoders is a 2d array, where the first d is the axis, and the two pin numbers
//first pin is on an interrupt (CHANGE), and second is a standard digital in
  if (digitalRead(encoders[0][0]) == digitalRead(encoders[0][1])) {
   positions[0]++;
  } else {
   positions[0]--;
  }
 if(servoEnable){
  updatePositions(); //// compares positions[] to targets[] and adjusts motor speed accordingly
 }
}

这是为了将手臂锁定在某个位置 - 如果 arduino 检测到电机的位置偏离了某个阈值,它会更新进入电机的功率以将手臂保持在适当的位置。

问题是这样的,然后 - 如果两个或三个(或更多)轴处于负载状态(需要不断更新以保持在原位)或它们正在移动,Arduino 将停止在串行输入上接收完整的命令,几个字符将被丢弃. 中断显然运行得很快,由于某种原因,这导致命令被破坏。有没有办法解决?在架构上,我这样做对吗?我的主要直觉是在主运行循环中以 100 毫秒的间隔调用 updatePositions(),这会显着减少中断开销吗?我想我的问题归结为即使所有 6 个编码器都在跳动,我如何将可靠的串行命令输入 Arduino?

4

2 回答 2

2

正交编码器设计为由硬件计数器读取。当电机全速运行时,脉冲频率通常很高。一兆赫兹并不罕见。脉冲数越高,伺服回路的工作效果就越好,电机的定位就越准确。

在具有低功耗 CPU 的软件中执行此操作非常具有挑战性。当 ISR 花费的时间超过脉冲之间的间隔时,它将分崩离析。你会失去脉搏,从而失去位置。尤其糟糕,因为您无法检测到这种错误情况。并且这种损失发生在机器人快速移动时,最坏的情况是失去控制。

你绝对不能在中断处理程序中更新伺服循环,所以首先摆脱它。将 ISR 保持在最低限度,只计算位置,不计其他。伺服回路应该是独立的,由定时器中断或滴答声驱动。您无法以 100 毫秒的伺服更新正确控制机器人,除非它非常缓慢,这最多需要几毫秒才能获得平稳的加速和稳定的反馈。

花四十美元来控制价值数千美元的机器人硬件的智慧是有限的。无法跟上伺服回路是您可以检测到的,当位置误差累积太多时将其关闭。失去脉搏你无能为力,那是一个残骸。获取硬件计数器。

于 2012-03-28T10:58:09.623 回答
1

嵌入式系统的第一条规则:

在中断中尽可能少做。

在您的情况下,只需更新中断中的位置并在后台或以较低优先级运行您的位置/速度控制循环。

旁白:我假设您知道您正在“丢失”编码器脉冲,因为您在其中一个通道上没有中断?

此外,中断驱动的编码器分析非常容易产生噪音。如果您收到噪声脉冲,您可能只会看到其中一个边缘的中断,因为它们太靠近而无法同时处理这两个边缘。

一种更强大的方法是使用一个状态机来监视所有 4 个转换,但这需要两个通道的两个边缘上的中断,或者轮询速度足够快,以免错过任何您期望看到的速率。

于 2012-03-28T11:54:05.150 回答