- 3D-Druck Einstieg und Tipps         
Seite 3 von 6 ErsteErste 12345 ... LetzteLetzte
Ergebnis 21 bis 30 von 55

Thema: srf04 mit pulse

  1. #21
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    20.06.2004
    Beiträge
    1.941
    Anzeige

    LiFePo4 Akku selber bauen - Video
    hallo muraad.
    "start_us_messung" oder im ersten "start_messung" gibt immer folgende werte aus. "1,0,5,5,5,1,5,2,5,1 usw". geht auch nicht, wenn ich einen gegenstand davor halte und wieder entferne.
    aber wichtig , es tut sich schon was. ich habe den AVR16 mit 8mhz und deine neuerstellte version auf 8mhz.
    mfg pebisoft.

  2. #22
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    23.05.2004
    Ort
    Untersöchering(Bayern,Alpenvorland)
    Alter
    37
    Beiträge
    215
    Jetzt ist mir noch was aufgefallen. Du musst in der Datei avr/delay.h neuerdings deine CLK Frequenz einstellen also bei dir 8Mhz. Dadurch ist warscheinlich das hier
    _delay_us(15); // Laut Datenblatt Trigger-Puls min 10us auf high
    falsch und die Ergebnisse spinnen.
    Und ich hab noch nen kleinen Fehler im Code oben verbessert.
    Auszug aus avr/delay.h :

    Code:
    /** \defgroup avr_delay Busy-wait delay loops
        \code
        #define F_CPU 16000000UL  // 16 MHz       <----------   Hier musst du es ändern also einfach ne 8 aus der 16                 //    machen   Zeile 45
        //#define F_CPU 14.7456E6
        #include <avr/delay.h>
        \endcode
    Ich hoffe das der Code noch irgendwann funktioniert. Vor allem weil ich keinen srf04 hab ums zu testen.

    Gruß Muraad

  3. #23
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    23.05.2004
    Ort
    Untersöchering(Bayern,Alpenvorland)
    Alter
    37
    Beiträge
    215
    Poste vielleicht mal den ganzen Code wie du meine Funktion verwendest und testest. Vielleicht liegt da auch ein Fehler?!
    Gruß Murad

  4. #24
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    20.06.2004
    Beiträge
    1.941
    hallo, geht noch nicht.
    in meiner delay.h stand nur 1mhz drin. habe mal auf 8mhz geändert, ergebnis
    war unverändert. habe probehalber die bascom-datei geladen für den srf04,
    da ging die messung, also srf04 ist in ordnung.
    auch wenn ich den teiler "10000" rausnehme kommt nur "168,147,165..usw" bei
    vorhalten von gegenständen. der fehler muss irgendwo im timer liegen, aber wo.
    kann man es nicht über einen normalen timer machen und mit einem zählwerk.
    mfg pebisoft

  5. #25
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    20.06.2004
    Beiträge
    1.941
    hier ist der code:
    Code:
    #include <inttypes.h> 
    #include <avr/io.h> 
    #include <avr/delay.h> 
    #include <avr/interrupt.h> 
    #include <avr/signal.h>
    #include <string.h> 
    #include <delay.c>   // das unterprogramm warte
    #include <stdint.h>
    
    #define READ  1 
    #define WRITE 2 
    
    #define USART_BAUD_RATE 	19200 
    #define USART_BAUD_SELECT 	(F_CPU/(USART_BAUD_RATE*16l)-1) 
    
    #define US_PORT  PORTD 
    #define US_PORT_RICHTUNG   DDRD 
    #define US_PIN  PD7         // Der Pin kommt zum Trigger-Puls Eingang  
    
    
    void usart_init(int Enable, int Interupts) 
    { 
         if (Enable & READ)         UCSRB = (1<<RXEN); 
         if (Enable & WRITE)       UCSRB |= (1<<TXEN); 
    
        if (Interupts & READ)      UCSRB |= (1<<RXCIE); 
        if (Interupts & WRITE)     UCSRB |= (1<<TXCIE); 
        UBRRL = (unsigned char) USART_BAUD_SELECT; 
    } 
    
    void usart_writeChar(unsigned char c) 
    { 
        while (!(UCSRA & (1<<UDRE))) {} 
        UDR = c; 
        while(!(UCSRA & (1<<TXC))) {} 
    } 
    
    void usart_writeString(unsigned char *string) { 
        while (!(UCSRA & (1<<UDRE))) {} 
         while ( *string) 
        usart_writeChar(*string++); 
    } 
    
    uint8_t start_messung(void) 
    { 
       uint8_t wert ; //wert_in_cm; 
       US_PORT|=(1<<US_PIN);     // Trigger-Puls auf high  
    
       // PD6 ist Input Capture Pin beim ATMega8, hier kommt der Echo-Pulse Ausgang hin 
       TIMSK|= (1<<TICIE1);           // Input Capture Interrupt enable 
       TCCR1B|= (1<<CS11); // Prescaler 8, damit dauert ein Tackt  1 micro sekunden 
       
       _delay_us(15);          // Laut Datenblatt Trigger-Puls min 10us auf high 
       US_PORT&=~(1<<US_PIN);   // Trigger-Puls Eingang wieder auf low 
       
       while ( !(TIFR & (1<<ICF1 )) ) ;  // Warten bis Echo-Puls Ausgang auf low --> Messung beendet 
       wert=172*ICR1/10000;   // wert ist nun in cm  
       TIFR|=(1<<ICF1);  // ICF1 Bit wieder löschen durch schreiben einer logischen 1 
       TCCR1B&= ~(1<<CS12) & ~(1<<CS11) & ~(CS10);     // Timer wieder aus 
    
       return wert; 
    } 
    
    int main (void) 
    {   
        US_PORT_RICHTUNG|=(1<<US_PIN);         // US_PIN auf Ausgang            
        char s[10];
        uint8_t wert_1; 
        usart_init( (READ + WRITE) , READ); 
    
       for (;;) {
    	
        wert_1=start_messung(); 
    
        itoa( wert_1, s, 10);
        usart_writeString(s);
        usart_writeString("\n\r");
        warte(20000);
    
     	}
    }
    vielen dank für deine mühe.
    mfg pebisoft

  6. #26
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    28.04.2004
    Ort
    Nähe Köln
    Alter
    57
    Beiträge
    247
    Hallo Ihr Beiden

    Code:
     while ( !(TIFR & (1<<ICF1 )) ) ;  // Warten bis Echo-Puls Ausgang auf low --> Messung beendet
    Diese Zeile macht die Verwendung des Timers sinnlos.

    Viel wichtiger ist aber, das ihr nie den Timer Wert löscht, oder vorher auslest.
    Bein Input Capture wird ja nur der aktuelle Wert weg geschrieben nach ICR1, aber nicht gelöscht.

    Ihr müsst also entweder beim Start der Messung TCNT1 löschen, oder auslesen, speichern in einer Variablen und spater von ICR1 abziehen.

    Geschickt wäre es das Ende der Messung mit dem Timer/Counter1 Capture INT auszuwerten.

    Also starten der Messung, Timer1 Wert speichern, auf INT warten, ICR1 - alten Timer Wert und dann berechnen.

    MFG
    Dieter

  7. #27
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    23.05.2004
    Ort
    Untersöchering(Bayern,Alpenvorland)
    Alter
    37
    Beiträge
    215
    Also ich hab jetzt den Code noch bisschen verbessert in der Zeile:
    TCCR1B&= ~(1<<CS12) & ~(1<<CS11) & ~(CS10); // Timer wieder aus
    muss es am ende natürlich auch so sein & ~(1<<CS10) vielleicht hat der Compiler hier garkeinen Fehler gemeldet. Die Folgen könnten sich dann schon sehr komisch auf das Ergebniss auswirken. Im Code im anderen Thread hab ichs auch geändert.
    Und ich fand deine ganzen UART Funktionen bisschen komisch(hab da einiges nicht verstanden), hab mal meine (die aus dem Datenblatt vom ATmega) eingefügt. Und auch wie du das Ergebniss verschickst hab ich bisschen geändert. :
    Code:
    #include <avr/io.h> 
    #include <avr/delay.h> 
    #include <avr/interrupt.h> 
    #include <avr/signal.h> 
    #include <stdio.h>
    #include <delay.c>   // das unterprogramm warte 
    #include <stdint.h> 
    
     
    
    #define USART_BAUD_RATE    19200 
    #define USART_BAUD_SELECT    (F_CPU/(USART_BAUD_RATE*16l)-1) 
    
    #define US_PORT  PORTD 
    #define US_PORT_RICHTUNG   DDRD 
    #define US_PIN  PD7         // Der Pin kommt zum Trigger-Puls Eingang  
    
    
    void usart_init(void) {
        UCSRB = (1<<RXCIE) | (1<<TXCIE) | (1<<RXEN) | (1<<TXEN);
        UBRRL = (unsigned char) USART_BAUD_SELECT;
        UCSRC |= (1<<URSEL)|(3<<UCSZ0);	            //Asynchron 8N1
    
    }
    
    void uart_putc(unsigned char c)      // Ein zeichen 
    {
        while(!(USR & (1 << UDRE)))
        ;   /* warte, bis UDR bereit */
    
        UDR = c;    /* sende Zeichen */
    }
    
    void uart_puts(unsigned char *s)             // mehrere Zeichen
    {
        while (*s)
        {   /* so lange *s != NULL */
            uart_putc(*s);
            s++;
        }
    }
    
    uint16_t start_messung(void) 
    { 
       uint16_t wert ; //wert_in_cm;       // Kann auch 300 sein wegen 300cm also reicht unit8 nicht
       US_PORT|=(1<<US_PIN);     // Trigger-Puls auf high  
    // PD6 ist Input Capture Pin beim ATMega8, hier kommt der Echo-Pulse Ausgang hin 
       _delay_us(15);          // Laut Datenblatt Trigger-Puls min 10us auf high 
       US_PORT&=~(1<<US_PIN);   // Trigger-Puls Eingang wieder auf low 
       _delay_us(185);     // Wartet nochmal
       TCCR1B&=~(1<<ICES1);   // Fallende Flanke für Input Capture
       TCCR1B|= (1<<CS11);; // Prescaler 8, damit dauert ein Tackt  1 micro Sekunde, Timer startet
       while ( !(TIFR & (1<<ICF1 )) ) ;  // Warten bis Echo-Puls Ausgang auf low --> Messung beendet 
       if(ICF1>19000) //kein Objekt vor dem Sensor, eigentlich schon wenn größer 18ms laut Datenblatt
       {
          wert=0;           
          TCCR1B= ~(1<<CS12) & ~(1<<CS11) & ~(1<<CS10);     // Timer wieder aus     geändert!!
          TIFR|=(1<<ICF1);  // ICF1 Bit wieder löschen durch schreiben einer logischen 1
          return wert;        // Raus aus der Funktion
       }
       else
       {
       wert=172*ICR1/10000;   // wert ist nun in cm  
       TIFR|=(1<<ICF1);  // ICF1 Bit wieder löschen durch schreiben einer logischen 1 
       TCCR1B= ~(1<<CS12) & ~(1<<CS11) & ~(1<<CS10);     // Timer wieder aus     geändert!!
    
       return wert; 
       }
    } 
    
    int main (void) 
    {    
        US_PORT_RICHTUNG|=(1<<US_PIN);         // US_PIN auf Ausgang            
        char s[3]; 
        uint16_t wert_1; 
        usart_init();
    
       for (;;) { 
        
        wert_1=start_messung(); 
        sprintf(s,"%u",&wert_1); 
        usart_puts(s); 
        usart_puts("\n\r"); 
        warte(20000); 
    
        } 
    }
    Und das mit dem Teiler von 10000 stimmt schon, die Formel ist aus dem Datenblatt vom srf04. Hab auch mal mit ein paar fiktiven Werten rumgerechnet und die Formlel passt. Probiers einfach mit dem Code jetzt nochmal aus. Ich hab auf jeden Fall wieder nen gravierenden Fehler (vor allem wenn der Compiler nichts gesagt hat) ausgebessert.
    Ach und wegen der Mühe, macht mir garnichts. Wenn der Code mal einwandfrei funktioniert habe ich und andere auch was davon.
    Gruß Muraad

    EDIT: Ich hab nochmal was geändert und zwar habe ich in die Funktion noch eine Warteschleife von 185us eingebaut bevor der Timer startet. Da im Datenblatt vom srf04 steht das erst ein 200us langer 40kHz Burst kommt bevor die Zeit gemessen werden kann/soll. Vorher wartet er ja schon 15us

  8. #28
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    23.05.2004
    Ort
    Untersöchering(Bayern,Alpenvorland)
    Alter
    37
    Beiträge
    215
    Warst schneller als ich Dino Dieter
    Reicht es nicht das ich den Timer am ende der Funktion mit
    TCCR1B= ~(1<<CS12) & ~(1<<CS11) & ~(1<<CS10);
    wieder auschalte. Damit müsste doch das Register TCNT1 automatisch gelöscht werden. Ich starte ja auch am Anfang der Funktion den Timer jedesmal neu.
    Ach und ein Beispielcode mit Input Capture Interrupt gibts einen Thread unter dem hier,
    " 1 interrupt vom AVR16 für 2 aufgaben ? "
    Gruß Muraad

  9. #29
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    20.06.2004
    Beiträge
    1.941
    hallo, es kommt jetzt immer "0" heraus.
    ich mache die ausgabe jetzt über ein lcd-display.
    ich habe vorher das lcd getestet. ich habe in der
    "start_messung" den "wert=67" vor return gesetzt.
    auf dem lcd erschien die zahl "67", auch wenn ich kein gegenstand
    in der nähe hielt, also wird die vorhergehene abfrageschleife auf "0"
    mit der ausgabe "wert=0" garnicht durchlaufen, oder der wert ist so klein,
    das der teiler 10000 diese verschlingt, weil ja bis zum letzen return gelaufen wird.
    mit dem bascom-programm geht die ausgabe der srf04-daten auf dem lcd.
    mf gpebisoft

  10. #30
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    23.05.2004
    Ort
    Untersöchering(Bayern,Alpenvorland)
    Alter
    37
    Beiträge
    215
    Ich habs jetzt nochmal mit ner if{}else{} Anweisung geändert. Jetzt dürfte nur einmal return aufgerufen werden. Aber langsam weis ich auch nicht mehr woran es liegen kann
    Aber noch ein Fehler findet sich immer.
    Gruß Muraad

    EDIT: Ich hab den Code oben nochmal geändert.

Seite 3 von 6 ErsteErste 12345 ... LetzteLetzte

Berechtigungen

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

Solar Speicher und Akkus Tests