Mittwoch, 17. Januar 2018

Zeichnen auf dem TFT mit dem XBox Controller

 
Im ersten Beispiel wurde beschrieben, wie man die Daten von einem Xbox Controller zu dem Arduino sendet und dabei einen Servo ansteuerte. Nachteil an der Code Konstellation war, dass nur ein Byte Wert übermittelt wurde und auch sehr instabil lief. Mit ein paar Anpassungen lässt sich dies einfach beheben. (siehe: Servo mit dem Xbox Controller steuern)

Hinweis
Das folgende Beispiel ist vom Aufbau relativ simple gehalten, so dass bei der Ausgabe Kompromisse eingegangen werden, wie z.B. die Daten Qualität über die Serielle Schnittstelle.

Mehr Daten Senden
Das MonoGame Projekt muss nur in der Update Methode angepasst werden. Zum einen wird geprüft, ob noch Bytes geschrieben werden. Dann können die Eingabewerte vom Xbox Controller eingelesen werden und über die Serielle Verbindung versendet werden.

 protected override void Update(GameTime gameTime)  
 {  
   GamePadState state = GamePad.GetState(PlayerIndex.One);  
   if (state.Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))  
   {  
     this.Exit();  
   }  
   if (this._serialPort.BytesToWrite == 0)  
   {  
     byte stickValueX = (byte)((state.ThumbSticks.Left.X + 1) * 90);  
     byte stickValueY = (byte)((state.ThumbSticks.Left.Y + 1) * 90);  
     byte buttonValuePaint = (byte)(state.Buttons.A == ButtonState.Pressed ? 10 : 0);  
     byte buttonValueReset = (byte)(state.Buttons.B == ButtonState.Pressed ? 10 : 0);  
     this._serialPort.Write(new byte[] { stickValueX, stickValueY, buttonValuePaint, buttonValueReset }, 0, 4);  
     this._serialPort.WriteLine(string.Empty);  
   }  
   Task.Delay(5);  
   base.Update(gameTime);  
 }  

Mehr Daten Empfangen
Die Lösung ist simple. Um mehrere Bytes einzulesen, müssen diese über einen Schleifen Vorgang vom Serial gelesen werden. Die Byte Werte werden dann zunächst in eine lokales Byte Array zugewiesen. Anschließend kann noch geprüft werden ob alle Bytes gelesen wurden. Die ersten zwei Werte sollten zumindest da sein, ansonsten kann der zu zeichnende Punkt (eigentlich ein Kreuz) nicht bewegt werden.

 bool ReadReceivedBytes() {  
  byte received[4];  
  int index = 0;  
  while(Serial.available() > 0) {  
   if(index < 5) {  
    received[index] = Serial.read();  
   }  
   index++;  
  }  
  if(index < 4) {  
   return false;  
  }  
  mReceivedStickX = received[0];  
  mReceivedStickY = received[1];  
  mReceivedButtonA = received[2];  
  mReceivedButtonB = received[3];  
  return true;  
 }  

Ausgabe und Fehler
Die Ausgabe erfolgt diesmal nicht an einem Servo, sondern an einem TFT Display mit einer Auflösung von 160x128 Pixeln, der auch für den Arduino Esplora ebenfalls verwendet wird.
Die Übertragung ist nicht immer Fehlerfrei, womit für genauere Ergebnisse eine Fehlerbehandlung notwendig wird. Aber das wird in einem anderen Blog Post beschrieben. :)



Keine Kommentare: