- 3D-Druck Einstieg und Tipps         
Ergebnis 1 bis 10 von 10

Thema: RP6: Probleme mit I2C und move

  1. #1
    Erfahrener Benutzer Roboter-Spezialist Avatar von -schumi-
    Registriert seit
    30.12.2009
    Ort
    Wasserburg am Inn / Bayern
    Alter
    30
    Beiträge
    449

    RP6: Probleme mit I2C und move

    Anzeige

    Powerstation Test
    Hallo zusammen,

    ich baue gerade eine Bibliothek für den Raspberry Pi, die ähnliche Funktionen wie die für das M32 bietet, um den RP6 steuern zu können.

    Für die Base habe ich das I2C-Slave-Beispielprogramm genommen. Wenn ich jetzt mit dem Raspi über I2C z.B. den Befehl für MoveAtSpeed(30, 30) schicke, dann macht der Robby das auch ganz brav.

    Die Move() und Rotate() Funktionen gehen dagegen nicht. Die Ketten fahren nur ganz kurz an bleiben dann wieder stehen.

    Das hier ist meine move-Funktion:
    Code:
    void rp6rpi_move (char desired_speed, char dir, unsigned int distance)
    {
        char buffer[] = {0, CMD_MOVE, desired_speed, dir, (distance>>8)&0xFF, distance&0xFF};
        rp6rpi_write(buffer);
    }
    Dazu gehört noch:
    Code:
    //Direction:
    #define FWD 0
    #define BWD 1
    #define LEFT 2
    #define RIGHT 3
    Und aufrufen tu ich die hiermit:
    Code:
    int main()
    {
        rp6rpi_openConnection();
        rp6rpi_move(60, FWD, 300);
        rp6rpi_closeConnection();
        return 0;
    };
    Warum funzt das nicht? Fehlt Irgend ein Watchdog zeuch oder sowas? Power On? Interrupt?

    Viele Grüße
    -schumi-

  2. #2
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.803
    Es kann daran liegen, dass die Bewegung noch andauert, während deine main mit deinem Gsamtprogramm schon abbricht.
    Mach mal eine Endlosschleife vor return.
    Du must auch auf den INT0 reagieren: Siehe task_checkINT0();
    Gruß
    Dirk

  3. #3
    Erfahrener Benutzer Roboter-Spezialist Avatar von -schumi-
    Registriert seit
    30.12.2009
    Ort
    Wasserburg am Inn / Bayern
    Alter
    30
    Beiträge
    449
    Also die Endlosschleife alleine reicht noch nicht..

    Das mit dem tast_checkINT0() hab ich so verstanden:

    Jedes mal wenn die Base die INT0-Leitung auf high setzt, möchte die dass der Master die ersten 3 Register (I2C_REG_STATUS1, I2C_REG_STATUS2, I2C_REG_MOTION_STATUS) ausliest?

    Ist das richtig?

    Und ist die INT0-Leitung mit Open-Collector-Ausgängen mit Pullups realisiert? (Damit jeder einen Interrupt auslösen kann. Währe wichtig zu wissen für den Pegelwandler)

    Viele Grüße
    -schumi-

  4. #4
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.803
    Nein, das ist ein normaler Portpin mit einem 10 kOhm PULLDOWN.
    Gruß
    Dirk

  5. #5
    Erfahrener Benutzer Roboter-Spezialist Avatar von -schumi-
    Registriert seit
    30.12.2009
    Ort
    Wasserburg am Inn / Bayern
    Alter
    30
    Beiträge
    449
    Und wenn jetzt die M32 einen Interrupt auslösen möchte? Gibts nen Datencrash und die Base bekommts nicht mit?!

    Oder wird der Pin entweder auf Eingang (mit Pulldown = low) oder Ausgang high und niemals Ausgang low geschalten?

  6. #6
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.803
    Hardware:
    Am XBUS (Pin 8 ) werden im ganzen RP6-System je ein Portpin der Platinen zusammen geführt:
    Base -> PA4
    M32 -> PD2
    M128 -> PE5

    D.h.: Natürlich kann es da zu Konflikten kommen.

    Software:
    Ein System (Base, M32 oder M128 ) kann nur als Ausgang den IRQ auslösen, die anderen Systeme müssen den Portpin auf Eingang schalten. Das System, was einen IRQ auslöst, ist ein I2C-Slave, denn der will ja dem Master sagen, dass Daten anliegen. Dazu zieht er den XBUS Pin 8 auf Highpegel. Im RP6Base-Slave-Programm passiert das in der Funktion signalInterrupt() und darin mit dem Makro extIntON. Umgekehrt wird der Interrupt gelöscht mit clearInterrupt() bzw. dem Makro extIntOFF.
    Die Makros schalten einfach PA4.

    Die M32 (oder deine Platine) als Master bekommt das Signal über einen Eingangspin und muss dann darauf reagieren (z.B. über den I2C-Bus Daten übernehmen...).
    Geändert von Dirk (16.06.2012 um 21:50 Uhr)
    Gruß
    Dirk

  7. #7
    Erfahrener Benutzer Roboter-Spezialist Avatar von -schumi-
    Registriert seit
    30.12.2009
    Ort
    Wasserburg am Inn / Bayern
    Alter
    30
    Beiträge
    449
    Der Hinweis wo ich das finde ist schon mal super - vielen herzlichen Dank dafür

    Code:
    /*****************************************************************************/ 
    // External Interrupt Output  
    // Can be used to notify Master Controllers  
    // about events when operating in Slave Mode. 
     
    /** 
     * Set external interrupt to high level 
     */ 
    void extIntON(void) 
    { 
        DDRA |= E_INT1; 
        PORTA |= E_INT1; 
    } 
     
    /** 
     * Set external interrupt to low level 
     */ 
    void extIntOFF(void) 
    { 
        PORTA &= ~E_INT1; 
        DDRA &= ~E_INT1; 
    }
    D.h.
    ON = Ausgang + high
    OFF = Eingang + Kein Pullup
    -> Kein Konflikt möglich

    Wobei ich mich schon frage, ob es bein ON nicht besser währe erst auf High zu schalten und dann auf Ausgang und bei OFF erst auf Eingang und dann PullupAus. Sonst kann ja für einen sehr kurzen Augenblick doch eine "hartes" low an der Interrupt-Leitung geben.


    So, jetzt muss ich erst mal überlegen wie ich das mit der Pegelwandlung mache... Vielleicht kann man das I2C-Prinzip ja umstülpen.

    Viele Grüße
    -schumi-

  8. #8
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.803
    So, jetzt muss ich erst mal überlegen wie ich das mit der Pegelwandlung mache...
    Haben die GPIOs des Raspberry denn andere Pegel als +5V/Gnd?
    Oder warum braucht es eine Pegelanpassung?
    Gruß
    Dirk

  9. #9
    Erfahrener Benutzer Roboter-Spezialist Avatar von -schumi-
    Registriert seit
    30.12.2009
    Ort
    Wasserburg am Inn / Bayern
    Alter
    30
    Beiträge
    449
    Jep, die haben 3V3, aber ich glaub ich machs so:

    Code:
                       D1
       3V3 ------+-----|>|------+------ 5V
                 |              |
                 |             | |  R1
                 |             | |  6k6 oder größer
                 |              |
                 +--------------+
                                |
                               | |  R2
                               | |  10k
                                |
                               ---  GND
    Hoffentlich erkennen die AVRs die 3.3V mit der Diode dazwischen auch noch als High. Naja, wird schon klappen. Hab noch irgendwo so Germaniumteile (uf=0V3) rumfliegen

  10. #10
    Erfahrener Benutzer Roboter-Spezialist Avatar von -schumi-
    Registriert seit
    30.12.2009
    Ort
    Wasserburg am Inn / Bayern
    Alter
    30
    Beiträge
    449
    Also so irgendwie wills immer noch nicht funktionieren...

    • Ich kann mit dem Raspberry Pi den Status von INT1 abfragen (mit Spannungsteiler von 5V auf 3V3)
    • Wenn ich z.B. einen Bumper drücke und somit INT1 auslöse kann ich INT1 auch folgendermaßen wieder löschen:

    Code:
    int main()
    {
        rp6rpi_init();
        rp6rpi_openConnection();
        rp6rpi_task_RP6RPISystem();        // Read all Registers
        rp6rpi_closeConnection();
        return 0;
    }
    • Wenn ich den Rp6_Move-Befehl mit dem im ersten Beitrag gezeigten Code ausführe wird wie zu erwarten INT1 ausgelöst und der Move-Vorgang abgebrochen.



    Jetzt hab ich den Code so umgeändert, dass immer wenn INT1 ausgelöst wird, die Register gelesen werden:
    Code:
    int main()
    {
        rp6rpi_init();
        rp6rpi_openConnection();
        rp6rpi_move(60, FWD, 300);
        while(1)
        {
            if(rp6rpi_return_INT1())
                rp6rpi_task_RP6RPISystem();        // Read Registers
        }
        rp6rpi_closeConnection();
        return 0;
    }
    Wenn ich an INT1 messe bekomme ich 0V, d.h. der Interrupt wird auch zurückgesetzt.

    Trotzdem bewegt sich der RP6 nur ein ganz kleines Stück vorwärts. WARUM? Was fehlt?


    Viele Grüße
    -schumi-

Ähnliche Themen

  1. Antworten: 4
    Letzter Beitrag: 01.09.2010, 13:34
  2. per TV-remote ein "move" programmablauf auslösen..
    Von carlitoco im Forum Robby RP6
    Antworten: 4
    Letzter Beitrag: 01.04.2008, 21:59
  3. Probleme mit Op-Amp
    Von Xtreme im Forum Elektronik
    Antworten: 6
    Letzter Beitrag: 30.07.2007, 18:03
  4. pwm Probleme
    Von fatjoe im Forum PIC Controller
    Antworten: 0
    Letzter Beitrag: 01.05.2007, 12:35
  5. Probleme mit den AVR´s
    Von mcmonkey im Forum AVR Hardwarethemen
    Antworten: 6
    Letzter Beitrag: 23.02.2005, 20:21

Berechtigungen

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

12V Akku bauen