- LiTime Speicher und Akkus         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 16

Thema: RP6 steuern mittels M32

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    01.05.2008
    Beiträge
    52

    RP6 steuern mittels M32

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hmm wie isn das, wenn ich den RP6 über den M32 steuern will, was brauch ich denn da alles? Weil diese Beispielprogramme sind da ziemlich vollgestopft mit den ganzen I2C sachen. Sind die alle nötig?
    Und was brauch ich eigentlich im Programm für die Basis damit das verarbeiten kann?

    Ist zwar schön das es am Anfang der Programme meist beschrieben wird was da sganze programm macht, aber es wäre doch evtl ganz nett wenne manche einzelne Punkte genauer beschrieben werden.

  2. #2
    Erfahrener Benutzer Roboter Genie Avatar von SlyD
    Registriert seit
    27.11.2003
    Ort
    Paderborn
    Alter
    39
    Beiträge
    1.516
    Hallo,

    wenn mal irgendwo keine Kommentare da sind, dann sind es meist "sprechende" Namen für die Variablen und Funktionen die sich von selbst erklären.
    Aber wenn Du fragen zu einem bestimmten Teil hast - dann kannst Du das hier natürlich gerne posten!


    > Hmm wie isn das, wenn ich den RP6 über den M32
    > steuern will, was brauch ich denn da alles?

    Du musst dich eigentlich gar nicht großartig mit dem I2C Bus befassen wenn Du das nicht willst - nimm halt die fertige
    RP6Control_I2CMasterLib.h und .c aus dem Example10_Move2.

    Dann kannst Du den Roboter mal abgesehen von ein zwei kleinen Unterschieden die aber in den Kommentaren stehen fast so steuern als wäre der I2C Bus gar nicht da.
    Also move, rotate, moveAtSpeed, changeDirection usw. alles wie gehabt.
    setLEDs und setRP6LEDs ist ein kleiner Unterschied.
    updateStatusLEDs funktioniert genau wie beim Mainboard auch.

    Die Funktionen heissen also *fast* alle genauso wie in der BaseLib und funktionieren auch genauso. Einfach in der Hauptschleife immer diese beiden:
    task_checkINT0();
    task_I2CTWI();

    Funktionen aufrufen, dann wird alles automatisch gemacht.

    OK - nur die größeren Sensordaten (alles was nicht einfach nur 0 oder 1 wie ACS und Bumper ist) muss man bei Bedarf abgleichen.
    s. getAllSensors() und getLightSensors() als Beispiele wie man das macht.
    Die Variablen heissen dann auch genauso wie in der BaseLib.
    Also adcBat, adcMotorCurrentLeft,... usw. alles identisch.


    Du musst natürlich das I2CSlave Programm in den Controller auf dem Mainboard laden damit das alles funktioniert.

    Btw. da ist mir gerade noch aufgefallen das im Example10_Move2 Beispiel die setRP6LEDs noch "inline" deklariert ist. Das klappt mit der neuesten WinAVR Version ja leider nicht mehr. Einfach das inline in beiden Dateien (.c und .h) löschen dann geht es. Wird demnächst behoben.
    Mit den 2007er Versionen von WinAVR sollte es auch so funktionieren.

    MfG,
    SlyD

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    01.05.2008
    Beiträge
    52
    Vielen Dank für den tip, hab damit nu mal mein Programm weiter gebaut.
    Nun hab ich aber ein anderes kleines Problem.
    das I2CSlave auf der Basis werde ich noch etwas ändern, da die Basis selber etwas machen soll, bis vom M32 eine bestimmte variable gelöscht wird, dann übernimmt die und gibt später die Controlle sieder zurück an die Basis wenn die Variable wieder gesetzt wird.

    Doch genau daran hapert es grad, wie kann ich denn eine einzelne Variable z.B. active auf der Basis löschen lassen?

  4. #4
    Erfahrener Benutzer Roboter Genie Avatar von SlyD
    Registriert seit
    27.11.2003
    Ort
    Paderborn
    Alter
    39
    Beiträge
    1.516
    Schau Dir mal

    void task_commandProcessor(void)

    an.
    Da einfach nen neues Kommando hinzufügen (neuen case) in dem halt irgendwas gemacht wird active = param1 z.B.
    Der Aufruf geht dann genauso wie bei CMD_SETLEDS.

    MfG,
    SlyD

  5. #5
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    09.04.2008
    Beiträge
    384
    Das muss in beide Programme etwas geandert werden. An sich halte ich das nicht gerade fur sinnfoll, da die Basis alle Sensorwerten weitergebt an den Master. Auch kan die Master alle Befehle weiter geben an die Basis. Ist der M32 schon ueberfordert mit ihre heutige Program ?
    Aber basis sind die I2C Register in Master und Slave. Darueber laufen alle Werten die beide auswechselen. Diese Register können erweitert werden, und darueber kannst du dan die Variabele nutzen.

  6. #6
    Benutzer Stammmitglied
    Registriert seit
    01.05.2008
    Beiträge
    52
    Danke schonmal für die Tips, werde ich dann demnächst umsetzen.
    Hab da aber gerade irgendein anderes Problem.
    Ich hab meiner Meinung nach eigentlich alles wichtige drin um die Basis über den M32 zu steuern aber ich bekomme immer eine Fehlermeldung mit 0x20.
    Hab mal testweise das selftest programm auf den M32 geladen, das lief ohne Fehlermeldung.

    Sieht jemand hier den Fehler?

    Code:
    #include "RP6ControlLib.h"
    #include "RP6I2CmasterTWI.h"
    #include "RP6Control_I2CMasterLib.h"
    
    void I2C_transmissionError(uint8_t errorState)
    {
    	writeString_P("\nI2C ERROR - TWI STATE: 0x");
    	writeInteger(errorState, HEX);
    	writeChar('\n');
    }
    
    ...
    ...
    ...
    
    int main(void)
    {
        initRP6Control();
    
    
    	I2CTWI_initMaster(100);
    	I2CTWI_setTransmissionErrorHandler(I2C_transmissionError);
    
        setLEDs(0);
    
        while(1)
        {
            task_checkINT0();
            task_I2CTWI();
    ...
    ...
    ...
            mSleep(500);
        }
        return 0;
    }
    Das ist jetzt nur ein Teil des Codes, der rest (die ...) betrifft aber eigentlich nur irgendwelche abfragen oder verarbeitung von sensorwerten etc.
    Insgesamt sind es halt etwa 315 zeilen code von denen ich euch die unwichtigen ersparen wollte *g*
    Das einzige was geschickt wird ist dann ein moveAtSpeed.

    Kann man eigentlich auch ein moveAtspeed(0,0) schicken? bzw gibt das eine Fehlermeldung?

  7. #7
    Erfahrener Benutzer Roboter Genie Avatar von SlyD
    Registriert seit
    27.11.2003
    Ort
    Paderborn
    Alter
    39
    Beiträge
    1.516
    Hallo,

    mach erstmal 500ms oder mehr Pause am Anfang - das ist im Slave Programm am Anfang nämlich noch drin (LEDs aufblinken lassen usw.).

    Hast Du das Slave Programm irgendwie geändert?

    0x20 kommt entweder bei falscher Slave Adresse oder natürlich bei fehlerhafter Übertragung.
    (die Fehlercodes stehen alle im RP6I2CmasterTWI.h Header)

    Wenn das alles nicht zutrifft - komplettes Programm posten bitte und alles nennen was sonst geändert wurde!

    MfG,
    SlyD

  8. #8
    Benutzer Stammmitglied
    Registriert seit
    01.05.2008
    Beiträge
    52
    Vielen Dank, das mit den 500 ms Pause scheint mein Problem behoben zu haben. Zumindest funktioniert es nun einigermassen richtig.
    Nun ist nur noch das Problem, das er irgendwie immer vorwärts fährt und nur nach rechts dreht. Egal wie ich steuer.

    Hier is nun eben dochmal das ganze Programm, ich hoffe ihr könnt es lesen.

    Code:
    #include "RP6ControlLib.h"
    #include "RP6I2CmasterTWI.h"
    #include "RP6Control_I2CMasterLib.h"
    
    void I2C_transmissionError(uint8_t errorState)
    {
    	writeString_P("\nI2C ERROR - TWI STATE: 0x");
    	writeInteger(errorState, HEX);
    	writeChar('\n');
    }
    
    extern uint8_t rc_input_right_y, rc_input_right_x, rc_input_active;
    /*
        Aufnahme der Servowerte des Empfaengers erfolgt in der ISR
        in der Datei RP6ControlLib.c ab Zeile 752
    */
    
    uint8_t speed_cruising, speed_rotating, speed_left, speed_right;
    uint8_t dir_cruising, dir_rotating, dir_cruising_high, dir_cruising_low, dir_rotating_high, dir_rotating_low;
    /*
        speed_cruising      := zu fahrende geschwindigkeit
        speed_rotating      := drehgeschwindigkeitsoffset
        dir_cruising        := zu fahrende richtung
        dir_rotating        := drehrichtung
        dir_cruising_high   := fahrrichtung mit hohen empfaengerwerten
        dir_cruising_low    := fahrrichtung mit niedrigen empfaengerwerten
        dir_rotating_low    := drehrichtung mit niedrigen empfaengerwerten
        dir_rotating_high   := drehrichtung mit hohen empfaengerwerten
        speed_left          := effektive geschwindigkeit links aus speed und speed_rotating
        speed_right         := effektive geschwindigkeit rechts aus speed und speed_rotating
    */
    
    static uint8_t speed_cruising_max = 100;
    static uint8_t speed_cruising_step = 30;
    /*
        speed_cruising_max  := maximale fahrgeschwindigkeit
        speed_cruising_step := geschwindigkeitsaenderung je schritt des empfaengers
    */
    
    static uint8_t speed_rotating_max = 50;
    static uint8_t speed_rotating_step = 20;
    /*
        speed_rotating_max  := maximaler offset zum drehen
        speed_rotating_step := drehgeschwindigkeitsaenderung je schritt des empfaengers
    */
    
    static uint8_t speed_mid = 0;
    /*
        speed_mid   := geschwindigkeitswerte bei mittelposition
    */
    
    int main(void)
    {
        initRP6Control();
    
    
    	I2CTWI_initMaster(100);
    	I2CTWI_setTransmissionErrorHandler(I2C_transmissionError);
    
        setLEDs(1);
        mSleep(500);
        setLEDs(0);
    
        while(1)
        {
            task_checkINT0();
            task_I2CTWI();
    
            /*
            writeString_P("RC active :");
            writeInteger(rc_input_active, 10);
            writeString_P(" - ");
            writeString_P("RC vorwaerts :");
            writeInteger(rc_input_right_y, 10);
            writeString_P(" - ");
            writeString_P("RC quer :");
            writeInteger(rc_input_right_x, 10);
            writeString_P("\n\r");
            */
    
    
            //ist die fernsteuerung aktiviert
            if ( rc_input_active >= 16 && rc_input_active <=18 )
            {
                //writeString_P(" RC aktiviert ");
                //fahrgeschwindigkeit auswerten
                switch( rc_input_right_y )
                {
                    //minimale werte
                    case 8:
                        writeString_P("y 8");
                        dir_cruising = dir_cruising_low;
                        speed_cruising = 4 * speed_cruising_step;
                        break;
                    case 9:
                        writeString_P("y 9");
                        dir_cruising = dir_cruising_low;
                        speed_cruising = 3 * speed_cruising_step;
                        break;
                    case 10:
                        writeString_P("y 10");
                        dir_cruising = dir_cruising_low;
                        speed_cruising = 2 * speed_cruising_step;
                        break;
                    case 11:
                        writeString_P("y 11");
                        dir_cruising = dir_cruising_low;
                        speed_cruising = 1 * speed_cruising_step;
                        break;
    
                    //mittlere werte
                    case 12:
                        writeString_P("y 12");
                        dir_cruising = dir_cruising_low;
                        speed_cruising = speed_mid;
                        break;
                    case 13:
                        writeString_P("y 13");
                        dir_cruising = dir_cruising_low;
                        speed_cruising = speed_mid;
                        break;
                    case 14:
                        writeString_P("y 14");
                        dir_cruising = dir_cruising_low;
                        speed_cruising = speed_mid;
                        break;
                    case 15:
                        writeString_P("y 15");
                        dir_cruising = dir_cruising_low;
                        speed_cruising = speed_mid;
                        break;
    
                    //maximale werte
                    case 16:
                        writeString_P("y 16");
                        dir_cruising = dir_cruising_high;
                        speed_cruising = 1 * speed_cruising_step;
                        break;
                    case 17:
                        writeString_P("y 17");
                        dir_cruising = dir_cruising_high;
                        speed_cruising = 2 * speed_cruising_step;
                        break;
                    case 18:
                        writeString_P("y 18");
                        dir_cruising = dir_cruising_high;
                        speed_cruising = 3 * speed_cruising_step;
                        break;
                    case 19:
                        writeString_P("y 19");
                        dir_cruising = dir_cruising_high;
                        speed_cruising = 4 * speed_cruising_step;
                        break;
    
                    //fuer alle anderen werte
                    default:
                        writeString_P("y default");
                        dir_cruising = dir_cruising_high;
                        speed_cruising = speed_mid;
                        break;
                }
                writeString_P("\n\r");
    
                //drehgeschwindigkeit auswerten
                switch ( rc_input_right_x)
                {
                    //niedrige werte
                    case 9:
                        writeString_P("x 9");
                        dir_rotating = dir_rotating_low;
                        speed_rotating = 5 * speed_rotating_step;
                        break;
                    case 10:
                        writeString_P("x 10");
                        dir_rotating = dir_rotating_low;
                        speed_rotating = 4 * speed_rotating_step;
                        break;
                    case 11:
                        writeString_P("x 11");
                        dir_rotating = dir_rotating_low;
                        speed_rotating = 3 * speed_rotating_step;
                        break;
                    case 12:
                        writeString_P("x 12");
                        dir_rotating = dir_rotating_low;
                        speed_rotating = 2 * speed_rotating_step;
                        break;
                    case 13:
                        writeString_P("x 13");
                        dir_rotating = dir_rotating_low;
                        speed_rotating = 1 * speed_rotating_step;
                        break;
    
                    //mittlere werte
                    case 14:
                        writeString_P("x 14");
                        dir_rotating = dir_rotating_low;
                        speed_rotating = speed_mid;
                        break;
                    case 15:
                        writeString_P("x 15");
                        dir_rotating = dir_rotating_low;
                        speed_rotating = speed_mid;
                        break;
                    case 16:
                        writeString_P("x 16");
                        dir_rotating = dir_rotating_low;
                        speed_rotating = speed_mid;
                        break;
                    case 17:
                        writeString_P("x 17");
                        dir_rotating = dir_rotating_low;
                        speed_rotating = speed_mid;
                        break;
    
                    //hohe werte
                    case 18:
                        writeString_P("x 18");
                        dir_rotating = dir_rotating_high;
                        speed_rotating = 1 * speed_rotating_step;
                        break;
                    case 19:
                        writeString_P("x 19");
                        dir_rotating = dir_rotating_high;
                        speed_rotating = 2 * speed_rotating_step;
                        break;
                    case 20:
                        writeString_P("x 20");
                        dir_rotating = dir_rotating_high;
                        speed_rotating = 3 * speed_rotating_step;
                        break;
                    case 21:
                        writeString_P("x 21");
                        dir_rotating = dir_rotating_high;
                        speed_rotating = 4 * speed_rotating_step;
                        break;
                    case 22:
                        writeString_P("x 22");
                        dir_rotating = dir_rotating_high;
                        speed_rotating = 5 * speed_rotating_step;
                        break;
    
                    //fuer alle anderen werte
                    default:
                        writeString_P("x default");
                        dir_rotating = dir_rotating_high;
                        speed_rotating = speed_mid;
                        break;
                }
                writeString_P("\n\r");
            }
            else
            {
                speed_cruising = 0;
                speed_rotating = 0;
            }
    
            /*
            writeString_P("X. ");
            writeInteger(rc_input_right_x, 10);
            writeString_P(" speed rot ");
            writeInteger(speed_rotating, 10);
            writeString_P(" Y. ");
            writeInteger(rc_input_right_y, 10);
            writeString_P(" speed crus ");
            writeInteger(speed_cruising, 10);
            writeString_P("\n\r");
            */
    
    
            //beschraenkung der maximalen werte
            if (speed_cruising > speed_cruising_max)
            {
                speed_cruising = speed_cruising_max;
            }
            if (speed_rotating > speed_rotating_max)
            {
                speed_rotating = speed_rotating_max;
            }
    
            //er soll fahren und sich evtl drehen
            if ( speed_cruising != 0 )
            {
                writeString_P("1 ");
                //vorwaerts fahren
                if ( dir_cruising == dir_cruising_high )
                {
                    writeString_P("1.1 ");
                    changeDirection(FWD);
                    speed_left = speed_cruising;
                    speed_right = speed_cruising;
    
                    //zusaetzlich drehen nach rechts
                    if ( dir_rotating == dir_rotating_high )
                    {
                        writeString_P("1.1.1 ");
                        speed_left += speed_rotating;
                        speed_right -=  speed_rotating;
    
                        if ( speed_right < 0)
                        {
                            speed_right = 0;
                        }
                    }
    
                    //zusaetzlich drehen nach links
                    else if ( dir_rotating == dir_rotating_low )
                    {
                        writeString_P("1.1.2 ");
                        speed_left -= speed_rotating;
                        speed_right += speed_rotating;
    
                        if ( speed_left < 0)
                        {
                            speed_left = 0;
                        }
                    }
    
                    moveAtSpeed(speed_left,speed_right);
    
                }
    
                //rueckwarts fahren
                else if ( dir_cruising == dir_cruising_low )
                {
                    writeString_P("1.2 ");
                    changeDirection(BWD);
                    speed_left = speed_cruising;
                    speed_right = speed_cruising;
    
                    //zusaetzlich drehen nach rechts
                    if ( dir_rotating == dir_rotating_high )
                    {
                        writeString_P("1.2.1 ");
                        speed_left += speed_rotating;
                        speed_right -= speed_rotating;
    
                        if ( speed_right < 0)
                        {
                            speed_right = 0;
                        }
                    }
    
                    //zusaetzlich drehen nach links
                    else if ( dir_rotating == dir_rotating_low )
                    {
                        writeString_P("1.2.2 ");
                        speed_left -= speed_rotating;
                        speed_right += speed_rotating;
    
                        if ( speed_left < 0)
                        {
                            speed_left = 0;
                        }
                    }
    
                    moveAtSpeed(speed_left,speed_right);
                }
            }
    
            //er soll auf der stelle drehen ohne zu fahren
            else if ( speed_cruising == 0 )
            {
                writeString_P("2 ");
                //auf der stelle nach rechts drehen
                if ( dir_rotating == dir_rotating_high )
                {
                    writeString_P("2.1 ");
                    rotate(speed_rotating,RIGHT,1,false);
                }
    
                //auf der stelle nach links drehen
                else if ( dir_rotating == dir_rotating_low )
                {
                    writeString_P("2.2 ");
                    rotate(speed_rotating,LEFT,1,false);
                }
            }
        mSleep(200);
        writeString_P("\n\r");
        }
        return 0;
    }
    Die Werte rc_input_right_y und rc_input_right_x werden wie in den Kommentaren angegeben durch eine ISR von einem Empfänger aufgenommen. Das klappt auch so wie es soll, aber irgendwie fährt er immer nur vorwärts, bzw landet immer an der Stelle wo es heisst vorwärts fahren und wenn er auf der Stelle drehen soll dreht er sich auch nuch nach rechts.
    Werd mir das morgen nochmal anschaun. Evtl sehe ich dann klarer.

  9. #9
    Erfahrener Benutzer Roboter Genie Avatar von SlyD
    Registriert seit
    27.11.2003
    Ort
    Paderborn
    Alter
    39
    Beiträge
    1.516
    Hui - nun das Programm ist doch recht lang und da gibt es viele Ecken woran es liegen könnte... Da musst Du mal ein paar zusätzliche Ausgaben reinmachen wie die Variablen so gesetzt sind (mit writeInteger) an verschiedenen Stellen und dann genau nachvollziehen wohin er verzweigt ist und mit welchen Werten...

    Oder alternativ mit was kleinerem anfangen und das Programm Schritt für Schritt aufbauen und zwischendrin immer wieder testen ob es bis dahin schonmal klappt...
    Umgekehrt geht es auch - teile aus dem Programm erstmal wieder rausnehmen und dann schritt für schritt testen und wieder mit reinnehmen.

    MfG,
    SlyD

  10. #10
    Benutzer Stammmitglied
    Registriert seit
    01.05.2008
    Beiträge
    52
    Das mit den Ausgaben hab ich gemacht, aber irgendwie rennt er dann immer wieder an die gleiche Stelle.
    Werd da dann wohl mal hingehen und das Stück für Stück duchexerzieren.

    Wenn das dann klapt mach ich mich dran das I2C Slave programm zu bearbeiten. Denn die Basis soll eigentlich etwas selbstständig machen, is jemand sagt er will das Ding per Fernsteuerung steuern.

    Und ich mach das doch Schritt für Schritt.
    Schritt 1: Testprogramme durchprobieren
    Schritt 2: Eigene Idee einfallen lassen
    Schritt 3: Diese Idee mit allen Mitteln durchdrücken bis sie klappt
    Schritt 4: Ergebnis bewundern
    Schritt 5: Wieder alles demontieren und eine neue Idee suchen

    *g*

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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

LiTime Speicher und Akkus