Arduino到Unity3D的延迟/滞后

时间:2016-04-18 19:33:00

标签: unity3d arduino lag latency electronics

我用真正的控件和运行Unity3D的PC构建这个街机游戏。基本上人们移动物理杆并移动数字杆。 (这需要尽可能实时)。

现在杆转动rotary encoder。 运行带有中断的this code的Arduino Mega读取值,然后通过Serial将其发送到Unity游戏。

所有东西都是超级优化的,但我在移动杆的那一刻和它在屏幕上显示的那一刻之间有500毫秒的滞后。

任何减少这种滞后的想法?我应该使用新的编码器吗?一个新的arduino?一个不同的设置?

非常感谢:)

2 个答案:

答案 0 :(得分:0)

您的问题中未提供Unity C#或Arduino C / C ++代码,因此您只能获得建议。

<强> 1 即可。使用Thread从Unity端的串行读取。在Unity中尝试之前,你必须先了解C#Thread,否则你最终会遇到很多其他问题。

<强> 2 即可。在接收数据时,避免在Arduino或Unity端进行字符串连接(oldString + = newString)。不这样做会导致随着时间的推移而减速。

第3 即可。优化您从Arduino发送和接收数据的方式。在Arduino端使用字节数组而不是字符串。

从你问题中链接中发布的Arduino编码器代码示例来看,它看起来像这样:

Serial.print("Left = ");
Serial.print(newLeft);
Serial.print(", Right = ");
Serial.print(newRight);

那不好。我们假设你有 4 编码器。 左前方右前方左后方右后方编码器。从每个编码器获取这些值。如果值,请将其缩放为0,127。如果值为负数,请将其从当前值缩放到-1,-127。可以使用Map函数轻松完成缩放。

创建一个unsigned char数组或使用字节数组并为其分配每个缩放值;

byte encoders[] = {0, 0, 0, 0}; //4 Encoders
encoders[0] = valueOfScaledFrontLeftEncoder;
encoders[1] = valueOfScaledFrontRightEncoder;
encoders[2] = valueOfScaledBackLeftEncoder;
encoders[3] = valueOfScaledBackRightEncoder;

然后在同一时间发送它们作为字节数组

Serial.write(encoders, sizeof(encoders));

现在,在Unity的接收器端,4个字节将按顺序到达。读取它们并按发送顺序提取值。这节省了Arduino的时间并提高了接收和发送速度。没有更多发送长串!

<强> 4 即可。如果全部失败,请从 Arduino Maega 切换到 Arduino到期。它非常快,因为它使用ARM处理器。请注意,它使用 3.3 伏而不是 5 伏特。因此,请务必购买 3.3 v编码器,或使用 5v 3.3 降压。

答案 1 :(得分:0)

感谢您的回答!

我做了一些进一步的优化,现在我有大约100毫秒的延迟。这仍然是相当多的,并没有提供良好的游戏体验。

这是Arduino代码:

   #include <Encoder.h> 
   // Define GPIO of the rotary encoders 

    Encoder rot0(38,39);
    Encoder rot1(40,41);
    Encoder pos0(6,7);
    Encoder pos1(18,19);
    // and so on...


    // setting default position
    int oldRot0, oldRot1, oldPos0, oldPos1 = -99999;
    int newRot0, newRot1, oldPos0, oldPos1;
    // and so on...

    void setup() 
    {  
      Serial.begin(250000);
    }


    void loop() {

      // Reading constantly the encoders
      newRot0 = rot0.read();
      newRot0 = rot0.read();

      newPos0 = pos0.read();
      newPos1 = pos1.read();
      // and so on...

    // Definying a char buffer to output data
    char buffer[4];

      // IF ROD 1 MOVES : output values
      if (newRot0 != oldRot0 || newPos0 != oldPos0)
       {

        sprintf(buffer,"1%c%c",newRot1,newPos1); // Sending the rod ID and data in char format to save space
        Serial.println(buffer);

        /* BEFORE: (I changed it to the sprintf buffer)
       Serial.print("~1#0#");
        Serial.print(newPos1);      
        Serial.print("#");
        Serial.print(newRot1);
        Serial.println();
        */

        oldRot0 = newRot0;
        oldPos0 = newPos0;
        }

......其他棒也一样。

  1. 你在谈论oldRot0 = newRot0; ?我应该避免使用它还是使用它?

  2. 的确,我正在读取值,使用map函数进行缩放,然后通过缓冲区输出它们。我可以做得更优化吗?

  3. 我正在考虑使用Arduino DUE,但我已经购买并组装了所有编码器,它们的工作电压为5V。我真的不想在3V3上找到新的编码器,而且它们似乎不如5V。 我想的是用更强大的微控制器取代Arduino。 this board可以解决这个问题吗?与16Mhz的Mega2560相比,它的运行频率为80MHz。

  4. 修改

    毕竟我改变了Arduino Mega的Teensy 3.2,这是非常快的,完全兼容的软件和5V容忍!它大大改善了。我现在不回到8位微控制器......