-         

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 15

Thema: RP6 über Joystick steuern (in VB2008)

  1. #1
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    04.03.2010
    Beiträge
    205

    RP6 über Joystick steuern (in VB2008)

    Anzeige

    Hallo,
    Ich habe mir in Visual Basic 2008 ein kleines Programm geschrieben, welches mir ermöglicht die Positioswerte eines Joysticks zu ermitteln.
    Ziel dieses Projekts ist es, dass man den RP6 mit einem Joystick über UART steuern kann. Das Visual Basic Programm funktioniert soweit,
    aber bei dem Empfangen von Daten mit dem RP6 haperts noch.

    Hier sind ein paar Download-Links:
    Joystick.exe (Prototyp)
    Joystick.exe (Quellcode)

    Und hier der Code für den RP6:
    Code:
    #include "RP6RobotBaseLib.h" 
    
    int main(void) 
    { 
       
       
       initRobotBase(); 
       powerON(); 
       void bewegdich() 
       {
        char receiveBuffer[5];  // <<-- da kommt der Text rein 
        uint16_t value[5];   // Array deklarieren   
        clearReceptionBuffer();   // Empfangspuffer leeren 
        
       uint8_t buffer_pos = 0;    
       while(buffer_pos < 4)    // Bis 4 Zeichen empfangen sind
        {
          if(getBufferLength())   // Sind neue Zeichen da? 
          {  
             setLEDs(0b111111);     
             receiveBuffer[buffer_pos] = readChar(); // Ein Zeichen lesen 
             value[buffer_pos] = atoi(receiveBuffer[buffer_pos]); //Zahlenwert in Array schreiben
             buffer_pos++;    // um eins erhöhen
          }                               
       } 
        uint8_t richtung = value[0] ;           // Variablen die empfangenen Werte zuweisen
    	uint8_t geschwindigkeit = value[1];
        uint8_t r= value[2];
        uint8_t l= value[3];
    	
    	  if (richtung == 1 )
          {
    	   changeDirection(FWD);
           moveAtSpeed(l*geschwindigkeit,r*geschwindigkeit);  
    	  }
    	  if (richtung == 2 )
          {
    	   changeDirection(BWD);
           
    	   moveAtSpeed(l*geschwindigkeit,r*geschwindigkeit);  
    	  }
    	  if (richtung == 3 )
          {
    	   rotate(geschwindigkeit, LEFT, 30,true);
    	  }
    	  if (richtung == 4 )
          {
    	   rotate(geschwindigkeit, RIGHT, 30,true);
    	  }
    	  
    	  
       }
       
       while(true) 
       { 
       
       task_RP6System(); 
       bewegdich();
        
       }	  
       }
    Jeder der einen Joystick hat kann das Programm ausprobieren. (Framework 3.5 erforderlich)
    Vielleicht kann mirja auch jemand mit dem Code vom RP6 helfen.
    Er zeigt mir zwar, dass er Daten empfängt (durch das blinken der LED´s), aber er fährt nicht.
    Würde mich über Verbesserungsvorschläge freuen.
    Nichts existiert durch sich allein!
    http://i42.tinypic.com/10pa90x.jpg

  2. #2
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    04.03.2010
    Beiträge
    205
    Hat sich schon jemand das Programm angeschaut? Wiegesagt wenn ihr Verbesserungsvorschläge habt, oder Fehler entdeckt, schreibt es mir.
    Nichts existiert durch sich allein!
    http://i42.tinypic.com/10pa90x.jpg

  3. #3
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    27.09.2009
    Alter
    22
    Beiträge
    661
    Ich schätze du soltest Else If nehmen. Auserdem wird wahr scheinlich das Komando immer wieder gelöscht ich würde Ausserhalb der Hauptschleife einmal den Puffer leeren und dann nur nach jedem ausgeführten Komando.
    MfG Martinius

  4. #4
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    54
    Beiträge
    5.782
    Blog-Einträge
    8
    Hallo

    Ich hatte mal ein Poti auf die Antriebe des RP6 geschaltet, Wertebereich war von 0 bis 1023:

    http://www.roboternetz.de/phpBB2/vie...=452519#452519

    Das berücksichtigt allerdings nur eine Achse des Joysticks. Dein VB-Programm kann ich nicht testen, weil ich keinen Joystick für den PC besitze ;)

    Gruß

    mic

    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  5. #5
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    04.03.2010
    Beiträge
    205
    Hi,
    @Martinius11,
    Ich habe die Vorschläge umgesetzt und musste leider feststellen, dass es das Problem nicht gelöst hat.
    @radbruch
    Das Programm für das Poti kann ich vielleicht so umscreiben, dass ich statt der ADC-Werte die Werte empfange die über USART reinbekomme.
    Nichts existiert durch sich allein!
    http://i42.tinypic.com/10pa90x.jpg

  6. #6
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    04.03.2010
    Beiträge
    205
    Habt ihr vielleicht eine Idee wie man Zahlen, die über UART (vom Terminal geschickt) ankommen mit dem RP6 in Integer-Werte umwandeln kann, sodass die dann zum Rechnen verwendet werdet können?
    Nichts existiert durch sich allein!
    http://i42.tinypic.com/10pa90x.jpg

  7. #7
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    27.09.2009
    Alter
    22
    Beiträge
    661
    da wird dein Problem liegen den du wilst den Adc in char receiveBuffer[5];
    zu schreiben. char ist aber ein 8-bit datentyp
    MfG Martinius

  8. #8
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    54
    Beiträge
    5.782
    Blog-Einträge
    8
    Hallo

    Für die Übertragung der Daten kenne ich eigentlich nur zwei grundsätzliche Möglichkeiten: Direkte Übertragung von Bytewerten oder als Zeichenkette.

    Bytewerte wäre für den RP6 wohl die einfachste Lösung. Das VB-Programm auf dem PC rechnet den Joystickwert in einen Wert von 0 bis 255 um und sendet das Ergebniss zum RP6. Bei zwei Joystickachsen errechnet der PC die Mischerwerte für jede Seite getrennt und sendet dann die Ergebnisse zum RP6. Dieser errechnet aus dem empfangenen Byte die Drehrichtung (< oder > als 127) und die Geschwindigkeit (0-210).

    Mit einem kleinen Protokoll sollte das einfach umzusetzen sein. Entweder mit Start- und Ende-Kennung, z.B.:

    print "*"; Wert_links; Wert_rechts; "#"

    Wenn der RP6 im Eingang ein * erkennt, sind die nächsten beiden Bytes die gesuchten Werte. Das # zeigt das Ende der Übertagung und ist gleichzeitig ein Indiz für eine fehlerfreie Übertragung der zuvor gesendeten Bytes. Alternativ wäre auch ein solches Protokoll sinnvoll:

    Print "L"; Wert_links
    Print "R"; Wert_rechts

    Der RP6 prüft dann immer auf L oder R und interpretiert den darauffolgenden Wert das Parameter. Das könnte man auch einfach mit dem RP6Loader testen. Dieser beherrscht beim Senden auch verschiedene Zahlenformate (mit .help im Terminalfenster zu erfahren), ein Test im Terminalfenster des RP6Loader könnte dann so aussehen:

    L
    .n100
    R
    .n100

    Sendet ein 'L', ein Byte mit 100, ein 'R', ein Byte mit 100. Das angepasste Programm der Potiauswertung würde dann etwa so aussehen:

    Code:
    // Steuerung beider Antriebe 0-255                                    18.9.10 mic
    
    // Einlesen über die serielle Schnittstelle fehlt noch!
    
    // Die für jede Seite getrennt eingelesen Werte werden in Richtung
    // und Geschwindigkeit umgerechnet.
    
    #include "RP6RobotBaseLib.h"
    
    #define joy_x_min 0
    #define joy_x_max 255
    #define joy_x_mid 127
    #define joy_y_min 0
    #define joy_y_max 255
    #define joy_y_mid 127
    
    uint8_t speed_l, speed_r;
    uint8_t dir_l, dir_r;
    uint8_t VB_wert_l, VB_wert_r; // empfangene Werte von 0-255
    uint16_t joy_x, joy_y;
    
    int main (void)
    {
       initRobotBase();
       powerON();
    
       while(1)
       {
          joy_x=VB_wert_l;
          joy_y=VB_wert_r;
    
    writeInteger(joy_x, 10);
    writeChar(':');
    writeInteger(joy_y, 10);
    writeChar(' ');
    
          if(joy_x > joy_x_mid)
          { // vorwärts
    writeChar('F');
             dir_l=FWD;
             speed_l=(joy_x-joy_x_mid)*105/(joy_x_max-joy_x_mid);
          }
          else
          { // rückwärts
    writeChar('B');
             dir_l=BWD;
             speed_l=(joy_x_mid-joy_x)*105/(joy_x_mid-joy_x_min);
          }
    writeInteger(speed_l*2, 10);
    writeChar('\n');
    
          if(joy_y > joy_y_mid)
          { // vorwärts
    writeChar('F');
             dir_r=FWD;
             speed_r=(joy_y-joy_y_mid)*105/(joy_y_max-joy_y_mid);
          }
          else
          { // rückwärts
    writeChar('B');
             dir_r=BWD;
             speed_r=(joy_y_mid-joy_y)*105/(joy_y_mid-joy_y_min);
          }
    
    writeInteger(speed_r*2, 10);
    writeChar('\n');
    
          setMotorDir(dir_l,dir_r);
    		moveAtSpeed(speed_l*2,speed_r*2);
          task_motionControl();
          mSleep(200);
       }
       return(0);
    }
    Bei der byteweisen Übertagung wird jeweils ein Wert in einem Byte übertragen. Als Alternative kann man auch den zu übertragenden Wert in eine Zeichenfolge (=String) umwandeln und dann die Zeichen der Zeichenkette übertragen. Zur Optimierung kann man bei diesem Verfahren noch jeweils zwei Zifffern in einem Byte übertragen (BCD) oder eine andere Zahlenbasis verwenden (Hex). Das wollte ich der Form halber erwähnen. Großer Vorteil ist dabei, dass man den Datenstrom quasi im Klartext mitlesen könnte, Nachteil der erhebliche Aufwand bei der Stringumwandlung und die größere zu übertragende Datenmenge.

    Um sicherzustellen, dass der RP6 alles richtig verstanden hat, wäre es einfach, wenn der RP6 das empfangene Zeichen bzw. das Byte direkt zurückschickt. Der PC kann dann erkennen, ob das Byte richtig übertragen wurde (Echo). Schneller und etwas komplizierter und deshalb erst bei größeren Datenmengen sinnvoll wäre ein Blockcheck. Ein Block mehrerer Bytes wird übertragen und nach der Übertragung antwortet der RP6 mit einer Prüfsumme die er aus dem empfangenen Block errechnet hat. Der PC vergleicht diesen Wert dann mit dem von ihm selbst errechneten Wert (CRC)

    Eine kleine Linkliste zum Thema Zahlendarstellungen hatte ich hier mal zusammengestellt:
    http://www.roboternetz.de/phpBB2/zei...g.php?p=353264

    Sorry, der Beitrag wurde irgendwie immer länger.

    Gruß

    mic

    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  9. #9
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    04.03.2010
    Beiträge
    205
    Danke für diese umfangreiche Antwort.
    Ich habe mir jetzt eine LIB gebastelt. Das funktioniert auch soweit. Ich verwende die Motorsteuerung der rblib.
    Aber Ich habe noch ein Problem beim Empfangen von Bytes über UART.
    Ich verwende diese Funktion:
    Code:
    uint8_t readByte(void)
    {
    while(!(UCSRA&(1<<RXC))); //Warten, bis ein Byte empfangen wurde!
    return UDR; //Lies  dieses Byte
    }
    Jetzt versuche ich die Funktion zu testen:
    Code:
    #include "lib.h" 
    
    int main(void)
    {
    char a;
    delta_init();
    usart_init();
    
    while(1)
    {
    writeString("Empfangen:");
    a = readByte();
    writeChar(a);
    }
    }
    Aber das funktioniert nicht so wie ich mir das vorstelle. Der RP6 sendet nur "Empfangen:" aber dann keinen Wert. Eigentlich sollte er wenn ich ihm über das Terminal ein Byte sende dieses wieder zurückgeben.
    Hat jemand eine Idee wo der Fehler liegen könnte?
    Nichts existiert durch sich allein!
    http://i42.tinypic.com/10pa90x.jpg

  10. #10
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    04.03.2010
    Beiträge
    205
    Hat vielleicht schon jemand anderes eine Lib für den RP6 geschrieben, um ohne ISR über USART kommunizieren zu können?
    Nichts existiert durch sich allein!
    http://i42.tinypic.com/10pa90x.jpg

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •