-
        

Ergebnis 1 bis 6 von 6

Thema: i2c(twi) srf10 atmega128

  1. #1

    i2c(twi) srf10 atmega128

    Anzeige

    Hallo @ all,

    ich habe ein großes Problem bezüglich der Vorgehensweise beim Auslesen
    meines Ultraschalls srf10. Der US ist per I2C(TWI) an meinen ATMEGA128
    angeschlossen. Ich bräuchte nun einen Pseudocode, wie ich von der
    Reihenfolge her theoretisch den US ansprechen kann und den Abstand zum
    hinderniss auslesen kann. Addressiert sind die US's bereits. Es geht
    also nur ums ansprechen und auslesen aber wie muss ich vorgehen?
    Programmieren würde ich gerne in C/C++

    Es wäre super, wenn mir jemand bei meinem Problem helfen könnte.


    Gruß Andy

  2. #2
    habe es selber probiert...Mit mäßigem Erfolg. Das Problem ist zwar, dass ich die Messung starte, aber ich kein Ergebnis erhalte.

    Im Anhang findet ihr meinen Quellcode.

    Findet jemand einen Fehler oder jemand ne idee was vergessen wurde oder was ich anderst machen sollte?
    Angehängte Dateien Angehängte Dateien

  3. #3
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    01.06.2007
    Ort
    München
    Alter
    54
    Beiträge
    198
    Hallo Andy,

    Du hast vor dem Auslesen vergessen, das Register auf 2 zu setzen. Dir fehlen vor dem Lesen folgende Code-Zeilen:

    • i2c_start(US_address + I2C_WRITE);
      i2c_write(0x02);
      i2c_stop();

    Erst danach darf kommen:

    • busy = i2c_start(US_address + I2C_READ);

      // address I2C device ultrasonic sensor with read access

      if (busy == 0) //vorher == 0

      {
      distance_low = i2c_readAck(); // read one byte
      distance_high = i2c_readNak();
      distance = (distance_low*256)+distance_high;
      //i2c_stop(); // release I2C bus
      }

      else

      {
      i2c_stop(); // release I2C bus
      }

    Ausserdem solltest Du die Stop-Condition nach dem Lesen nicht auskommentieren. Sonst wartet der SRF10, ob noch was kommt auf dem I2C Bus.

    Gruß, uffi.

  4. #4
    Hallo,

    einen Fehler habe ich auch noch gefunden: die Formel zur Berechnung der Entfernung ist laut Datenblatt

    d = (Highbyte *256)+Lowbyte, nicht andersherum. Außerdem muss doch das register zum auslesen gewechselt werden?

    Ich habe aber auch ein Problem, und zwar, dass die Leitungen SDA und SCL super funktionieren, wenn kein Sensor dranhängt, schließe ich den Sensor an, sind die Leitungen dauerhaft low...

    Kann dies an zu groß gewählten Pull-Ups liegen?

    Verwenden tue ich auch einen Atmega128, SRF10 und 4,7k Pull-Ups.

    Vielen Dank schonmal für Antworten


    Hier nochmal mein Code:
    Code:
    void getDistanceVal_USDS1(void)
    {
    	unsigned char busy=255, result_highByte=0, result_lowByte=0;
    	
    	//issue measuring command
    	i2c_start_wait(ADDRESS_USDS1+I2C_WRITE);
    	i2c_write(W_COMMANDREGISTER);
    	i2c_write(MEASURE_CM);
    	i2c_stop();
    	
    	//wait for measure ready
    	while (busy==255){
    		//while measurement is running firmware reads as 255
    		busy = getUSDSstatus(ADDRESS_USDS1);
    	}
    	
    	i2c_start_wait(ADDRESS_USDS1+I2C_WRITE);
    	i2c_write(R_DIST_HIGHBYTE); //read register2
    	i2c_stop();
    	
    	i2c_start_wait(ADDRESS_USDS1+I2C_READ);
    	result_highByte = i2c_read(0); //read one byte
    	i2c_stop();
    	
    	i2c_start_wait(ADDRESS_USDS1+I2C_WRITE);
    	i2c_write(R_DIST_LOWBYTE); //read register3
    	i2c_stop();
    	
    	i2c_start_wait(ADDRESS_USDS1+I2C_READ);
    	result_lowByte = i2c_read(0); //read one byte
    	i2c_stop();
    	
    	actualDistance_USDS1 = (int) (result_highByte*256 + result_lowByte); //in globaler Variable speichern
    }
    You know you’re an engineer if you have a habit of destroying things in order to see how they work.

    --
    StreetSkatingHH - Das Spotarchiv
    http://StreetSkatingHH.de

  5. #5
    So, ich nochmal:

    Ich konnte den Fehler weiter einkreisen. Ich benutze das i2c-Framework von peter fleury. Dort wird in der Funktion "i2c_readAck()" darauf gewartet, dass die Hardware das TWINT-Bit auf 0 setzt und somit anzeigt, dass die Übertragung beendet wurde:

    Code:
    while(!(TWCR & (1<<TWINT)));
    Offenbar passiert das aber nicht, leider Suche ich nun schon seit geraumer Zeit vergeblich nach einer Lösung, hat jemand von Euch eine Idee?

    Vielen Dank,
    Moe
    You know you’re an engineer if you have a habit of destroying things in order to see how they work.

    --
    StreetSkatingHH - Das Spotarchiv
    http://StreetSkatingHH.de

  6. #6
    Hallo, da ich es immer gut finde, am Ende eines Threads auch eine Lösung stehen zu haben: Ich habe den Fehler gefunden:

    Das Problem war in der while-Schleife, in der ich auf das Ende der Messung warte:

    Code:
     //wait for measure ready
       while (busy==255){
          //while measurement is running firmware reads as 255
          busy = getUSDSstatus(ADDRESS_USDS1);
       }

    hier muss auf jeden Fall ein delay rein, anscheinend verschluckt sich sonst der Sensor. richtig sollte es also so lauten:

    Code:
     //wait for measure ready
       while (busy==255){
          _delay_ms(1); //wait 1ms
          //while measurement is running firmware reads as 255
          busy = getUSDSstatus(ADDRESS_USDS1);
       }
    Der Vollständigkeit halber nochmal die getUSDSstatus-Funktion (USDS:ultra sonic distance sensor):

    Code:
    unsigned char getUSDSstatus(unsigned char address)
    {
    	unsigned char busy=0;
    	
    	//PORTA ^= BIT4; //TODO: remove debugging LED
    	i2c_start_wait(address + I2C_WRITE);
    	i2c_write(R_FIRMWAREREGISTER);
    	
    	i2c_rep_start(address + I2C_READ);
    	busy = i2c_readAck(); //read one byte
    	i2c_stop();
    	
    	return busy;
    }
    Gruß, Moe
    You know you’re an engineer if you have a habit of destroying things in order to see how they work.

    --
    StreetSkatingHH - Das Spotarchiv
    http://StreetSkatingHH.de

Berechtigungen

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