-         

Ergebnis 1 bis 8 von 8

Thema: Problem mit RC5 Fernbedienung und M32

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    29.12.2010
    Beiträge
    55

    Problem mit RC5 Fernbedienung und M32

    Anzeige

    Hey,
    Ich habe ein Problem bei der Verwendung von einer RC5 Fernbedienung in Kombination mit dem M32. Egal welche Taste ich auf der Fernbedienung drücke, das Programm wird immer sofort beendetund startet sich dann manchmal neu und manchmal bleibt es beendet.
    Nur mit der Base funktioniert alles.
    Auf der Base ist das Slave Programm und die Lib ist ebenfalls die Lib aus den Beispielen!

    Weiß zufällig jemand ne Lösung für das Problem?

    Mein eigentliches Programm habe ich soweit gekürzt, dass nur die Stellen die für das Problem wichtig sind drin bleiben.

    Code:
    /* 
    **********************************************************************
     */
    
    /*****************************************************************************/
    // Includes:
    
    #include "RP6ControlLib.h"         // The RP6 Control Library. 
                                    // Always needs to be included!
    
    #include "RP6I2CmasterTWI.h"    // I2C Master Library
    
    
    #include "RP6Control_I2CMasterLib.h"// Include our new "RP6 Control I2C Master library":
    
    
    /*****************************************************************************/
    // Definiton:
    
    
    
    
    
    
    
    
    /*****************************************************************************/
    // SRF02:
    
    // The I2C slave address of the SRF ranger - default is 0xE0, but you can
    // change this when you use the function changeSRFAddr() below.
    // Here we changed it to 0xE6 already:
    #define SRF_ADR  0xE0
    
    
    
    /*****************************************************************************/
    // I2C Event handlers:
    
    
    // I2C Data request IDs:
    #define MEASURE_US_LOW     110
    #define MEASURE_US_HIGH 111
    
    
    /*****************************************************************************/
    /*****************************************************************************/
    // TV- Fernsteuerung!!                                                                                xx
    
    #define RC_MEINE
    
    // Key Belegung
    
    #ifdef RC_MEINE        // RC Type:  Phillips RC5 - Bp2            
        #define RC5_KEY_LINKS_ROT             60        
        #define RC5_KEY_RECHTS_ROT            42        
        #define RC5_KEY_VOR                 32      
        #define RC5_KEY_RUECK                33        
        #define RC5_KEY_STOP                 59    
        #define RC5_KEY_CURVE_LEFT             17    
        #define RC5_KEY_CURVE_RIGHT         16    
        #define RC5_KEY_FAHRE_ZUM_LADEN     12    
        #define RC5_KEY_NORMALER_MOD         1        
        #define RC5_KEY_IR_MOD                 2
    #endif
    
    
    
    /**
     * RC5 Data reception handler - this function is called automatically from the 
     * RP6lib if new RC5 Data has been received.
     */
    void receiveRC5Data(RC5data_t rc5data)
    {
        // Output the received data:
        writeString_P("Toggle Bit:");
        writeChar(rc5data.toggle_bit + '0');
        writeString_P(" | Device Address:");
        writeInteger(rc5data.device, DEC);
        writeString_P(" | Key Code:");
        writeInteger(rc5data.key_code, DEC);
        writeChar('\n');
    
            // Check which key is pressed:
        switch(rc5data.key_code)
        {
            case RC5_KEY_LINKS_ROT:              // Turn left:
                writeString_P("LEFT\n");
            break;
            case RC5_KEY_RECHTS_ROT:         // Turn right:
                writeString_P("RIGHT\n");
            break;
            case RC5_KEY_VOR:         // Move forwards
                writeString_P("FORWARDS\n");
            break;
            case RC5_KEY_RUECK:     // Move backwards
                writeString_P("BACKWARDS\n");
            break;
            case RC5_KEY_STOP:             // Stop!
                writeString_P("STOP\n");
            break;
            case RC5_KEY_CURVE_LEFT:     // Drive curve left - forwards
                writeString_P("CURVE LEFT FWD\n");
            break;
            case RC5_KEY_CURVE_RIGHT:     // Drive curve right - forwards
                writeString_P("CURVE RIGHT FWD\n");
            break;
            case RC5_KEY_FAHRE_ZUM_LADEN:     // fahre zur Ladestation
                writeString_P("fahre zur Ladestation\n");
            break;
            case RC5_KEY_NORMALER_MOD:     // Normaler Modus
                writeString_P("Normaler Modus\n");
            break;
            case RC5_KEY_IR_MOD:     // folge den Bewegungsbefehlen der Fernbedienung
                writeString_P("folge den Bewegungsbefehlen der Fernbedienung\n");
        }
    }
    
    
    
    
    /*****************************************************************************/
    // I2C Requests: 
    
    /**
     * The I2C_requestedDataReady Event Handler
     */
    void I2C_requestedDataReady(uint8_t dataRequestID)
    {
        checkRP6Status(dataRequestID);                            
    
        uint8_t messageBuf[8];
        static uint8_t dist_tmp;
        switch(dataRequestID)
        {
            case MEASURE_US_HIGH: // High data register
                // get received data ...
                I2CTWI_getReceivedData(messageBuf, 2);
                dist_tmp = (messageBuf[0]);
                // ... and request low data byte:
                I2CTWI_transmitByte(SRF_ADR, 3);
                I2CTWI_requestDataFromDevice(SRF_ADR, MEASURE_US_LOW, 1);
    
            break;
            case MEASURE_US_LOW: // low data byte:
                I2CTWI_getReceivedData(messageBuf, 2);
            
            break;
        }
    }
    
    /*****************************************************************************/
    // I2C Error handler
    
    /**
     * This function gets called automatically if there was an I2C Error like
     * the slave sent a "not acknowledge" (NACK, error codes e.g. 0x20 or 0x30).
     */
    void I2C_transmissionError(uint8_t errorState)
    {
        writeString_P("\nI2C ERROR - TWI STATE: 0x");
        writeInteger(errorState, HEX);
        writeChar('\n');
    }
    
    
    
    //Hauptprogramm
    
    /*****************************************************************************/
    // Main function - The program starts here:
    
    int main(void)
    {
        initRP6Control();  
        initLCD();
        
        writeString_P("\n\nRP6 CONTROL M32 I2C Master Example Program!\n"); 
    
        // ---------------------------------------
        I2CTWI_initMaster(100);  
        I2CTWI_setRequestedDataReadyHandler(I2C_requestedDataReady);
        I2CTWI_setTransmissionErrorHandler(I2C_transmissionError);
        // Set the RC5 Receive Handler:
        IRCOMM_setRC5DataReadyHandler(receiveRC5Data);
    
    
    
        sound(180,80,25);
        sound(220,80,25);
    
        setLEDs(0b1111);
    
        showScreenLCD("################", "################");
        mSleep(500);
        showScreenLCD("Mein Robot", "Behaviours");
        mSleep(1000);
        setLEDs(0b0000);
    
        // ---------------------------------------
        // Setup ACS power:
        I2CTWI_transmit3Bytes(I2C_RP6_BASE_ADR, 0, CMD_SET_ACS_POWER, ACS_PWR_MED);
        // Enable Watchdog for Interrupt requests:
        I2CTWI_transmit3Bytes(I2C_RP6_BASE_ADR, 0, CMD_SET_WDT, true);
        // Enable timed watchdog requests:
        I2CTWI_transmit3Bytes(I2C_RP6_BASE_ADR, 0, CMD_SET_WDT_RQ, true);
        showScreenLCD("Active Behaviour", "");
    
        while(true) 
        { 
            task_checkINT0();
            task_I2CTWI();
            mSleep(5);
        }
        return 0;
    }
    Lieben Gruß

    Ingo Hunfeld

  2. #2
    Erfahrener Benutzer Roboter Genie Avatar von SlyD
    Registriert seit
    27.11.2003
    Ort
    Paderborn
    Alter
    32
    Beiträge
    1.514
    Könnte dran liegen das Du den Software Watchdog des Slave Programms aktiviert hast. Der muss dann auch ständig zurückgesetzt werden.

    Das hier:
    // Enable Watchdog for Interrupt requests:
    I2CTWI_transmit3Bytes(I2C_RP6_BASE_ADR, 0, CMD_SET_WDT, true);
    // Enable timed watchdog requests:
    I2CTWI_transmit3Bytes(I2C_RP6_BASE_ADR, 0, CMD_SET_WDT_RQ, true)
    muss auf false wenn Du das nicht brauchst.

    MfG,
    SlyD

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    29.12.2010
    Beiträge
    55
    Das setzen auf false bei den beiden Parametern ändert leider nichts.

    Desweiteren ist mir noch aufgefallen, dass im Terminal noch
    Toggle Bit:0 | Device Address:0 | Key Code:16
    angezeigt wird, bevor das Programm beendet wird. Das müsste doch heißen, dass der Empfang ansich funktioniert, jedoch danach einen Fehler provoziert!

    Lieben Gruß

  4. #4
    Erfahrener Benutzer Roboter Genie Avatar von SlyD
    Registriert seit
    27.11.2003
    Ort
    Paderborn
    Alter
    32
    Beiträge
    1.514
    In so nem Fall kommentierst Du einfach erstmal alles aus bis nur noch ein Minimalprogramm übrig bleibt - also den Ultraschall Code da raus, und in der RC5 routine das komplette switch(rc5data.key_code) ...

    Genauso das msleep in der Hauptschleife.
    Dann nochmal die Ausgaben des Programms checken.

    MfG,
    SlyD

    PS:
    Verwende auch bitte die aktuelle RP6Lib und das aktuelle WinAVR aus dem Netz - nicht die von der CD.

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    29.12.2010
    Beiträge
    55
    hi,
    vielen Dank für deine Hilfe ich konnte den Fehler jetzt soweit eingrenzen.
    Er steckt in dieser Passage:

    Code:
    void I2C_requestedDataReady(uint8_t dataRequestID)
    {
        checkRP6Status(dataRequestID);                            
    
        uint8_t messageBuf[8];
        static uint8_t dist_tmp;
        switch(dataRequestID)
        {
            case MEASURE_US_HIGH: // High data register
                // get received data ...
                I2CTWI_getReceivedData(messageBuf, 2);
                dist_tmp = (messageBuf[0]);
                // ... and request low data byte:
                I2CTWI_transmitByte(SRF_ADR, 3);
                I2CTWI_requestDataFromDevice(SRF_ADR, MEASURE_US_LOW, 1);
    
            break;
            case MEASURE_US_LOW: // low data byte:
                I2CTWI_getReceivedData(messageBuf, 2);
            
            break;
        }
    
    
    }
    Mein Problem ist jetzt allerdings, dass ich nicht weiß wie ich diese Passage so programmiere, das es nicht zum Absturz des Systems führt.

    Vielen Dank für eure Hilfe

    Lieben Gruß

  6. #6
    Erfahrener Benutzer Roboter Genie Avatar von SlyD
    Registriert seit
    27.11.2003
    Ort
    Paderborn
    Alter
    32
    Beiträge
    1.514
    Hast Du überhaupt einen Ultraschallsensor an Deinem Roboter angeschlossen?
    Der Code da ist ja aus der Ultraschalldemo.

    Da Du aber nirgendwo eine Messung auslöst vermute ich mal das Du sowieso keine dran hast also lösch das BIS AUF
    checkRP6Status(dataRequestID);

    alles weg.

    MfG,
    SlyD

  7. #7
    Benutzer Stammmitglied
    Registriert seit
    29.12.2010
    Beiträge
    55
    Hi vielen dank für deine Hilfe.
    Doch ich hab einen angeschlossen, ich wollte nur zum Posten das prog nicht komplett reinstellen, sondern nur die Teile die den Fehler verursachen, damit jemadn der das Prog nicht geschrieben hat keine 3 std braucht um sich einzulesen.

    Ich habe den Fehler jetzt gefunden. Verstehe aber nicht warum es zu einem komplett Abstuz führt vllt kannst du mir das erklären.

    Und zwar darf
    uint8_t messageBuf[8];
    nicht innerhalb der Funktion stehen. Wenn ich das Array außerhalb der Funktion erzeuge funktioniert es...
    ICh weiß nur einfach nicht warum.

    Lieben Gruß

    Ingo

  8. #8
    Erfahrener Benutzer Roboter-Spezialist Avatar von RolfD
    Registriert seit
    07.02.2011
    Beiträge
    414
    Ich weis nicht ob es daran liegt aber Variablen in einer Funktion sind ansich dynamisch auf dem Stack im Gegensatz zu statischen vars im Ram. Wenn Dein Programm aus irgendwelchen Gründen zum Stack overflow neigt, knallt es natürlich um so schneller, je mehr Du auf den Stack drauf packst. Entsprechend hat die Var auch nur eine Gültigkeit innerhalb der Funktion da nach der Funktion der Stack abgeräumt ist. Demnach müsste es laufen wenn du ein "static" davor setzt, dann bastelt sich der Compiler die Var in einen extra Speicherbereich statt auf den Stack.
    LG Rolf
    Sind Sie auch ambivalent?

Berechtigungen

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