2016-04-18 28 views
-1

Ich baue dieses Arcade-Spiel mit echten Steuerelementen und einem PC mit Unity3D. Grundsätzlich bewegen Menschen einen physischen Stab und es bewegt einen digitalen Stab. (Dies muss so real wie möglich sein).Arduino zu Unity3D Latenz/Verzögerung

Gerade jetzt dreht die Stange eine rotary encoder. Ein Arduino Mega läuft this code mit Interrupts liest die Werte, dann senden Sie es über Serial zum Unity-Spiel.

Alles ist super optimiert, aber ich habe eine Verzögerung von 500ms zwischen dem Moment, in dem ich die Rute bewege und dem Moment, in dem sie auf dem Bildschirm angezeigt wird.

Irgendwelche Ideen, um diese Verzögerung zu reduzieren? Soll ich neue Encoder verwenden? Ein neues Arduino? Eine andere Einrichtung?

Vielen Dank :)

+0

Wlan oder Seriell? – Programmer

+0

1/2 Sekunde Verzögerung? Ich vermute, Sie haben auf der Unity-Seite einfach einen Fehler gemacht. Haben Sie einfach die Eingabe "simuliert", um zu überprüfen, dass Sie keinen grundlegenden Fehler upstream gemacht haben? – Fattie

Antwort

0

Keine Einheit C# oder Arduino C/C++ Code in Ihrer Frage zur Verfügung gestellt, so dass Sie einen Rat nur erhalten werden.

. Verwenden Sie Thread, um von der seriellen Seite auf der Unity-Seite zu lesen. Sie müssen C# -Thread verstehen, bevor Sie dies in Unity versuchen, oder Sie werden mit vielen anderen Problemen enden.

. Vermeiden Sie String-Verkettungen (oldString + = newString) auf der Arduino- oder Unity-Seite, wenn Daten empfangen werden. Wenn Sie dies nicht tun, verlangsamen Sie sich im Laufe der Zeit.

. Optimieren Sie, wie Sie Daten vom Arduino senden und empfangen. Verwenden Sie Bytearray auf der Arduino-Seite anstelle von String.

Aus dem Beispiel von Code Arduino-Encoder in Verbindung in Ihrer Frage gestellt, es sieht aus wie etwas wie folgt aus:

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

Das ist nicht gut. Nehmen wir an, Sie haben Encoder. vorne links, vorne rechts, hinten links und Hinten Rechts Encoder. Holen Sie sich diese Werte von jedem Encoder. Wenn der Wert positiv ist, skalieren Sie ihn auf 0,127. Wenn der Wert negativ ist, skalieren Sie ihn von seinem aktuellen Wert auf -1, -127. Die Skalierung kann einfach mit der Map Funktion durchgeführt werden.

Erstellen Sie ein vorzeichenloses char-Array oder verwenden Sie ein Byte-Array und weisen Sie jedem skalierten Wert einen Wert zu;

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

Dann sie bei thesame Zeit als Array von

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

Jetzt Bytes senden, auf der Empfängerseite in der Einheit, die 4 Bytes in Reihenfolge ankommen. Lesen Sie sie und extrahieren Sie die Werte in der Reihenfolge wie gesendet. Dies spart Zeit auf dem Arduino und erhöht die Empfangs- und Sendegeschwindigkeit. KEINE mehr langen STRINGS!

. Wenn alles fehlschlägt, wechseln Sie von Arduino Maega zu Arduino Due. Es ist sehr schnell, weil es ARM-Prozessor verwendet.Beachten Sie, dass 3,3 Volt anstelle von Volt verwendet wird. Stellen Sie also sicher, dass Sie einen 3.3 Encoder und 5v zu 3.3 V Step-down kaufen.

+0

es scheint komisch eine 1/2 Sekunde Verzögerung rechts. Ich vermute irgendwo nur einen groben Fehler. – Fattie

+0

@JoeBlow Ich stimme dir zu, obwohl er sagte: "Alles ist superoptimiert". Ich arbeite mit Arduino und .5 Lag ist riesig und schlecht für Echtzeit-Sachen und ich denke, dass er wahrscheinlich tut, was ich in # 3 erwähnte oder die Encoder-Bibliothek ist schlecht gemacht. Die Verzögerung kann auch auftreten, wenn Thread nicht auf der Unity-Seite verwendet wird, was die Nummer 1 ist, die ich erwähnt habe. – Programmer

+0

richtig, 1/2 sek scheint wie eine große Verzögerung ... – Fattie

0

Vielen Dank für Ihre Antwort!

Ich habe einige weitere Optimierungen vorgenommen und habe jetzt etwa 100ms Verzögerung. Das ist immer noch ein bisschen und bietet keine großartige Spielerfahrung.

Hier ist der Arduino-Code:

#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; 
     } 

... gleiche Sache für die anderen Stäbe.

  1. Sprichst du von oldRot0 = newRot0; ? Soll ich es vermeiden oder benutzen?

  2. In der Tat, ich lese den Wert, verwenden Sie die Kartenfunktion zu skalieren und dann über einen Puffer ausgeben. Könnte ich es noch optimierter machen?

  3. Ich dachte über die Verwendung des Arduino DUE nach, aber ich habe bereits alle meine Encoder gekauft und montiert und sie arbeiten in 5V. Ich möchte nicht wirklich neue Encoder finden, die auf 3V3 laufen, und sie scheinen weniger verbreitet zu sein als die 5V. Was ich stattdessen dachte, ist das Ersetzen des Arduino durch einen leistungsstärkeren Mikrocontroller. Würde this board den Trick machen? Es läuft mit 80 MHz, verglichen mit den 16 MHz des Mega2560.