1

我无法使用带有 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();
}

有任何想法的人吗?

4

3 回答 3

3

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

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

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

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

于 2013-04-17T18:06:41.523 回答
1

引用的示例一次只主动侦听一个端口。推荐的解决方案是升级到具有 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();
}
于 2012-09-18T01:26:59.270 回答
0

暂时不要使用......

利用:

  {     portOne.listen();

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

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

超过 500 毫秒对于切换来说是一个太大的时间,没有时间......

于 2014-07-31T15:12:27.763 回答