【问题标题】:Two port receive using software serial on Arduino在 Arduino 上使用软件串行接收两个端口
【发布时间】:2014-07-31 23:12:27
【问题描述】:

我在使用带有 arduino 板的两个软件串行端口从两个传感器获取数据时遇到问题。我注意到以前可能有人问过类似的问题,但答案表明它无法完成,我完全知道它可以基于此处的示例 (http://arduino.cc/en/Tutorial/TwoPortReceive)!

我正在使用 arduino 以太网。我试图从中获取数据的设备包括来自 sparkfun 的 GPS 和 IMU。

我可以只使用软件串行端口从任一设备获取数据,但是一旦我添加了第二个软件串行端口,两个端口都将无法工作。我无法使用硬件串行端口,因为它正在被另一台设备使用。

我的代码和例子一模一样:

#include <SoftwareSerial.h>

SoftwareSerial portOne(7,8);
SoftwareSerial portTwo(5,6);

void setup()
{
  Serial.begin(9600);


  portOne.begin(9600);
  portTwo.begin(9600);
}

void loop()
{

  portOne.listen();
  while (portOne.available() > 0) {
    char inByte = portOne.read();
    Serial.write(inByte);
  }

  delay(500);

  portTwo.listen();
  while (portTwo.available() > 0) {
    char inByte = portTwo.read();
    Serial.write(inByte);
  }

  Serial.println();
}

有人有什么想法吗?

【问题讨论】:

  • 你能告诉我们更多关于它是如何不工作的信息吗?
  • 我不知何故让它工作了,你必须设置引脚状态,即接收引脚作为输入,发送引脚作为输出。

标签: arduino


【解决方案1】:

此代码将无法运行,或者如果它完全可以运行则效果不佳。 SoftwareSerial 只有一个内部缓冲区。是的,您可以拥有多个 SoftwareSerial 对象,但其中只有一个控制内部缓冲区。当任何 RX 引脚被置位时,都会产生中断,但只有正在侦听()的 RX 引脚会被检查开始位。

真正需要的是当中断来自起始位时检查多个引脚的能力。然后,您必须设置指向适当数据结构的指针。这会很复杂,但有可能。

或者可能只是放弃中断驱动的接收,然后旋转检查两个/所有 RX 引脚,然后根据您看到的引脚开始接收。请注意,此代码有很多毛发,您需要一台示波器才能使其工作。

我遇到了类似的问题,这就是我找到您的传感器的原因。在与我的同事讨论后,我们决定按轮换顺序读取我们的传感器。我们的传感器报告传感器的当前状态,而不是特定事件,所以如果我们丢失一些报告也没关系。所以我们将从端口 1 读取,然后从端口 2 读取,然后从端口 1 读取,等等。我们的传感器输出文本行,因此我们知道何时切换到下一个传感器。

【讨论】:

  • 感谢您的回答。您能否提供一些代码来展示您的轮换订单概念?
【解决方案2】:

引用的示例一次只主动监听一个端口。推荐的解决方案是升级到具有 4 个硬件串行端口的 Arduino Mega (https://www.sparkfun.com/products/11061)。

为了同时支持两个软件串口将需要大量的 CPU 资源。这也是一个困难的设计和过多的编程时间,远远超过了 58 美元 + 运费的成本。

再次查看您的代码,我突然想到您在 portOne.listen 命令之后立即检查字符。在 9600 波特下,第一个字符到达大约需要 1 毫秒,您的 while 测试已经完成,并且 portTwo.listen 命令在第一个字符到达之前很久就执行了。

出于测试目的,请尝试在 portOne.listen 命令之后添加 1-2 毫秒的延迟,看看是否有字符。

作为示例(未经测试并注意,如果端口一正在发送没有字符间间隙的字符,则第一个 while 永远不会失败,从而阻止读取 portTwo 字符):

void loop()
{

    portOne.listen();
    delay(2);
    while (portOne.available() > 0) {
        char inByte = portOne.read();
        Serial.write(inByte);
        delay(1);
    }

    portTwo.listen();
    delay(2);
    while (portTwo.available() > 0) {
        char inByte = portTwo.read();
        Serial.write(inByte);
        delay(1);
    }
    Serial.println();
}

【讨论】:

  • 你是说,上面的代码行不通?我一次只监听一个端口。
  • 我应该说我没有尝试过这样做。只要您打开端口一,接收数据,关闭端口一,打开端口二,接收数据,关闭端口二,然后重复,我希望它会起作用。它仍然会使用比两个硬件端口更多的微资源,但取决于微负载和固件的其余部分,这可能不是问题。
【解决方案3】:

不要使用 while ......

用途:

  {     portOne.listen();

   if (PortOne.available() ) {
       ricevo = myPort1.read(); }

   // delay(2);   // ridiculos waiting time
   // delay(1);   // extra ridiculos waiting time

超过 500 毫秒的切换时间太长了,没时间.....

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-03
    • 1970-01-01
    相关资源
    最近更新 更多