【问题标题】:How do I read serial between interrupts on Arduino?如何在 Arduino 上的中断之间读取串行?
【发布时间】:2016-12-15 15:06:50
【问题描述】:

我有步进器在 50 的中断计时器期间步进,并且我的所有代码都在中断之间工作,直到我尝试读取超过一个字符长的串行命令。

我的字节数丢失了,所以我的字符串每 4-5 个字符丢失一个字母。我研究了一整天,试图找出解决方案,但一无所获。如果我不使用中断,我的步进器会停止 2 秒,将一个字符的串行输入作为字符串读取。

我的目标是让远程控制应用程序发送速度命令。我需要帮助解决这个问题。

https://sourceforge.net/p/open-slider/code/ci/master/tree/OpenSliderFirmware/

String incomingString = "";
if (Serial.available() > 0) {
    incomingString = Serial.readString();
    Serial.println(incomingString);
}

使用 Accelstepper 库

中断:

//Interrupt Timer1
void ISR_stepperManager() {
    Slide.runSpeed();
    Xaxis.runSpeed();
    Yaxis.runSpeed(); 
}

【问题讨论】:

  • 您使用的是软件(bit-banged?)串口吗?串行数据速率是多少,步进中断的速率是多少?
  • 中断时间为 50 毫秒。 serial0 USB 上的波特率为 115200。最终,我将在引脚 2 和 3 上运行软件串行,我相信蓝牙(如果我能弄明白的话)我仍在努力寻找能够解释 Marlin 固件如何可靠地同时完成步进和串行的人。 Marlin 一次读取 1 个字符,我将切换回它,这样它就不会阻塞其他内容。我以为他们使用中断来驱动步进器,但我不再确定这一点。我正在使用 2560 和 RAMPS。对于高级的东西,我还是个新手。
  • 您应该首先尝试降低串行波特率:115200 波特大约是每字节 80 微秒 - 因此,如果您的步进中断服务例程花费超过 80 微秒,您将立即面临丢失串行字符的风险。尝试 9600 波特(或更慢),即每字节大约一毫秒。如果您不确定 ISR 需要多长时间并且有可用的示波器,请在 ISR 开始时将 ISR 输出为 1 到端口,最后为 0,并查看脉冲的宽度和多少它因人而异。对于 bit-banged,您肯定必须降低串行数据速率。
  • 说到示波器,我一直想要一台,但不想花 200 美元买一个*便宜的。 20 美元的 DSO 138 是否符合您的建议?

标签: arduino serial-port interrupt


【解决方案1】:

快速回答:如果中断计时器过于频繁地切入,则不需要。

我通过使用可变中断定时器和步进乘法器解决了这个问题。基本上,每次定时器中断时都会调用这些步骤,而不是检查中断函数内的毫秒。这解决了很多问题。步进器的速度现在由中断定时器控制。这给了我更多的空闲周期来完全读取传入的序列而不会损坏并提高效率。当执行超过 4k 步/秒时,每个周期调用更多步也提高了效率,需要更少的周期来实现高步率。

串行每个周期处理一个字符以防止阻塞。

总体而言,如果您使用串行和中断计时器,任何发生

【讨论】:

    【解决方案2】:

    我不确定它是否有助于解决您的问题,但我一直看到 String 类型在需要发生其他事情时不安全使用。 我更喜欢使用 char 数组并一次读取一个字符。

    while(Serial.available())
    {
     data[x] = Serial.read();
     x++;
    }
    

    我发现它更可靠。

    希望对你有帮助!

    【讨论】:

    • 不幸的是,在我的代码中使用它不会有什么不同,因为 while 循环会被定时器中断打断,这是我遇到的问题。不过感谢您的建议。
    猜你喜欢
    • 2018-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多