- Akku Tests und Balkonkraftwerk Speicher         
Seite 4 von 6 ErsteErste ... 23456 LetzteLetzte
Ergebnis 31 bis 40 von 55

Thema: srf04 mit pulse

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

    LiFePo4 Akku selber bauen - Video
    sag mal, in Bascom kann man jeden pin des AVR benutzen. gibt es hier keine andere möglichkeit den timertakt zu zählen. wenn der takt zum srf04 gegeben wird könnte doch ein einfacher zähler in betrieb genommen werden und wenn ein pin wieder kontakt bekommt hört der zähler auf zu zählen, dies müsste innerhalb einer zählschliefe laufen. denke ich hier zu einfach? vielleicht hast du dich irgendwie festgefahren in dem code, das man den fehler irgendwie nicht erkennt.
    mfg pebisoft

  2. #32
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    23.05.2004
    Ort
    Untersöchering(Bayern,Alpenvorland)
    Alter
    38
    Beiträge
    215
    Ja aber dann müsste man ständig den Pin auf dem Port abfragen. Was eigentlich ziemliche Zeitverschwendung ist. Aber prinzipiell wäre es ziemlich einfach.
    1. Timer starten.
    2. Ständig Pin abfragen, sobald sich etwas ändert
    3. Timer stop. Timer wert auslesen.
    Allerdings kann man dan während des Pinabfragens nichts anderes machen!!!
    Gruß Muraad

    PS: An alle die sich damit auskennen, was stimmt nicht an meinem Code??
    Hab ich irgendwo nen Denkfehler drin? Vielleicht schaut ihn sich mal jemand mit mehr Erfahrung an ?!

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

    Folgende Sachen noch.

    In der neuen WINAVR Version gibt es ein kleines Problem mit der Delay.h.

    The macro F_CPU is supposed to be defined to a
    constant defining the CPU clock frequency (in Hertz).

    The maximal possible delay is 768 us / F_CPU in MHz.
    Also auf die maximale Zeit achten, oder selber eine Delay Schleife Proggen.

    Beim eintreten eines ICP wird das Bit gesetzt und der Wert von Timer1 nach
    ICR1 kopiert. Danach muss das Bit durch schreiben einer 0 zurückgesetzt
    werden.

    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(!(UCSRA & (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 !!!!!!!1 geht laut Simulator nicht richtig 95 µs werden angezeigt
       _delay_us(185);              //mit 2 Delay kommt man auf 192µs, anpassen !!!!!!!!!!!!!!!
       TCCR1B &=~(1<<ICES1);   	// Fallende Flanke für Input Capture
       TCNT1 = 0;                   //hinzugefügt, Timer Wert löschen
       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, ICF1 ist dann gesetzt
       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
          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 0    geändert
    	TCCR1B &= ~(1<<CS12) & ~(1<<CS11) & ~(1<<CS10);     // Timer wieder aus
    
       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);
    
        }
    }

    Das starten oder stoppen des Timers hat keinen Einfluß auf den Timerwert
    in TCNT1. Also vorher löschen oder einlesen und nachher in die Berechnung einfliessen lassen.

    MFG
    Dieter

  4. #34
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    23.05.2004
    Ort
    Untersöchering(Bayern,Alpenvorland)
    Alter
    38
    Beiträge
    215
    Ok danke dir dann schreib ich die Funktion mal schnell um
    Hier der neue Code:
    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)))  asm volatile("NOP");   /* 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++; 
        } 
    } 
    // PD6 ist Input Capture Pin beim ATMega8, hier kommt der Echo-Pulse Ausgang hin
    uint16_t start_messung(void) 
    {  
       uint16_t wert ;            //wert_in_cm;   
       US_PORT|=(1<<US_PIN);     // Trigger-Puls auf high  
                         
       _delay_us(15);          // Laut Datenblatt Trigger-Puls min 10us auf high 
       _delay_us(15);
       US_PORT&=~(1<<US_PIN);   // Trigger-Puls Eingang wieder auf low 
       _delay_us(185);     // Wartet nochmal  
       _delay_us(185);
       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 )) ) asm volatile("NOP");
      // Warten bis Input Capture Flag gesetzt   ---> Echo-Eingang ist low
       
       if(ICR1>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    
          TCNT1=0;                  // Wird jetzt auf 0 gesetzt!!!!!!!!!
          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  
          TCCR1B= ~(1<<CS12) & ~(1<<CS11) & ~(1<<CS10);     // Timer wieder aus     
          TCNT1=0;               // AUF 0 setzten !!!!!!
          TIFR|=(1<<ICF1);       // ICF1 Bit wieder löschen durch schreiben einer logischen 1
          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); 
    
        } 
    }
    Jetzt wird am ende der Funktion jedesmal zuers der Timer1 ausgeschaltet und anschließend das Register TCNT1 auf 0 gesetzt.
    Pepisoft wenn du nochmal so nett sein könntest und den Code testest

    Gruß Muraad

  5. #35
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    20.06.2004
    Beiträge
    1.941
    hallo, ich habe dies hier noch gefunden:

    "Wie bereits oben erwähnt müssen vor dem Zugriff auf dieses Register alle Interrupts gesperrt werden. Zudem müssen Low- und Highbyte des Registers in der richtigen Reihenfolge bearbeitet werden:
    Lesen: ICR1L -> ICR1H
    Schreiben: ICR1H -> ICR1L "

    könnt ihr das umsetzen.
    mfg pebisoft

  6. #36
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    20.06.2004
    Beiträge
    1.941
    hallo, bei einem roboter sollten eh die Sensoren nacheinander abgefragt werden und müssen auch noch ausgewertet werden, was er dann machen muss, ich glaube da ist der sogenannte zeitverlust kein hindernis ,das irgend etwas schief läuft. die motoren und die anderen mechanischen geräte haben viel grössere reaktionszeiten, z.b. bremsen der motoren, anziehen eines relais usw.
    würde mich und vielleicht auch andere freuen, wenn die alte routine doch noch klappt.
    mfg pebisoft

  7. #37
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    23.05.2004
    Ort
    Untersöchering(Bayern,Alpenvorland)
    Alter
    38
    Beiträge
    215
    Also Pepisoft da oben ist ein neuer Code. Bitte teste mal genau den.
    Mit dem auslesen von erst high und dann low, das weiß ich schon aber in der Headerdatei von jedem ATmega ist auch ICR1 als ganzes definiert.
    Und Dino Dieter im Datenblatt vom ATmega32 steht doch ausdrücklich das man das Bit durch schreiben einer logischen 1 löscht?!
    Gruß Muraad

  8. #38
    Hab glaub noch nen Tippfehler entdeckt,
    anstelle von ICF1>19000
    ICR1>19000
    ?

  9. #39
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    23.05.2004
    Ort
    Untersöchering(Bayern,Alpenvorland)
    Alter
    38
    Beiträge
    215
    Ja klar danke Fretzschi, habs gleich ausgebessert. Und pepisoft ich glaub ich weis jetzt was war. Der Compiler hat diese Zeile
    while ( !(TIFR & (1<<ICF1 )) ) asm volatile("NOP"); vorher ohne das
    asm volatile("NOP"); wegoptimiert. Hab das grad nochmal bei mikrocontroller.net nachgelesen das der Compiler das wegomptimieren kann/wird. Ich bin mir fast sicher dass das der Fehler war.
    Gruß Muraad

  10. #40
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    20.06.2004
    Beiträge
    1.941
    hallo, muraad, es kommt immer die "0", auf lcd und über uart,probiere immer beide ausgaben.
    bitte setzt das doch mal um, vielleicht kannst du das als sprungbrett nehmen wenn es funktioniert, damit man mal die reaktion der timer sieht, da ist vielleicht erst einmal die fehlersuche einfacher, wenn es da überhaupt fehler gibt.
    dein vorschlag:
    1. Timer starten.
    2. Ständig Pin abfragen, sobald sich etwas ändert
    3. Timer stop. Timer wert auslesen.

    mfg pebisoft

Seite 4 von 6 ErsteErste ... 23456 LetzteLetzte

Berechtigungen

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

Solar Speicher und Akkus Tests