两个端口使用Arduino上的软件序列接收

时间:2012-09-17 16:38:16

标签: arduino

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

任何有想法的人?

3 个答案:

答案 0 :(得分:3)

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

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

或者可能只是放弃中断驱动的接收,并旋转检查所有RX引脚,并根据您看到的引脚启动接收。转发这段代码有很多头发,你需要一台示波器来使它工作。

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

答案 1 :(得分:1)

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

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

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

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

作为一个例子(未经测试并注意,如果端口1发送没有字符间距的字符,则第一个字符将永远不会失败,阻止读取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();
}

答案 2 :(得分:0)

不要使用......

使用:

  {     portOne.listen();

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

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

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