-         

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

Thema: SRF05: Abfrage, Berechnung; Ergebnis immer 0

  1. #1
    Erfahrener Benutzer Robotik Einstein Avatar von Jaecko
    Registriert seit
    16.10.2006
    Ort
    Lkr. Rottal/Inn
    Alter
    35
    Beiträge
    1.987

    SRF05: Abfrage, Berechnung; Ergebnis immer 0

    Anzeige

    SMARTPHONES & TABLETS-bis zu 77% RABATT-Kostenlose Lieferung-Aktuell | Cool | Unentbehrlich
    Moin.

    Hab mal wieder ein kleines Problem.
    Ich bin gerade dabei, einen SRF05 auszulesen.

    Vom Prinzip her send ich einfach den 10µs-Trigger und mess dann die Zeit des Antwort-Pulses über den Timer1.
    Wird die steigende Flanke empfangen, startet der Timer mit Prescaler 8, d.h. die Dauer des Pulses entspricht dem Timerwert / 2 (bei 16MHz FCPU)
    Ist der Antwortpuls beendet (fallende Flanke), wird der Timer gestoppt und das Ergebnis berechnet.
    In der main lass ich mir das Ergebnis über I2C an ein LCD ausgeben, zusammen mit einer laufenden Nummer als Kontrolle, ob sich was tut.
    Die Nummer läuft hoch, das Ergebnis bleibt jedoch immer 0.

    Ich geh davon aus, dass gemessen wird, da die LED am SRF05 blinkt und man auch ein leises Knacken vom Ultraschallsender hört.

    Die betreffenden Codes sind angehängt.

    Sieht hier jemand nen Fehler?

    main.c:
    Code:
    int main (void)
    {
      _delay_ms(100);
      I2C_Init(100000ul);
      SRF05_Init();
     
      sei();
      ui16_t measures = 0;
    
      while(1)
      {
        sprintf(I2C_SendText, "%5d = %06ld ", measures++, SRF05_GetResponseTime());
        I2C_PutS(0x20, (ui8_t*)I2C_SendText, 20);
        _delay_ms(100);
      }
    }

    srf05.c:
    Code:
    #include "srf05.h"
    
    typedef enum
    {
      SRF_IDLE = 0,
      SRF_WAITING_FOR_ECHO,
      SRF_ECHO_ACTIVE,
      SRF_RESULT_READY,
      SRF_TIMEOUT
    } e_srfstate;
    
    volatile ui16_t SRF_ValueBuffer[400];
    volatile ui16_t SRF_ValueBufferIndex = 0;
    
    volatile ui8_t  SRF_Overflows = 0;
    volatile ui16_t SRF_TCNT = 0;
    volatile ui32_t SRF_TotalTimeTicks = 0;
    
    volatile e_srfstate  SRF_State = SRF_IDLE;
    
    void SRF05_Init(void)
    {
      // Setup result pin
      SRF_RESULT_PORT  &=~ (1 << SRF_RESULT_PIN);
      SRF_RESULT_DDR   &=~ (1 << SRF_RESULT_PIN);
    
      // setup trigger pin
      SRF_TRIGGER_PORT &=~ (1 << SRF_TRIGGER_PIN);
      SRF_TRIGGER_DDR  |=  (1 << SRF_TRIGGER_PIN);
    
      // Setup result pin interrupt:
      SRF_RESULT_INT_ISC_REG |= (1 << SRF_RESULT_INT_ISC_BIT);
    
    }
    
    ui32_t SRF05_GetResponseTime(void)
    {
      // Response signal 100µs - 25ms
      // FCPU = 16MHz
      // Prescaler 8 => 2 MHz => 0.5 µs tick duration
      
      // Prepare Timer
      TCCR1A = 0; // Standard timer; just count here
      TCCR1B = 0; // Stop timer
      TCNT1 = 0;
      SRF_Overflows = 0;
      SRF_TCNT = 0;
      SRF_TotalTimeTicks = 0;
    
      // clear a possible pending interrupt request
      SRF_RESULT_INT_FLAG_REG |= (1 << SRF_RESULT_INT_FLAG_BIT);
    
      // enable interrupt
      SRF_RESULT_INT_MSK_REG |= (1 << SRF_RESULT_INT_MSK_BIT);
      
      // enable timer overflow interrupt
      TIMSK |= (1 << TOIE1);
      
      SRF_State = SRF_WAITING_FOR_ECHO;
    
      // Send trigger pulse (10µs)
      SRF_TRIGGER_HIGH();
      _delay_us(10);
      SRF_TRIGGER_LOW();
      
      // wait until measurement is complete
      while((SRF_State == SRF_ECHO_ACTIVE) || (SRF_State == SRF_WAITING_FOR_ECHO))
      {
        // nothing to do; just wait...
      }
    
      // Calculate result  
      SRF_TotalTimeTicks  = SRF_Overflows;
      SRF_TotalTimeTicks <<= 16;
      SRF_TotalTimeTicks += SRF_TCNT;
    
      return SRF_TotalTimeTicks;
    }
    
    
    ISR(SRF_RESULT_ISR)
    {
      ui8_t pinlevel = SRF_RESULT_INPUT & (1 << SRF_RESULT_PIN);
      
      if (pinlevel)
      {
        // rising edge: result pulse started
        // start timer for counting
        TCCR1B = (1 << CS11);
        SRF_State = SRF_ECHO_ACTIVE;
      }
      else
      {
        // falling edge: result pulse end
        // stop timer
        SRF_TCNT = TCNT1;
        TCCR1B = 0;
        
        // disable trigger interrupt
        SRF_RESULT_INT_MSK_REG &=~ (1 << SRF_RESULT_INT_MSK_BIT);
    
        // disable timer overflow interrupt
        TIMSK &=~ (1 << TOIE1);
        SRF_State = SRF_RESULT_READY;
      }
    }
    
    ISR (SIG_OVERFLOW1) // Interrupt Timer 1
    {
      SRF_Overflows++;
    }
    srf05.h
    Code:
    #ifndef _SRF05_H_
    #define _SRF05_H_
    
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <util/delay.h>
    #include "glob_defs.h"
    #include "glob_type.h"
    
    #define SRF_TRIGGER_PORT     PORTD
    #define SRF_TRIGGER_DDR      DDRD
    #define SRF_TRIGGER_PIN      4
    
    #define SRF_RESULT_PORT      PORTD
    #define SRF_RESULT_DDR       DDRD
    #define SRF_RESULT_INPUT     PIND
    #define SRF_RESULT_PIN       3
    
    #define SRF_RESULT_INT_ISC_REG  (MCUCR)
    #define SRF_RESULT_INT_ISC_BIT  (ISC11)
    
    #define SRF_RESULT_INT_MSK_REG  (GICR)
    #define SRF_RESULT_INT_MSK_BIT  (INT1)
    
    #define SRF_RESULT_INT_FLAG_REG (GIFR)
    #define SRF_RESULT_INT_FLAG_BIT (INTF1)
    
    #define SRF_RESULT_ISR           SIG_INTERRUPT1
    
    #define SRF_TRIGGER_HIGH()   (SRF_TRIGGER_PORT |=  (1 << SRF_TRIGGER_PIN))
    #define SRF_TRIGGER_LOW()    (SRF_TRIGGER_PORT &=~ (1 << SRF_TRIGGER_PIN))
    
    void SRF05_Init(void);
    ui32_t SRF05_GetResponseTime(void);
    
    #endif
    #ifndef MfG
    #define MfG

  2. #2
    Benutzer Stammmitglied
    Registriert seit
    15.03.2010
    Beiträge
    94
    Hast du die andere Variante ohne I2C ausprobiert, hat bei mir besser funktioneirt.

  3. #3
    Erfahrener Benutzer Robotik Einstein Avatar von Jaecko
    Registriert seit
    16.10.2006
    Ort
    Lkr. Rottal/Inn
    Alter
    35
    Beiträge
    1.987
    Ohne I2C seh ich nix mehr, da das Display per I2C dranhängt.
    Zudem ist später dann auch I2C der einzige Weg für den Datenaustausch.

    Der SRF05 selber hat kein I2C. Den gibts erst ab SRF08 oder 10.
    #ifndef MfG
    #define MfG

  4. #4
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Sieht hier jemand nen Fehler?
    Ja, ich denke schon, aber um sicher zu sein, müsste man mal wissen, um welchen Controller es sich eigentlich handelt.
    MfG
    Stefan

  5. #5
    Erfahrener Benutzer Robotik Einstein Avatar von Jaecko
    Registriert seit
    16.10.2006
    Ort
    Lkr. Rottal/Inn
    Alter
    35
    Beiträge
    1.987
    Upsa verplant: ATMega8, ext. Quarz mit 16MHz; VCC 5V.
    #ifndef MfG
    #define MfG

  6. #6
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Externer Interrupt ist auf fallende Flanke konfiguriert
    => steigende Flanke (Pulsanfang) löst keinen Interrupt aus
    => Timer wird nicht gestartet
    => Interrupt bei fallender Flanke (Pulsende) liest 0 aus
    => Ergebnis immer 0
    MfG
    Stefan

  7. #7
    Erfahrener Benutzer Robotik Einstein Avatar von Jaecko
    Registriert seit
    16.10.2006
    Ort
    Lkr. Rottal/Inn
    Alter
    35
    Beiträge
    1.987
    Thx.
    Mal wieder zu schnell übers Datenblatt geflogen bzw. den Wert vertauscht.
    Die Zeile in der srf05.h muss dann logischerweise so aussehen:

    #define SRF_RESULT_INT_ISC_BIT (ISC10)
    #ifndef MfG
    #define MfG

  8. #8
    Benutzer Stammmitglied
    Registriert seit
    21.04.2010
    Beiträge
    31

    SRF05

    Hi Jaecko!
    Hat es geklappt bei dir? Hast du zufällig Quelltext für mich?))

  9. #9
    Erfahrener Benutzer Robotik Einstein Avatar von Jaecko
    Registriert seit
    16.10.2006
    Ort
    Lkr. Rottal/Inn
    Alter
    35
    Beiträge
    1.987
    Naja, Quelltext liegt im ersten Posting.
    Und mit ändern der Zeile für die Interrupt source klappts auch perfekt.
    #ifndef MfG
    #define MfG

  10. #10
    Benutzer Stammmitglied
    Registriert seit
    21.04.2010
    Beiträge
    31
    So gut kenne ich mich leider nicht aus. Welche Zeile genau?

    Ach so, hab eben gesehen das du ATMega8 hast. Würde dieser Quelltext auf einem ATMEGA32 (RP6) funktionieren?

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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