收到太多数据时,Arduino会挂起

时间:2014-04-03 08:40:16

标签: arduino simulink buffer-overflow uart

我遇到了Arduino Uno的问题。它应该将数据从Novint Falcon传输到Dspace,并从Dspace接收传感器数据,然后发送回Falcon。 Dspace用Simulink编程。

我的Arduino代码运行如下:

  1. 使用Serial。从笔记本电脑读取6个字节。
  2. 使用SoftwareSerial将8个字节写入Dspace。
  3. 使用SoftwareSerial从Dspace读取3个字节。
  4. 将这3个字节写回笔记本电脑。
  5. 在Dspace中,程序为:

    1. 使用Serial Receive从Arduino读取8个字节。
    2. 使用Serial Transmit将3个字节发送回Arduino。
    3. 我现在遇到的问题是,当Dspace打开时,Arduino在大约1秒后挂起(在我的笔记本电脑上,我确实看到从Dspace读取的3个字节)。但是,当我只从Dspace发送一个字节时,不会发生此问题。任何更多,它不起作用。

      串口的波特率为115200.Simulink模型的步进时间为2ms。

      看起来这与Arduino中的缓冲区溢出有关,但我不确定。有人可以帮助我或提供如何确定问题根源的建议吗?现在已经坚持了一段时间..谢谢!

      #include <SoftwareSerial.h>
      
      char Axispos[6] ={0,0,0,0,0,0};
      
      SoftwareSerial mySerial(7,6); //RX, TX
      
      void setup() {
      
        Serial.begin(115200);
        Serial.flush();
        mySerial.begin(115200);
      }
      
      void loop(){
      
        if ( Serial.available() >= 6) 
        {
          char Fx=0;
          char Fy=0;
          char Fz=0;
      
          Serial.readBytes(Axispos,6);
      
          mySerial.write(33);
          mySerial.write(22);
          mySerial.write(Axispos);
      
          Fx = mySerial.read();
          Fy = mySerial.read();
          Fz = mySerial.read();
      
          Serial.write(Fx);
          Serial.write(Fy);
          Serial.write(Fz);
        }
      }
      

      simulink中的C代码:

      function [xPos, yPos, zPos, Force] = fcn(Axispos, NumRX)
      
      persistent xPer yPer zPer count output;
      
      Force=uint8(zeros(1,3));    
      if isempty(xPer)
          xPer = int16(0);
          yPer = int16(0);
          zPer = int16(0);
          count = 0;
          output = uint8(0);
      end
      
      StartByte1 = char(Axispos(1));
      StartByte2 = char(Axispos(2));
      xh = uint8(Axispos(3));
      xl = uint8(Axispos(4));
      yh = uint8(Axispos(5));
      yl = uint8(Axispos(6));
      zh = uint8(Axispos(7));
      zl = uint8(Axispos(8));
      
      if (NumRX >=8 && StartByte1 == 33 && StartByte2 == 22)
      
      xwert = uint16(bitshift(uint16(xh),8,16) + bitand(uint16(xl),uint16(255)));
      ywert = uint16(bitshift(uint16(yh),8,16) + bitand(uint16(yl),uint16(255)));
      zwert = uint16(bitshift(uint16(zh),8,16) + bitand(uint16(zl),uint16(255)));
      
      var1 = typecast(uint16(xwert),'int16');
      var2 = typecast(uint16(ywert),'int16');
      var3 = typecast(uint16(zwert),'int16'); 
      
      xPer = var1(1);
      yPer = var2(1);
      zPer = var3(1);
      
      end
      
      xPos = xPer;
      yPos = yPer;
      zPos = zPer;
      
      Force(1) = uint8(10);
      Force(2) = uint8(20);
      Force(3) = uint8(30);
      

1 个答案:

答案 0 :(得分:0)

在Arduino上同时使用硬件和软件序列可能会导致问题。

已经编写了开源库AltSoftSerial来克服这个问题。

从他们的主页:

  

当需要同步数据流时,AltSoftSerial特别有用

则...

  

但是,最大波特率通常不是最重要的问题。每个库都会对其他库施加中断延迟。 AltSoftSerial导致大约2-3μs的延迟。 NewSoftSerial导致其他库的延迟时间为10位。以57600波特率运行,即174μs!这种延迟是AltSoftSerial和NewSoftSerial之间的主要区别。

     

要查看此操作,您可以尝试Arduino 1.0中的SoftwareSerial附带的示例。如果你在Arduino串口监视器中输入“晚安”,你会看到4800波特的引脚3实际上是“Goot”。字符“dnigh”丢失了。原因是因为当SoftwareSerial在4800发送字母“G”时,字母“oodnigh”到达57600波特。只有“oo”保存在UART寄存器中。其余的都丢失了,因为中断被禁用了太长时间。 AltSoftSerial可以轻松处理此测试,因为它不会长时间锁定中断。

我几乎可以肯定这正是您在Arduino项目中面临的问题。因此,我建议您使用此库而不是标准的SoftwareSerial。