- 12V Akku mit 280 Ah bauen         
Ergebnis 1 bis 7 von 7

Thema: SRF05 auslesen liefert nur Ergebnis 0

Baum-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Erfahrener Benutzer Begeisterter Techniker Avatar von Torrentula
    Registriert seit
    10.10.2009
    Ort
    Procyon A
    Beiträge
    355

    SRF05 auslesen liefert nur Ergebnis 0

    Hallo RNler!

    Da ich mal wieder Plane einen SF05 einzusetzen habe ich ein Programm zum auslesen geschrieben, da das Programm aus einem anderen Thread nicht funktionierte (immer mal wieder Ergebnis 0).

    Das Programm soll wie folgt funktionieren:

    1. Messung wird per 12µs-Impuls an SRF05 ausgelöst
    2. Externer Interrupt 0 wird auf steigende Flanke konfiguriert
    3. INT0 wird zum ersten mal ausgelöst und startet den Timer, welcher selber alle 10µs einen Interrupt auslöst; gleichzeitig wird INT0 auf fallende Flanke konfiguriert
    4. INT0 wird nun bei fallender Flanke ausgelöst und stoppt den Timer --> variable measurement_complete wird nun auf 1 gesetzt
    5. Die Dauer des Impulses in µs wird durch 58 geteilt um Entfernung in cm zu erhalten und die Entfernung wird per RS232 an den PC gesendet

    Ich erhalte jedoch immer eine 0 im Terminal. Wenn ich den Timer auf 10Hz umgestellt habe, haben sich einfach alle Werte aufaddiert.

    Hier mein Code:
    Code:
    #ifndef F_CPU
    #define F_CPU 16000000UL
    #endif
    
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <util/delay.h>
    #include <stdlib.h>
    #include "standards.h" // hier sind init_USART() und sendchar() definiert
    
    #define SRFout PD7
    #define SRFin PD2
    
    volatile unsigned int microseconds = 0; // um die Pulslänge zu speichern
    volatile uint8_t INT0_interrupt = 0; // wird benutzt um zwischen Pulbeginn und Pulsende zu entscheiden
    volatile uint8_t measurement_complete = 0; // wird in der hauptschleife gepollt um Abschluss der Messung festzustellen
    
    int main(void)
    {    
        init_USART();
        
        // Timer einstellen
        TCCR0A = (1<<WGM01); // CTC Mode of Timer 0
        // ((16000000 / 1024) / 100) -1 = 155  
        OCR0A = 155; // 155 steps = interrupt ca. alle 10µs
        
        TIMSK0 |= (1<<OCIE0A); // Enable compare interrupt
        //~~~~~~~~~~~~~~~~~
        
        EIMSK |= (1<<INT0); // External interrupt mask register INT0 aktivieren
        
        DDRD |= (1<<SRFout); // Auslösepin auf Ausgang
        DDRD &= ~(1<<SRFin); // INT0 pin muss auch auf input stehen
        
        // Variablen
        uint16_t distance = 0;
            
        unsigned char buffer[10];
        
        while(1)
        {
            // Auslösen der Messung:
            PORTD |= (1<<SRFout);
            _delay_us(12); // 12µs Auslöse-Signal
            PORTD &= ~(1<<SRFout);
            
            // external interrupt 0 bei steigender flanke auslösen:
            EICRA = (ISC01) | (1<<ISC00);
            
            sei(); // alle interrupts aktivieren
            
            while(measurement_complete != 1){
                // auf Abschluss der Messung warten
            }
            measurement_complete = 0;
            
            distance = microseconds / 58;
            
            itoa(distance, buffer, 10);
            sendUSART(buffer);
            sendchar('\n');
            
            distance = 0; // distance wieder zurücksetzen, sonst werden Messungen aufaddiert
            microseconds = 0; // microseconds ebenfalls zurücksetzen
            _delay_ms(1000);    
        }
    }
    
    ISR(INT0_vect){  // external interrupt 0 
        
        if(INT0_interrupt == 0){ // nur wenn noch nicht bei steigender Flanke ausgelöst wurde
            TCCR0B |= (1<<CS02) | (1<<CS00); // Timer starten mit Prescaler 1024
            
            // umschalten interrupt bei fallender Flanke:
            EICRA = (1<<ISC01); // EICRA = External Interrup Control Register A
            
            INT0_interrupt = 1; // da nun bei steigender Flanke bereits getriggert wurde
        }
        else{ // wenn bereits ein INT0 interrupt erfolgte
            TCCR0B &= ~((1<<CS02) | (1<<CS00)); // Timer stoppen
            
            cli(); // alle interrupts sperren
            
            INT0_interrupt = 0; // Variable zurücksetzen
            measurement_complete = 1; // Variable um in der Hauptschleife den Abschluss der Messung festzustellen    
        }    
    }
    
    //gibt uns einen Interrupt ca. alle 10µs
    ISR(TIMER0_COMPA_vect){
        microseconds += 10;
    }
    MfG

    Torrentula
    Geändert von Torrentula (28.12.2011 um 13:47 Uhr)
    MfG Torrentula

Ähnliche Themen

  1. SRF05: Abfrage, Berechnung; Ergebnis immer 0
    Von Jaecko im Forum C - Programmierung (GCC u.a.)
    Antworten: 15
    Letzter Beitrag: 24.09.2011, 17:40
  2. Division mit Nachkommastellen als Ergebnis???
    Von erik_wolfram im Forum C - Programmierung (GCC u.a.)
    Antworten: 3
    Letzter Beitrag: 22.08.2011, 17:13
  3. ADC sendet Ergebnis nicht
    Von zappel76 im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 9
    Letzter Beitrag: 11.09.2010, 13:53
  4. Ergebnis der AD-Wandlung mit Kommata angeben!
    Von patrick-rp6 im Forum C - Programmierung (GCC u.a.)
    Antworten: 2
    Letzter Beitrag: 10.06.2010, 05:41
  5. ADC-Ergebnis in Variable weiter benutzen
    Von Cvecko im Forum C - Programmierung (GCC u.a.)
    Antworten: 6
    Letzter Beitrag: 30.09.2005, 12:26

Berechtigungen

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

12V Akku bauen