【问题标题】:Arduino encoder interrupts corrupting serial dataArduino 编码器中断损坏串行数据
【发布时间】:2012-04-11 16:56:54
【问题描述】:

我有一个连接到 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?

【问题讨论】:

    标签: serial-port arduino encoder


    【解决方案1】:

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

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

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

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

    【讨论】:

      【解决方案2】:

      嵌入式系统第一法则:

      尽量少打断。

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

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-12-18
        • 2012-04-29
        • 1970-01-01
        • 1970-01-01
        • 2013-10-19
        • 1970-01-01
        • 2015-05-05
        相关资源
        最近更新 更多