Hallo,
ich bin noch relativ neu bei der Sache und stehe im Moment vor einem Problem, welches ich einfach nicht lösen kann.
Es geht darum, dass ich am Ende meine RC Helikopter mit einem Xbox Gamepad steuern möchte. Meine Idee dazu war folgende:
Ich schließe das Gamepad an den PC und sende die Position der Gamepad Sticks an einen Arduino Uno, der mir dann ein PPM Signal erzeugt, was ich dann an ein HF-Modul weitergebe. Soweit funktioniert auch alles.
Jetzt zu Meinem Problem. Ein einzelner PPM Frame ist etwa 22,5 ms lang. davon werden ca. 8-16ms für die Daten benötigt und ca. 6,5-14ms zur Synchronisation. Da sich in der Zeit der Synchronisation der Wert des Signals nicht ändert hab ich hier Zeit für Berechnungen, Kommunikation usw... Auf der Seite kann man sich so ein Signal noch einmal genau anschauen:
http://www.mftech.de/ppm.htm
Wenn mein PC nun ein Signal an den Arduino schickt muss ich damit im Idealfall den Anfang der Synchronisationzeit treffen, damit ich die Daten lesen kann usw..., tue ich das nicht, dann braucht der Arduino zu lange zum lesen und die Synchronisationphase wird zu lang, was dazu führt, dass meine Servos zucken...
Ich bin als erstes etwas Blauäugig rangegangen und habe einfach alle 50ms ein Signal an den Arduino geschickt und mir gedacht, dass ich damit schon irgendwie treffen werde. Leider ist das nun nicht der Fall und auch andere Sendeintervalle helfen nicht.
Als zweites habe ich versucht ein Signal an den PC zu senden, wenn die Synchronisationphase beginnt und ihn dann Daten schicken zu lassen, was dann leider noch vielweniger funktioniert.
Der dritte Versuch war dann über Timer und Interrupts die Kommunikationsphase zu erzwingen. Aber wie man sich schon denken kann wird der Controller dann beim Lesen der Daten gestört und das Signal spinnt durch die unvollständigen Daten wie verrückt...
Für mein Problem gibt es sicherlich eine Lösung, die ich aber auf Grund meiner Unerfahrenheit nicht kenne. Es wäre schön, wenn mir jemand helfen könnte.
Ach ja hier noch der relevante Quelltext: (Ich weiß er ist nicht unbedingt hübsch)
Arduino:
int pin = 12;
int a = 1000;
int b = 1000;
int c = 1000;
int d = 1000;
int e = 1000;
int f = 1000;
int g = 1000;
int h = 1000;
int incomingByte;
char chan;
unsigned long prevMicros = 0;
void setup() {
pinMode(pin, OUTPUT);
Serial.begin(115200);
Serial.setTimeout(0);
}
void loop() {
unsigned long currentMicros = micros();
int i = 0;
if((currentMicros - prevMicros) < (22500-a-b-c-d-e-f-g-h-2.7)){
digitalWrite(pin, 1);
if (Serial.available() > 0) {
delay(1);
while(Serial.available() > 0)
{
chan = Serial.read();
switch (chan){
case 'a':
a = Serial.parseInt();
break;
case 'b':
b = Serial.parseInt();
break;
case 'c':
c = Serial.parseInt();
break;
case 'd':
d = Serial.parseInt();
break;
case 'e':
e = Serial.parseInt();
break;
case 'f':
f = Serial.parseInt();
break;
case 'g':
g = Serial.parseInt();
break;
case 'h':
h = Serial.parseInt();
break;
}
}
}
}
else{
digitalWrite(pin, 0);
delayMicroseconds(300);
digitalWrite(pin, 1);
delayMicroseconds(a);
digitalWrite(pin, 0);
delayMicroseconds(300);
digitalWrite(pin, 1);
delayMicroseconds(b);
digitalWrite(pin, 0);
delayMicroseconds(300);
digitalWrite(pin, 1);
delayMicroseconds(c);
digitalWrite(pin, 0);
delayMicroseconds(300);
digitalWrite(pin, 1);
delayMicroseconds(d);
digitalWrite(pin, 0);
delayMicroseconds(300);
digitalWrite(pin, 1);
delayMicroseconds(e);
digitalWrite(pin, 0);
delayMicroseconds(300);
digitalWrite(pin, 1);
delayMicroseconds(f);
digitalWrite(pin, 0);
delayMicroseconds(300);
digitalWrite(pin, 1);
delayMicroseconds(g);
digitalWrite(pin, 0);
delayMicroseconds(300);
digitalWrite(pin, 1);
delayMicroseconds(h);
digitalWrite(pin, 0);
delayMicroseconds(300);
prevMicros = micros();
}
}
PC(C#):
private void timer1_Tick(object sender, EventArgs e)
{
State state = _Controller.GetState();
RightStick = new ThumbstickState(
Normalize(state.Gamepad.RightThumbX, state.Gamepad.RightThumbY, Gamepad.GamepadRightThumbDeadZone),
(state.Gamepad.Buttons & GamepadButtonFlags.RightThumb) != 0);
LeftStick = new ThumbstickState(
Normalize(state.Gamepad.LeftThumbX, state.Gamepad.LeftThumbY, Gamepad.GamepadLeftThumbDeadZone),
(state.Gamepad.Buttons & GamepadButtonFlags.LeftThumb) != 0);
string str = "c" + (1000 + (int)(RightStick.Position.Y * 200)) + "b" + (1000 + (int)(RightStick.Position.X * 300)) + "a" + (1000 + (int)(state.Gamepad.RightTrigger / (float)byte.MaxValue * 500))
+ "d" + (1000 + (int)(LeftStick.Position.X * 300));
label1.Text = str;
port.Write(str);
}