- LiFePO4 Speicher Test         
Seite 2 von 3 ErsteErste 123 LetzteLetzte
Ergebnis 11 bis 20 von 25

Thema: I2C Verständnisprobleme

  1. #11
    Erfahrener Benutzer Roboter-Spezialist Avatar von RolfD
    Registriert seit
    07.02.2011
    Beiträge
    414
    Anzeige

    Powerstation Test
    Zu Teil 1 , richtig, so müsste das sein.
    Zu Teil 2 , zum Teil richtig wobei I2CTWI_readRegisters das auch und quasi in einem Rutsch erledigen würde. Aber genau so funktionierts im Prinzip.
    Da es aber einen Schreib- und einen Lesezeiger gibt, kannst du glaube ich nicht den Lesezeiger mit einer Schreiboperation setzen. Da bin ich mir aber grade sehr unsicher. Kann sein das es doch geht. Für sowas ist jedenfalls I2CTWI_readRegisters vorgesehen.

    Ich muss dazu sagen, ich bin grade an einer anderen Baustelle und kann das hier grade nicht praktisch nachvollziehen - ich mach also Trockenübungen.
    RP6data ist ein StringBuffer im Master... und hat mit dem Slave nur so viel zu tun als das I2CTWI_readBytes diesen mit Daten anfüllt. In deinem Fall 1 Byte.

    Irgendwo später im Programm bzw. in der I2CmasterLib werden die Bytes sicher aus dem Buffer ausgelesen und in ein Byte oder 16 bit Int gewandelt.
    #define meltbytes(hvar,lvar) ((hvar << 8) | lvar) // get 16bit from two 8 bit (hi/lo)
    Das müsste etwa so aussehen da adc Werte 10 Bit haben, was für ein Byte zu klein wäre. Daher aufgeteilt in High und Low Byte. Wie das Kind heisst ist dabei egal so lange die Funktionen, die später den Buffer convertieren darauf zugreifen können.
    Den Buffer bzw. Vars kannst du dir mit
    writeString(stringbuffer);writeChar('\n');
    oder
    writeInteger(variable, DEC);writeChar('\n');
    auf die Konsole ausgeben lassen... beim Buffer vorausgesetzt, da sind druckbare Zeichen drin... eine Ausgabe per Hex und Schleife ist ggf. praktischer
    Die RP6Control_I2CMasterLib dürfte die Werte so bereit stellen wie sie auch in der Base bereit liegen. Spätestens da ist als garantiert auch besagte Wandlung zu finden.
    LG Rolf
    Sind Sie auch ambivalent?

  2. #12
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.803
    @RP6fahrer,

    ... welche Funktion hat RP6data?
    Das ist eine uint8_t Variable, die den Wert des/der gelesenen Register enthält. Wenn du mehrere Register liest, müßte das ein Array sein.
    Wenn alle Register da rein passen sollen: uint8_t RP6data[32];
    Wenn du nur 1 Register liest, kann das auch eine einfache 8-bit Variable sein oder du nimmst Var = I2CTWI_readByte(I2C_RP6_BASE_ADR);

    Anzeigen: Einfach die Variable z.B. mit writeInteger() ausgeben.

    Mit der RP6Control_I2CMasterLib kannst du die ADCs tatsächlich mit den Variablen adc0 / adc1 anzeigen. Neu werden die Werte aber nur angezeigt, wenn du sie mit der Funktion readAllRegisters() eingelesen hast. Diese Funktion müßtest du dann regelmäßig aufrufen.
    Wenn du nicht immer alle Register der Base lesen willst, müßtest du z.B für die ADCs eine eigene Lesefunktion schreiben.
    Die sieht dann so aus, wie z.B. die für die Lichtsensoren (readLightSensors), aber ohne die Ausgabe.
    Gruß
    Dirk

  3. #13
    Benutzer Stammmitglied
    Registriert seit
    10.09.2010
    Beiträge
    74
    @Rolf
    Ja, danke. Kannst dich erstmal um deine Baustelle kümmern. Ich habe da nicht so ein stress.

    Also, zum Problem ADC. In meinem Programm steht das hier so:


    Code:
    void task_test(void)
    {
        I2CTWI_transmitByte(10, 23); Also hier erfolgt die Anfrage an das Register 23 von Slave(adresse 10)
        uint8_t result1 = I2CTWI_readByte(10);   und hier wird es eingelesen
        writeString_P("\n ADC0 High :   ");
        writeIntegerLength(result1, DEC, 3);  Und hier wird er über die serielle Schnittstelle ausgegeben.
        mSleep(500);
      
        I2CTWI_transmitByte(10, 25);
        uint8_t ergebnis = I2CTWI_readByte(10);
        writeString_P("\n ADC1 High :   ");
        writeIntegerLength(ergebnis, DEC, 3);
        mSleep(500);
        
            I2CTWI_transmitByte(10, 22);
        uint8_t ergebniss = I2CTWI_readByte(10);
        writeString_P("\n Batterie High :   ");
        writeIntegerLength(ergebniss, DEC, 3);
        mSleep(500);
        
        writeString_P(" | BAT:");writeIntegerLength(adcBat,DEC,4);
        writeString_P(" | AD0:");writeIntegerLength(adc0,DEC,4);
        writeString_P(" | AD1:");writeIntegerLength(adc1,DEC,4);
        writeChar('\n');
    
    }
    /**
     * Timed Watchdog display only - the other heartbeat function
     * does not work in this example as we use blocked moving functions here.
     */
    void watchDogRequest(void)
    {
        static uint8_t heartbeat2 = false;
        if(heartbeat2)
        {
            clearPosLCD(0, 14, 1);
            heartbeat2 = false;
        }
        else
        {
            setCursorPosLCD(0, 14);
            writeStringLCD_P("#"); 
            heartbeat2 = true;
        }
    }
    
    /*****************************************************************************/
    // I2C Requests: 
    
    /**
     * The I2C_requestedDataReady Event Handler
     */
    void I2C_requestedDataReady(uint8_t dataRequestID)
    {
        checkRP6Status(dataRequestID);
    }
    
    /*****************************************************************************/
    // 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');
    }
    
    void I2C_requestedDataReady(uint8_t dataRequestID)
    {
        // We need to check if this is an INT0 Request from the Robot Base unit.
        // The Function call inside the if condition returns true if it was an
        // interrupt request, so we have to negate it here and if it was NOT
        // an interrupt request from the Robot base we can check any other sensors
        // from which you may have requested data...
        if(!checkRP6Status(dataRequestID)) 
        {
            // Here you can Check other sensors/microcontrollers with their own
            // request IDs - if there are any... 
        }
    }
    
    /*****************************************************************************/
    // Main function - The program starts here:
    
    int main(void)
    {
        initRP6Control();  
        initLCD();
        
        writeString_P("\n\nRP6 CONTROL M32 I2C Master Example Program!\n"); 
        writeString_P("\nMoving...\n"); 
    
        // ---------------------------------------
        WDT_setRequestHandler(watchDogRequest); 
        
        // ---------------------------------------
        // Init TWI Interface:
        I2CTWI_initMaster(100);  
        I2CTWI_setRequestedDataReadyHandler(I2C_requestedDataReady);
        I2CTWI_setTransmissionErrorHandler(I2C_transmissionError);
    
        sound(180,80,25);
        sound(220,80,25);
    
        setLEDs(0b1111);
    
        showScreenLCD("################", "################");
        mSleep(500);
        showScreenLCD("I2C-Master", "Movement...");
        mSleep(1000);
        setLEDs(0b0000);
        
        WDT_setRequestHandler(watchDogRequest); 
        
        // ---------------------------------------
        //I2CTWI_transmit3Bytes(I2C_RP6_BASE_ADR, 0, CMD_SET_ACS_POWER, ACS_PWR_MED);
        //writeString_P("ACS Power ist medium\n");
        //mSleep(500);
        I2CTWI_transmit3Bytes(I2C_RP6_BASE_ADR, 0, CMD_SET_WDT, true);
        writeString_P("WDT ist true\n");
        mSleep(500);
        I2CTWI_transmit3Bytes(I2C_RP6_BASE_ADR, 0, CMD_SET_WDT_RQ, true);
        writeString_P("WDT-RQ ist true\n");
        mSleep(500);
            //I2CTWI_transmit3Bytes(10, 0, 6, FWD);
            
            I2CTWI_setRequestedDataReadyHandler(I2C_requestedDataReady);
        
        while(true) 
        {     
        task_I2CTWI();
        task_test();    
        
            }
        return 0;
    }
    Das Problem ist jetzt, dass der Wert diese ADC0 normal (durch Lichtsensor) 780 ist, aber über das M32 sind dass nur 230 ungefähr. mache ich da noch was falsch?
    Und beu ubat zeigt er mir 000 an.
    Und dann würde ich noch gern wissen wollen, was das wdt und wdt_RQ ist.
    LG
    Geändert von RP6fahrer (21.04.2011 um 16:32 Uhr)

  4. #14
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.803
    Wenn du diese 2 Funktionen benutzt, liest du adc0 und adc1 richtig ein.
    Code:
    void getADC0(void)
    {
     I2CTWI_readRegisters(I2C_RP6_BASE_ADR, I2C_REG_ADC_ADC0_L, RP6data, 2);
     adc0 = RP6data[0] + (RP6data[1]<<8);
    }
     
    void getADC1(void)
    {
     I2CTWI_readRegisters(I2C_RP6_BASE_ADR, I2C_REG_ADC_ADC1_L, RP6data, 2);
     adc1 = RP6data[0] + (RP6data[1]<<8);
    }
    RP6data müßtest du als uint8_t RP6data[2] deklarieren.
    Für Ubat sieht die Funktion genauso aus. Der 2. Parameter in der I2C-Lesefunktion wäre dann I2C_REG_ADC_UBAT_L.
    Gruß
    Dirk

  5. #15
    Erfahrener Benutzer Roboter-Spezialist Avatar von RolfD
    Registriert seit
    07.02.2011
    Beiträge
    414
    Ich bin mir sehr sicher, das dies Übertragungsfehler verursacht durch I2C sind. Genau solche Fehler treten z.B. auch mit Remotrol auf, einer Steuersoftware für den RP6. Wenn es dich wirklich interssiert, schau mal in den Thread:
    https://www.roboternetz.de/community...-RP6Lib-Bugfix
    LG Rolf
    Geändert von RolfD (21.04.2011 um 17:09 Uhr)
    Sind Sie auch ambivalent?

  6. #16
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.803
    Ich bin mir sehr sicher, das dies Übertragungsfehler verursacht durch I2C sind.
    Bevor man das sagen kann, muss das Testprog erst mal funktionieren:
    1. Von Ubat wird nur das Highbyte gelesen und das sollte zwar auch nicht 0 sein, aber das müßte man noch checken.
    2. Von ADC0 und ADC1 wird nur das Lowbyte gelesen, da kann man nicht mit den direkt ermittelten 16-Bit-Werten vergleichen.
    Gruß
    Dirk

  7. #17
    Erfahrener Benutzer Roboter-Spezialist Avatar von RolfD
    Registriert seit
    07.02.2011
    Beiträge
    414
    @Dirk
    Welchen Grund sollte es sonst haben das Werte bei der Übertragung ab und zu verloren gehen.. und zwar ausgerechnet die spät gelesenen Register so ca. ab pos 20?
    Ausserdem funktioniert das Testprogramm schon was länger.
    Is aber auch egal. Mein Bot macht was er soll...

    Edit: Sorry, das war wohl ein Missverständnis zwischen mir und Dirk
    Geändert von RolfD (21.04.2011 um 22:11 Uhr)
    Sind Sie auch ambivalent?

  8. #18
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.803
    Ausserdem funktioniert das Testprogramm schon was länger.
    Ich habe vom Testprog von RP6fahrer (17:25) "task_test" gesprochen.
    Gruß
    Dirk

  9. #19
    Benutzer Stammmitglied
    Registriert seit
    10.09.2010
    Beiträge
    74
    @Dirk
    Ja, dein Vorschlag hat funktioniert. Jetzt zeigt er die richtigen Werte an. Ich habe allerdings dazu noch ein paar fragen
    Code:
    I2CTWI_readRegisters(10, I2C_REG_ADC_ADC0_L, RP6data, 2);
        adc0 = RP6data[0] + (RP6data[1]<<8);
    I2CTWI_readRegisters ist der Befehl zum Lesen der Register
    10 die Adresse des Slave
    I2C_REG_ADC_ADC0_L das Register zum Lesen des Adc0 Registers -- Warum nicht I2C_REG_ADC_ADC0_H?
    RP6data ne Variable?
    2 wozu ist die gut?

    RP6data[0] + (RP6data[1]<< und was hat das im einzelnen zu sagen?

    Ich hoffe ich nerve euch nicht damit. Aber ich finde irgendwie nirgendwo eine einfache Erklärung zu den ganzen Aufrufen.

    Naja, denn noch nen schönen Abend und schöne Ostern
    LG RP6fahrer

  10. #20
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.803
    @RP6fahrer:
    I2C_REG_ADC_ADC0_L ist nur eine Konstante, die ist in der RP6Control_I2CMasterLib.h als 23 definiert.
    Du könntest also auch I2CTWI_readRegisters(10, 23, RP6data, 2); schreiben.

    Damit liest du 2 Bytes, das erste ist der Low Wert von ADC0 (aus Register 23), der wird in RP6data[0] gespeichert.
    Das 2. Byte ist der High Wert von ADC0 (aus Register 24), der wird in RP6data[1] gespeichert.

    I2C_REG_ADC_ADC0_H braucht man nicht, weil das 2. Byte automatisch aus Register 24 gelesen wird, wenn man 2 Bytes einliest.

    Der komplette adc0-Wert errechnet sich als: adc0 = Low Wert + (256 * High Wert), also:
    adc0 = RP6data[0] + (RP6data[1] * 256);

    Anstelle von *256 kann man auch achtmal nach links schieben: <<8

    RP6data iat eine Variable.
    Gruß
    Dirk

Seite 2 von 3 ErsteErste 123 LetzteLetzte

Ähnliche Themen

  1. Verständnisprobleme -> Drehmomentrechner
    Von selan im Forum Motoren
    Antworten: 9
    Letzter Beitrag: 13.11.2006, 14:25
  2. Verständnisprobleme über die Funktionsweise eines Interrupts
    Von electrofux im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 3
    Letzter Beitrag: 31.10.2006, 16:14
  3. Syntax - Verständnisprobleme
    Von R2D3212 im Forum C - Programmierung (GCC u.a.)
    Antworten: 8
    Letzter Beitrag: 05.07.2006, 01:41
  4. Serielle Verständnisprobleme
    Von steffenvogel im Forum Software, Algorithmen und KI
    Antworten: 6
    Letzter Beitrag: 09.04.2006, 13:23
  5. Antworten: 17
    Letzter Beitrag: 01.01.2006, 17:33

Berechtigungen

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

Solar Speicher und Akkus Tests