-         

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

Thema: Register des SRF02 über TWI bzw. I2C auslesen

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    21.02.2010
    Beiträge
    11

    Register des SRF02 über TWI bzw. I2C auslesen

    Anzeige

    hallo an alle. ich hab ein problem beim auslesen der resigster vom
    SRF02 Ultraschallsensor. ich verwende den sensor über twi an einem
    atmega128 und 16mhz. für TWBR habe ich 72 eigetragen.

    die funktion bleib an der kommentierten stelle hängen und läuft nicht
    mehr weiter. kann mir da jemand weiterhelfen, wie ich über twi die
    register auslesen kann??? alleine finde ich den fehler leider nicht.

    das übertragen mit einer anderen funktion läuft ohne problme, nur am
    empfangen / lesen gibt es schwierigkeiten.

    hier hatte jemand das gleiche problem würde ich sagen:
    http://www.mikrocontroller.net/topic/99910#1606143


    Code:
    #include <inttypes.h>	// these four library headers are part of WinAVR compiler
    #include <stdio.h>
    #include <stdlib.h>
    #include <avr/io.h>
    
    ...
    
    int main()
    {
    	...
    	unsigned int range_h;
    	unsigned int range_l;
    
    	DDRD = 0xff;
    	PORTD = 0xff;
    
    	setup();
    
    	printf( "Ultraschallsensor SRF02\n");
    
    	while(1)
    	{
    		PORTA ^= ( 1 << PA2 );
    		i2c_transmit(0xE0,0,0x51);				// srf02 ping command, result in cm
    		_delay_ms(120);
    
    		range_h = i2c_read(0xE0,2);				// read srf02 range, high byte
    		range_l = i2c_read(0xE0,3);				// read srf02 range, low byte
          
    		printf( "high: %d\tlow: %d\n", range_h, range_l);
    
    		//printf( "Abstand: %dcm\n", range);
    		
    	}
    }
    
    char i2c_read(char address, char reg)
    {
    	char read_data = 0;
    
    	TWCR = 0xA4;			// send a start bit on I2C bus
    	while(!(TWCR & 0x80));	// wait for confirmation of transmit  
    	TWDR = address;			// load address of I2C device
    	TWCR = 0x84;			// transmit 
    	while(!(TWCR & 0x80));	// wait for confirmation of transmit
    	TWDR = reg;				// send register number to read from
    	TWCR = 0x84;            // transmit
    	while(!(TWCR & 0x80));  // wait for confirmation of transmit
    	TWCR = 0xA4;            // send repeated start bit
    	while(!(TWCR & 0x80));  // wait for confirmation of transmit 
    	TWDR = address+1;       // transmit address of I2C device with readbit set
    	TWCR = 0xC4;            // clear transmit interupt flag
    	while(!(TWCR & 0x80));  // wait for confirmation of transmit
    	TWCR = 0x84;            // transmit, nack (last byte request)
    	
    //----------------------------ab hier geht es dann nicht mehr weiter-------------
    while(!(TWCR & 0x80));  // wait for confirmation of transmit
    	read_data = TWDR;       // and grab the target data
    	TWCR = 0x94;            // send a stop bit on I2C bus
    	return read_data;
    }
    
    void i2c_transmit(char address, char reg, char data)
    {
    	TWCR = 0xA4;			// send a start bit on I2C bus
    	while(!(TWCR & 0x80));	// wait for confirmation of transmit 
    	TWDR = address;			// load address of I2C device
    	TWCR = 0x84;			// transmit
    	while(!(TWCR & 0x80));	// wait for confirmation of transmit
    	TWDR = reg;
    	TWCR = 0x84;			// transmit
    	while(!(TWCR & 0x80));	// wait for confirmation of transmit
    	TWDR = data;
    	TWCR = 0x84;			// transmit
    	while(!(TWCR & 0x80));	// wait for confirmation of transmit
    	TWCR = 0x94;			// stop bit
    }
    
    void setup(void)
    {
    	TWBR = 72;				// 100khz I2C bus speed
    	TWSR = 0;				// no prescaler
    	PORTA &= ~( 1 << PA1 );
    }

  2. #2
    Neuer Benutzer Öfters hier
    Registriert seit
    21.02.2010
    Beiträge
    11
    Hallo noch einmal...

    kann das vielleicht sein das der srf02 nicht senden kann und dadurch die schleife nie beendet wird, da nix empfangen wird??? den wenn ich ihm den befehl zum messen sende, empfängt er diesen und die led leuchtet einmal auf (also er misst einmal).

    hab an die scl und sda 5v über je 3,3k rangehangen, müsste soweit eigendlich richtig sein :-S

  3. #3
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    22.05.2005
    Ort
    12°29´ O, 48°38´ N
    Alter
    48
    Beiträge
    2.731
    Hallo,

    schonmal die Wartezeit zwischen start und auslesen vergrößert ?
    Der SRF02 klemmt sich in der Zeit vom I2C ab, solange er misst.

    Zum Testen ob die TWI-Geschichte in Deinem Prog läuft, kannst Du ja mal die Firmware auslesen, oder ohne MessStart die Register auslesen, da sollte dann immer was kommen.

  4. #4
    Neuer Benutzer Öfters hier
    Registriert seit
    21.02.2010
    Beiträge
    11
    ich hab ebend die wartezeit auf 500ms vergrößert, es passiert leider das gleiche. an der while schleife bleibt er stehen.

    zudem habe ich den teil mit "i2c_transmit(0xE0,0,0x51);" auskommentiert, so dass nur die register abgefragt werden, ohne messung. leider wie oben bleibt in der while schleife hängen.

    da muss irgendwas mit dem auslesen nicht laufen, den wenn ich das register 0 auslesen will bleibt er auch an dieser stellen hängen. beim register 1 der den wert 0x80 liefern soll passiert ebenso das gleiche.

    wo ist nur dieser fehler!!!!!??????!!!!!!!??????
    kann es an der hardware liegen??????

  5. #5
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    22.05.2005
    Ort
    12°29´ O, 48°38´ N
    Alter
    48
    Beiträge
    2.731
    Wenn Dein primäres Ziel das Auswerten des SRF ist, würde ich jetzt den Tipp mit der I2C-Lib von P.Fleury anbringen
    Wenn Du mit I2C basteln willst, kannst Du mal ins Wiki schauen, wie das der Reihe nach geht.

  6. #6
    Neuer Benutzer Öfters hier
    Registriert seit
    21.02.2010
    Beiträge
    11
    über die lib von fleury hab ich das auch schon probiert. unten der code dazu. die zahlen die per printf geschrieben werden, sind dazu da um zu sehen wie weit er kommt. leider wird die zahl 12 nicht mehr ausgegeben, also es wird nur die zahl 11 ausgeben und es läuft nicht mehr weiter.



    Code:
    #include <inttypes.h>	
    #include <stdio.h>
    #include <stdlib.h>
    
    #include <avr/io.h>
    #include "i2cmaster.h"
    
    
    #define SLAVE_ADRESSE 0xE0
    #define F_CPU 16000000UL
    #define BAUD 9600		//Baudrate
    #define MYUBRR F_CPU/16/BAUD-1  //Werte für UBRR Register 
    
    #include <util/delay.h>
    ...
    unsigned int read_cm(unsigned char address);
    
    int main(void)
    {
    
            stdout = &mystdout;
    	USART_Init ( MYUBRR ); //USART initialisieren
    
    	printf( "*** Ultraschallsensor SRF02 ***\n");
    
    int distance;
    i2c_init();
    DDRD = 0xff;
    PORTD = 0xff;
    read_cm(SLAVE_ADRESSE);
    distance = read_cm(SLAVE_ADRESSE);
    
    printf( "    Abstand: %dcm\n", distance);
    
    while(1);
    
    return 0;
    }
    
    unsigned int read_cm(unsigned char address)
    {
    	printf("1");
       unsigned char lowbyte,highbyte;
       unsigned int distance;
    	printf("2");
       i2c_start_wait(address+I2C_WRITE);
       	printf("3");
       while (i2c_write(0));
       	printf("4");
       while (i2c_write(81));
       	printf("5");
       i2c_stop();
       	printf("6");
    
       i2c_start_wait(address+I2C_WRITE);
       	printf("7");
       while (i2c_write(2));
       	printf("8");
       i2c_stop();
       	printf("9");
    
       _delay_ms(65);
       	printf("10");
    
       i2c_start_wait(address+I2C_READ);
       	printf("11");
       highbyte = i2c_readAck();
       	printf("12");
       lowbyte = i2c_readNak();
       	printf("13");
       distance = (highbyte*256)+lowbyte;
       	printf("14");
       i2c_stop();
       	printf("15");
    
       if(distance > 150)
       {
          PORTD = 0x00;
    	  printf("6");
       }
    
       return distance;
    
    }

  7. #7
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    22.05.2005
    Ort
    12°29´ O, 48°38´ N
    Alter
    48
    Beiträge
    2.731
    Ich weiss nicht wie kritisch das hier mit den Pullups ist, ich hab immer 10k.

    Kann es sein, das der nicht auf die 0xE0 hört, probier mal die anderen Adressen aus.

    Oder noch besser, Du gibst nicht nur diese Zahl aus, sondern auch jeweils den Wert von TWSR, dann sieht man was das TWI gemacht hat. Und man sieht gleich, ob der auf E0 hört.

  8. #8
    Neuer Benutzer Öfters hier
    Registriert seit
    21.02.2010
    Beiträge
    11
    so ich habe nach den zahlen mal die TWSR ausgeben lassen. leider kann ich auch mit datenblatt das register nicht verstehen. es steht nur twi status. hier mal ein durchlauf.

    kurz zum E0 muss eigendlich richtig sein den wenn ich den sensor mit strom versorge leuchtet er einmal auf. laut datenblatt ist es dann e0. wenn ich ihn den befehl zum messen sende, leuchtet er erst ganzschwach auf und dann sofort hell. also müsste er eigendlich messen.

    kannst du mir die TWSR Register erklären, hier der durchlauf. (der TWSR wert steht nach dem punkt. die zahl davor ist meine durchlauf kontrolle)

    1.248
    2.248
    3.24
    4.40
    5.40
    6.248
    7.24
    8.40
    9.248
    10.248
    11.72

  9. #9
    Neuer Benutzer Öfters hier
    Registriert seit
    21.02.2010
    Beiträge
    11
    wenn ich e0 auf z.b. f1 ändere macht er folgendes:

    1.248
    2.248
    3.72

    mehr nicht

  10. #10
    Neuer Benutzer Öfters hier
    Registriert seit
    21.02.2010
    Beiträge
    11
    auch mit Pullups mit 10k statt 3,3k das gleiche

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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