-
        

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

Thema: RP6 I2C

  1. #1
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    22.06.2009
    Beiträge
    1.265

    RP6 I2C

    Anzeige

    SMARTPHONES & TABLETS-bis zu 77% RABATT-Kostenlose Lieferung-Aktuell | Cool | Unentbehrlich
    Ich habe mir einen kleinen Entfernungssensor gebaut, der soweit auch schon gut funktioniert. Jetzt habe ich den Ausgang des Sensor an die RP6 Base angeschlossen. Wenn ich die Werte über den UART an den PC sende sind diese vollkommen korrekt. Wenn ich jedoch versuche via I2C den vom ADC0 gemessenen Wert am Display von dem M32 Erweiterungsboard anzuzeigen, bekomme ich nur Schrott angezeigt.
    Anbei mein Code der Basis und der Erweiterung. Ich kann zwar keinen Fehler darin entdecken aber vllt findet jemand von euch einen.

    Code:
     
    #include "RP6RobotBaseLib.h"
    #include "RP6I2CmasterTWI.h"
    
    
    void I2C_transmissionError(uint8_t errorState)
    {
    	writeString_P("\nI2C ERROR - TWI STATE: 0x");
    	writeInteger(errorState, HEX);
    	writeChar('\n');
    }
    
    
    int main(void)
    { 
    initRobotBase(); 
    powerON();
    writeString_P("Hallo"); //UART Test
    writeChar('\n');
    I2CTWI_initMaster(200); //I2C Master initialisieren
    I2CTWI_setTransmissionErrorHandler(I2C_transmissionError);
    
    
    while(1)
    {
    	uint16_t adc0 = readADC(ADC_ADC0); //ADC auslesen
    	writeInteger(adc0, DEC);			// Wert via UART senden
    	writeChar('\n');
    	while(I2CTWI_isBusy()) // warten bis I2C frei ist
    	{
    	
    	}
    	if(!I2CTWI_isBusy())
    	{
    	
    	I2CTWI_transmit2Bytes(10 ,adc0, (adc0 >> 8 )); //ADC  Wert in Lowbyte und Highbyte teilen und via I2C senden
    	writeString_P("I2C hat was gesendet");			// Kontrolle dass etwas gesendet wurde
    	writeChar('\n');
    	}
    	
    
    	}
    return 0;
    
    }
    Code:
    
    #include "RP6ControlLib.h" 		
    #include "RP6I2CslaveTWI.h"
    
    
    int main(void)
    {
    	initRP6Control();
    
    	initLCD();  //Display initialisieren
    	 
    	setLEDs(0b1010); 
    
    	I2CTWI_initSlave(10); // Slave mit der Adresse 10 initialisieren
    	writeString_P("I2C Init");	//UART testen
    	writeChar('\n');
    	showScreenLCD("Hallo","ADC:");	// Display testen
    	uint16_t adcwert;
    	
    	uint8_t highbyte = 0;
    	uint8_t lowbyte = 0;
    	while(true) 
    	{			
    			
    				if(I2CTWI_writeRegisters[0] && !I2CTWI_writeBusy)
    				{
    					lowbyte = I2CTWI_writeRegisters[0]; //lowbyte auslesen
    					
    					highbyte= I2CTWI_writeRegisters[1]; //highbyte auslesen
    					
    				}
    				
    				adcwert = ((highbyte << 8 ) | lowbyte);  // wieder zusammensetzen
    				setCursorPosLCD(1,4);
    				writeIntegerLCD(adcwert, DEC); // auf dem display ausgeben
    				setCursorPosLCD(1,4);
    				writeInteger(adcwert , DEC);
    				writeChar('\n');
    	}
    	
    	
    	return 0;
    }

  2. #2
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.791
    Hallo shedepe,

    beim Master ist wohl alles ok.

    Beim Slave:
    Du solltest erst den Wert anzeigen, wenn er komplett übertragen wurde. Da du immer wieder einen 16-Bit Wert sendest, erkennt der Slave evtl. nicht, welche Bytes zusammen gehören.
    Abhilfe:
    Übertrag einfach 3 Bytes. Wenn das 1. Byte einen bestimmten Wert != 0 hat, dann sind die weiteren beiden Bytes der Messwert und werden nur ausgegeben, wenn das 1. Byte stimmt. Ist das 1. Byte 0, wird ja auch schon bei deinem jetzigen Programm nichts gelesen, allerdings leider in jeder Schleife wieder etwas (Müll) ausgegeben.

    Gruß Dirk

  3. #3
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    22.06.2009
    Beiträge
    1.265
    ich hab das ganze jetzt so abgeändert:
    im Master wird jetzt zuerst ein Kontrollbyte gesendet mit:
    Code:
    I2CTWI_transmit3Bytes(10 , 1 ,adc0, (adc0 >> 8 )); //Kontrollbyte senden ADC  Wert in Lowbyte und Highbyte teilen und via I2C senden
    und im slave mit:
    Code:
    	if(I2CTWI_writeRegisters[0] && !I2CTWI_writeBusy)
    				{
    					controllbyte = I2CTWI_writeRegisters[0]; // Kontrollbyte
    					
    					lowbyte = I2CTWI_writeRegisters[1]; //lowbyte auslesen
    					
    					highbyte= I2CTWI_writeRegisters[2]; //highbyte auslesen
    					
    				}
    				if(controllbyte != 0)
    				{
    				adcwert = ((highbyte << 8 ) | lowbyte);  // wieder zusammensetzen
    				setCursorPosLCD(1,4);
    				writeIntegerLCD(adcwert, DEC); // auf dem display ausgeben
    				setCursorPosLCD(1,4);
    				writeInteger(adcwert , DEC);
    				writeChar('\n');
    				controllbyte = 0;
    				}
    Mein Problem: es funktioniert immer noch nicht

  4. #4
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.791
    Mein Problem: es funktioniert immer noch nicht
    Was genau?
    Also heißt es: Bebuggen!
    Ich würde versuchen, feste Bytes zu senden und herauszufinden, wo's hakt.

    Vorher füge beim Master nach jedem Senden noch eine Pause von z.B. 500ms ein. Hilft das?

    Gruß Dirk

  5. #5
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    22.06.2009
    Beiträge
    1.265
    habe heut versucht das ganze mit festen bytes zu machen:
    im Master mit
    I2CTWI_transmitByte(10,5);

    es macht keinerlei unterschied ob ich eine Pause einfüge, im Slave kommt immer noch nichts an. Habe sogar mal den Bus mit dem Oszilloskop überwacht. Es wird definitiv was gesendet. Auch die Beispiel Programme von der CD funktionieren.

    Um noch mal von der theoretischen Seite sicher zu gehen. Wenn ich eine Byte versende wird dies im Slave hier hin geschrieben:
    I2CTWI_writeRegisters[0] oder?

    langsam gehen mir die ideen aus, woran es liegen könnte

  6. #6
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.791
    Ich werde das morgen 'mal bei mir probieren.

    Gruß Dirk

  7. #7
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    22.06.2009
    Beiträge
    1.265
    so habe das ganze jetzt so gelöst, dass ich das Erweiterungsboard als Master verwendet habe und im Slave den ADC Wert in die Readregister schreibe.
    Würde mich dennoch interessieren warum das ganze nicht andersherum funktionert. Also dass ich mit der Basis als Master den Wert an die Erweiterungsende

  8. #8
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.791
    Hallo shedepe,

    sorry, hatte einfach noch keine Zeit.

    Hier jetzt eine funktionierende Variante:

    RP6Base (Master):
    Code:
    /* 
     * ****************************************************************************
     * RP6 ROBOT SYSTEM - ROBOT BASE EXAMPLES
     * ****************************************************************************
     * Example: I2C Master - I2C Send Test
     * Author(s): Dirk
     * ****************************************************************************
     * Description:
     *
     * This Example sends a 16-bit value via I2C as master.
     *
     *
     * ############################################################################
     * The Robot does NOT move in this example! You can simply put it on a table
     * next to your PC and you should connect it to the PC via the USB Interface!
     * ############################################################################
     * ****************************************************************************
     */
    
    /*****************************************************************************/
    // Includes:
    
    #include "RP6RobotBaseLib.h" 	// The RP6 Robot Base Library.
    								// Always needs to be included!
    #include "RP6I2CmasterTWI.h"	// Include the I2C-Bus Master Library
    
    /*****************************************************************************/
    // Defines:
    
    // The Slave Address on the I2C Bus can be specified here:
    #define RP6CONTROL_I2C_SLAVE_ADR 10
    
    #define CMD_SHOW_DATA 99		// Command to display the data
    
    /*****************************************************************************/
    // I2C Event handlers:
    
    /**
     * 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).
     * The most common mistakes are: 
     *   - using the wrong address for the slave
     *   - slave not active or not connected to the I2C-Bus
     *   - too fast requests for a slower slave
     * Be sure to check this if you get I2C errors!
     */
    void I2C_transmissionError(uint8_t errorState)
    {
    	writeString_P("\nI2C ERROR --> TWI STATE IS: 0x");
    	writeInteger(errorState, HEX);
    	writeChar('\n');
    }
    
    /*****************************************************************************/
    // Variables:
    
    uint16_t adc0;
    uint8_t buffer[4];
    
    /*****************************************************************************/
    // Functions:
    
    
    /*****************************************************************************/
    // Main - The program starts here:
    
    int main(void)
    {
    	initRobotBase();
    	
    	I2CTWI_initMaster(100); // Initialize the TWI Module for Master operation
    							// with 100kHz SCL Frequency
    	
    	// Register the event handlers:
    	I2CTWI_setTransmissionErrorHandler(I2C_transmissionError);
    
    	setLEDs(0b111111);
    	mSleep(500);	   
    	setLEDs(0b000000);
    	
    	powerON();
    
    	writeString_P("Hallo"); // UART Test 
    	writeChar('\n'); 
    
    	startStopwatch1();
    	
    	while(true)  
    	{
    		if (getStopwatch1() > 250) {					// Jede 1/4 Sekunde:
    //			adc0 = readADC(ADC_ADC0);					// ADC auslesen
    			adc0 += 10;									// TEST: ZÄHLER!!!
    			writeString_P("Zu sendender Wert: ");
    			writeInteger(adc0, DEC);					// Wert via UART senden 
    			writeChar('\n'); 
    			buffer[0] = 0;
    			buffer[1] = CMD_SHOW_DATA;
    			buffer[2] = adc0;
    			buffer[3] = (adc0 >> 8);
    			if (!I2CTWI_isBusy()) {
    				I2CTWI_transmitBytes(RP6CONTROL_I2C_SLAVE_ADR, buffer, 4);
    				writeString_P("I2C hat gesendet:  ");	// Kontrolle, dass etwas gesendet wurde 
    				writeInteger(adc0, DEC);
    				writeChar('\n'); 
    				writeChar('\n'); 
    			}
    			setStopwatch1(0);
    		}
    	}
    	return 0;
    }
    
    /******************************************************************************
     * Additional info
     * ****************************************************************************
     * Changelog:
     * - v. 1.0 (initial release) 13.01.2010 by Dirk
     *
     * ****************************************************************************
     */
    
    /*****************************************************************************/
    RP6Control (Slave):
    Code:
    /* 
     * ****************************************************************************
     * RP6 ROBOT SYSTEM - RP6 CONTROL M32 EXAMPLES
     * ****************************************************************************
     * Example: I2C Slave - I2C Receive Test
     * Author(s): Dirk
     * ****************************************************************************
     * Description:
     *
     * This Example receives a 16-bit value via I2C as slave.
     *
     *
     * ############################################################################
     * The Robot does NOT move in this example! You can simply put it on a table
     * next to your PC and you should connect it to the PC via the USB Interface!
     * ############################################################################
     * ****************************************************************************
     */
    
    /*****************************************************************************/
    // Includes:
    
    #include "RP6ControlLib.h" 		// The RP6 Control Library. 
    								// Always needs to be included!
    #include "RP6I2CslaveTWI.h"     // Include the I2C-Bus Slave Library
    
    /*****************************************************************************/
    // Defines:
    
    // The Slave Address on the I2C Bus can be specified here:
    #define RP6CONTROL_I2C_SLAVE_ADR 10
    
    #define CMD_SHOW_DATA 99		// Command to display the data
    
    /*****************************************************************************/
    // Variables:
    
    uint16_t adcwert;
    uint8_t controlbyte; 
    uint8_t highbyte = 0; 
    uint8_t lowbyte = 0; 
    
    /*****************************************************************************/
    // Functions:
    
    
    /*****************************************************************************/
    // Main function - The program starts here:
    
    int main(void)
    {  
    	initRP6Control();	// Always call this first! The Processor will not
    						// work correctly otherwise. 
    
    	initLCD();			// Initialize the LC-Display (LCD)
    						// Always call this before using the LCD!
    	clearLCD();			// Clear the whole LCD Screen
    
    	setLEDs(0b111111);
    	mSleep(500);	   
    	setLEDs(0b000000);
    
    	I2CTWI_initSlave(RP6CONTROL_I2C_SLAVE_ADR);		// Slave mit der Adresse 10 initialisieren 
    
    	showScreenLCD("I2C-Empfang", "ADC:");			// LC-Display vorbereiten 
    
    	while(true)  
    	{
    		if (I2CTWI_writeRegisters[0] && !I2CTWI_writeBusy) { 
    			controlbyte = I2CTWI_writeRegisters[0];		// Kontrollbyte lesen
    			I2CTWI_writeRegisters[0] = 0;				//  und zurücksetzen (!!!)
    			lowbyte = I2CTWI_writeRegisters[1];			// lowbyte auslesen 
    			highbyte = I2CTWI_writeRegisters[2];		// highbyte auslesen 
    
    			if (controlbyte == CMD_SHOW_DATA) { 
    				adcwert = ((highbyte << 8) | lowbyte);	// wieder zusammensetzen 
    				setCursorPosLCD(1, 5); 
    				writeIntegerLCD(adcwert, DEC);
    				controlbyte = 0;
    			}
    		}
    	}
    	return 0;
    }
    
    /******************************************************************************
     * Additional info
     * ****************************************************************************
     * Changelog:
     * - v. 1.0 (initial release) 13.01.2010 by Dirk
     *
     * ****************************************************************************
     */
    
    /*****************************************************************************/
    Gruß Dirk

  9. #9
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    14.11.2009
    Alter
    24
    Beiträge
    188
    Ich habe zurzeit ein großes Problem mit dem I²C Bus:

    Ich verwende die M32 als Master und die Base als Slave.
    Nun habe ich auf der M32 den folgenden Befehl im Programm stehen:
    Code:
    I2CTWI_transmitByte(10,1);
    Das eigentliche Problem besteht nun darin, dass ich die 1, die ich übertragen will auf der Base nicht auslesen kann.

    Mein eigentliches Ziel wäre, dass ich dann schreiben könnte if( ... ) und er dabei die übertragen Zahl abfragt.

    Ich hoffe ihr versteht was ich meine und könnt mir helfen


  10. #10
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.791
    Ich hoffe ihr versteht was ich meine und könnt mir helfen
    Ohne deinen Code für Master und Slave?

    Wie soll das gehen?

    Gruß Dirk

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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