Servo mit dem Xbox Controller steuern
Das ansteuern eines Servos über einen Xbox One Controller ist simpel umzusetzen. Für dieses Beispiel wird folgendes verwendet:
- MonoGame
- Xbox Controller
- Arduino UNO oder vergleichbar
- Servo
- Motor Shield
- Externe Batterie
Nach der Installation von MonoGame sind in Visual Studio mehre Vorlagen verfügbar. Benötigt wird das Template 'MonoGame Windows Project', das im folgenden Bild als erstes in der Liste erscheint.
Programmcode mit MonoGame
Sobald das Projekt angelegt würde, könnt ihr die Game1.cs Datei öffnen. Für die Verbindung zum Arduino wird die Klasse SerialPort verwendet. Dazu sollte vorher bekannt sein, welcher COM Port bei euch der Arduino verwendet. Die Baudrate von 115200 ist die maximale Geschwindigkeit, die zuverlässig funktioniert. Die restlichen Parameter sind die Default Werte der Seriellen Verbindung zum Arduino (siehe Programmcode).
Die überschriebenen Methoden 'Initialization()', 'LoadContent()' und 'Draw()' werden für das Beispiel nicht verwendet und können entfernt werden.
Mit der Update Methode wird der Xbox Controller eingelesen. Der Input Wert vom Stick kommt dann aus dem GamePadState unter '.ThumbSticks.Left.X'. Der Float Wert geht von -1 bis +1 und wird deshalb zunächst um plus eins dass Offset verschoben. Anschießend wird der Float Wert in ein Byte Wert transformiert, dass dann anschließend an den Serial Port geschrieben wird.
Damit die Anwendung nicht zu viele Bytes versendet, wird am Ende 50 Millisekunden gewartet. Ansonsten läuft der Buffer im Arduino über.
Damit die Anwendung nicht zu viele Bytes versendet, wird am Ende 50 Millisekunden gewartet. Ansonsten läuft der Buffer im Arduino über.
GraphicsDeviceManager _graphics;
private SerialPort _serialPort;
public Game1()
{
_graphics = new GraphicsDeviceManager(this);
// Verwendete COM Port muss ggf. angepasst werden.
this._serialPort = new SerialPort("COM5", 115200, Parity.None, 8, StopBits.One);
this._serialPort.Open();
}
protected override void UnloadContent()
{
this._serialPort.DiscardOutBuffer();
this._serialPort.Close();
}
protected override void Update(GameTime gameTime)
{
GamePadState state = GamePad.GetState(PlayerIndex.One);
byte stickValue = (byte)((state.ThumbSticks.Left.X + 1) * 90);
this._serialPort.Write(new byte[] { stickValue }, 0, 1);
Task.Delay(50).Wait();
}
Arduino als Empfänger
Der Arduino muss nun die empfangenden Bytes vom PC entgegen nehmen und daraus ein PWM Signal erzeugen das zur Steuerung des Servos verwendet wird. Weiters habe ich im Programmcode beschrieben.
#include <Servo.h>
Servo servo;
int servoPin = 9;
int receivedValue;
void setup() {
// Muss die selbe Baudrate haben,
// wie in der MonoGame Anwendung.
Serial.begin(115200);
// die meisten Servos arbeiten mit einem
// HIGH Signal von 1ms bis 2ms.
servo.attach(servoPin, 1000, 2000);
}
void loop() {
if( Serial.available() > 0){
receivedValue = Serial.read();
// Den eingelesenen Wert Abschneiden,
// falls der maximale Stellwert überschritten wird.
if(receivedValue > 180) {
receivedValue = 180;
}
else if(receivedValue < 0) {
receivedValue = 0;
}
// alle weiteren eingegangenen bytes werden verworfen
Serial.flush();
}
// Aktuellen Einstellwert festlegen.
servo.write(receivedValue);
delay(20);
}
Was nun
Im Grunde ist die Ausführung simpel und das Schreiben dieses Post hat da deutlich mehr Zeit benötig. :D
Aber was kann man nun mit dem Wissen anstellen? Nun, man kann stattdessen einer Kabelgebundenen Ausführung, auf eine Bluetooth Funkverbindung wechseln. Damit ließe sich dann ein RC Model ansteuern. Mag etwas Umständlich sein, die Fernsteuerung gegen etwas eigenes gebasteltes zu ersetzen, aber darin liegt der Spaß.
Zur Vollständigkeit wieder ein Link zu dem Github Repository und dem gesamten Beispiel Programmcode.
Nachtrag
Leider funktioniert dieses einfache Beispiel nur in dieser Konstellation. Sobald versucht wird, zwei Bytes zu versenden, treten Probleme auf mit der Seriellen Verbindung.
Wie man das behebt, beschreibe ich mit dem Post "Zeichnen auf dem TFT mit dem XBox Controller"
Nachtrag
Leider funktioniert dieses einfache Beispiel nur in dieser Konstellation. Sobald versucht wird, zwei Bytes zu versenden, treten Probleme auf mit der Seriellen Verbindung.
Wie man das behebt, beschreibe ich mit dem Post "Zeichnen auf dem TFT mit dem XBox Controller"
Kommentare