PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Joystick --> Visual Basic-->Arduino-->Servo



dulone
24.05.2014, 20:20
Hallo Zusammen,

ich habe ein kleines Problem und hoffe sehr das ihr mir weiterhelfen könnt. Konkret geht es darum, dass ich Joystickeingaben (Cyborg Evo) per Visual Basic Express 2010 einlese und diese dann über den Serial Port an einen Arduino Mega sende, um dort Servos zu bewegen. Das funktioniert solange wunderbar, solange ich nur 2 Werte übergebe. Also X und Y Achse oder Y und Z Achse und so weiter. Sobald ich versuche 3 Servos anzusteuern wird meine Z Achse ignoriert.
Hier mal die meiner Meinung nach wichtigsten Teile des Visual Basic Codes:


Public Class Form1

Private myJoystick As joystick

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Try
myJoystick = New joystick(Me.Handle, -1000, 0, 0, 100) 'erstellt eine neue Instanz der Joystick-Klasse
Catch ex As Exception
MsgBox(ex.Message)
End Try
SerialPort1.Open()

End Sub

Private Sub pollingTimer_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles pollingTimer.Tick
Try
myJoystick.poll()


SerialPort1.Write(myJoystick.StatusInformation.Pos ition.Y.ToString - 1500 & myJoystick.StatusInformation.Rotation - 2501 & myJoystick.StatusInformation.Position.X.ToString) 'hier liegt mein Problem!!

Catch ex As Exception
Label7.Text = "" + ex.Message.ToString
End Try

End Sub




In der Zeile "SerialPort1.Write..." liegt auch das Problem Position.X und Position.Y werden übergeben, "Rotation" aber nicht.
Wobei auch alle Paarkombinationen funktionieren (siehe oben) also es nicht an der Übergabe von "Rotation" an sich liegen kann sondern eben wahrscheinlich am Einlesen am Arduino.

polling Timer fragt alle 100ms

und hier der Arduino Code:


#include <Servo.h>

Servo Servo1;
Servo Servo2;
Servo Servo3;


void setup (){

Servo1.attach(9);
Servo2.attach(10);
Servo3.attach(11);

Serial.begin(9600);

}


void loop()
{
int i;
char X_buffer[4]; //Max. Zahl "9999"
int incomingpos = 0;



while(incomingpos == 0)
{
if (Serial.available())
{

Serial.flush();
delay(5);
i=0;
while(i<5)
{
X_buffer[i] = Serial.read();
i++;
}
Serial.flush();
incomingpos = atoi(X_buffer);
Serial.println(incomingpos);



//Servo Lenkung
if ((incomingpos >= -1000) && (incomingpos <= 0))
{
incomingpos = map(incomingpos, -1000, 0, 0, 179); // x Achse


Servo1.write(incomingpos);

delay(10);
}
// Regler Beschleunigung
else if ((incomingpos <= -1501) && (incomingpos >= -2500))
{
incomingpos = map(incomingpos, -1501, -2501, 0, 179); // y Achse
Servo2.write(incomingpos);
delay(10);
}

// Servo Lenkung parralell (z-Achese)
else if ((incomingpos <= 2501) && (incomingpos >=3500))
{
incomingpos = map(incomingpos, -2501, -3501, 0, 179); // z Achse
Servo3.write(incomingpos);
delay(10);
}


}
incomingpos = 0;

}
}


Wäre super wenn sich jemand die Zeit nimmt um den Code zu checken. Komme seit einer Woche nicht voran.
Über jeden Hinweis bin ich sehr dankbar und falls noch Infos fehlen gerne laut schreien.


Grüße
dulone

HeXPloreR
25.05.2014, 07:39
Hallo,

ich kenne mich zu wenig mit VB aus und mit Arduino-C garnicht, aber kann es sein das in der dritten Bedingung (Servo Lenkung parralell) die Vorzeichen der Werte nicht korrekt sind? Sie weichen jedenfalls von der Systematik der anderen Schwellenwerte ab. Ob das jetzt das anscheinende Problem auslöst kann ich nicht sagen.

Viele Grüße
Jörg

Sisor
25.05.2014, 11:06
Nur schnell überflogen:
Die Bedingung kann nicht erfüllt werden:

else if ((incomingpos <= 2501) && (incomingpos >=3500))

Die schon:

else if ((incomingpos >= 2501) && (incomingpos <=3500))

- - - Aktualisiert - - -


SerialPort1.Write(myJoystick.StatusInformation.Pos ition.Y.ToString - 1500 & myJoystick.StatusInformation.Rotation - 2501 & myJoystick.StatusInformation.Position.X.ToString) 'hier liegt mein Problem!!
Richtig!
Mal ne Analyse:
1. Wir nehmen an, der Joystick ist etwas aus der Mittellage ausgelenkt, sodass
myJoystick.StatusInformation.Position.X
vielleicht 100 liefert
myJoystick.StatusInformation.Position.Y
vielleicht 200 liefert

2. Nehmen wir an, der Befehl lautet:
SerialPort1.Write(myJoystick.StatusInformation.Pos ition.X.ToString )
->Dann kommt am Empfänger ein String an z.B. "100" .

3. Nehmen wir an, der Befehl lautet nun:
SerialPort1.Write(myJoystick.StatusInformation.Pos ition.X.ToString & myJoystick.StatusInformation.Position.Y.ToString )
->Dann kommt am Empfänger ein String an z.B. "100200".

4. Den String wandeln wir wieder um in eine Ganzzahl "100200" -> 100200.

Die Methode solltest du überarbeiten.

-- Lösung mit Write(String) ------------------------------------
Kannst du sagen welche Parameter hier übergeben werden?

joystick(Me.Handle, -1000, 0, 0, 100)
Ich VERMUTE es wäre schlauer, gleich zu schreiben:

joystick(Me.Handle, 0, 179, 0, 100)
--
Wenn das geht, kannst du schreiben:

...
joystick(Me.Handle, 0, 179, 0, 100)
...
Dim joyData As Integer
joyData = myJoystick.StatusInformation.Position.X + myJoystick.StatusInformation.Position.Y *256 + myJoystick.StatusInformation.Rotation *256*256
SerialPort1.Write(joyData.toString)
...
--
Im Arduino Code:

...
char X_buffer[8]; //Max. Zahl "16700000"
int joyData = atoi(X_buffer);
int x = joyData & 0xff;
int y = (joyData >> 8) & 0xff;
int rot = (joyData >> 16) & 0xff;
...

--- BESSER: Lösung ohne Stringumwandlung ------------------------------------


...
joystick(Me.Handle, 0, 179, 0, 100)
...
Dim joyData(3) As Byte
joyData(0) = myJoystick.StatusInformation.Position.X
joyData(1) = myJoystick.StatusInformation.Position.Y
joyData(2) = myJoystick.StatusInformation.Rotation
SerialPort1.Write(joyData, 0, 3)
...

Arduino Code:


#include <Servo.h>
#define LEN 3
Servo Servo1;
Servo Servo2;
Servo Servo3;

void setup()
{
Servo1.attach(9);
Servo2.attach(10);
Servo3.attach(11);
}

void loop()
{
if(Serial.available() == LEN)
{
byte joyData[LEN];
int i = 0;
while(Serial.available()>0)
{
joyData[i++] = Serial.read();
}
Servo1.write(joyData[0]); // Position.X
Servo2.write(joyData[1]); // Position.Y
Servo3.write(joyData[2]); // Rotation
}
delay(10);
}

dulone
25.05.2014, 15:52
Erstmal ein riesen Dankeschön für eure schnellen Antworten. Bin begeistert.

@ HeXPloreR
das ist natürlich richtig, da sind mir in der else if Zeile tatsächlich Minuszeichen abhanden gekommen.
Vielen Dank für den Hinweis.


@ Sisor
nur Bytes zu übergeben klingt interessant und macht das ganze auch übersichtlicher.
Ich werde das heute Abend gleich ausprobieren, hab nur gerade meinen Rechner nicht zur Verfügung. Werde dann so schnell wie möglich Rückmeldung geben.
Abgesehen davon nochmal ein großes Dankeschön für den Aufwand den du dir gemacht hast.
Grüße
dulone

Sisor
25.05.2014, 16:52
Kein Problem...
Wenn du Lust hast dein Projekt mal vorzustellen: Das Forum freut sich!