- Modernes Energiemessgeraet         
Ergebnis 1 bis 10 von 11

Thema: Tacho-Signal Erfassung

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    02.08.2006
    Ort
    Würzburg, Germany
    Beiträge
    716
    Ich konnte es nicht abwarten und habe es gleich probiert. Leider ohne Erfolg. Es muss noch ein Fehler drin sein. Ich poste deshalb mal etwas mehr von meinem Code, vielleicht ist es ja noch eine Kleinigkeit:

    Code:
    #define AVRGCC 
    #include <avr/io.h> 
    #include <compiler.h>
    #include <util/delay.h>
    /** 
    IOs:
    PD2 (INT0)  Tacho Eingang
    **/
     
    volatile U32 TachoTime = 0;
    volatile U16 TachoTimeCounterHigh = 0;
       U32 SpeedBuffer[SpeedBufferSize];
       U8  SpeedBufferPointer;
       U32 CurrentSpeed = 0;
     
    int main(void)
    { 
     DDRB =  0b11111100; // Das LCD hängt an PB7...PB5
     PORTB = 0b00000000;
     DDRD =  0b00000000;
     PORTD = 0b01000100;
     LCD_Init ();
     
     
     // IRQ 0 für Tacho-Signal-Eingang:
     MCUCR = 0b00000001;
     GIMSK = 0b01000000;
     
     // Timer 1:  Takt für Tacho-Input-Counter:
     TCCR1B |= (1<<CS11);  // Prescaler auf 8:
     TIMSK |= (1<<TOIE1);  // IRQ für Overflow
    
    /** 
     for (SpeedBufferPointer = 1; SpeedBufferPointer < SpeedBufferSize; SpeedBufferPointer++)
      SpeedBuffer[SpeedBufferPointer] = 0;
     SpeedBufferPointer = 1;
    **/
     sei ();
     
     while (1)
     {
      // Geschwindigkeitsberechnung:
      // TachoTime:
      // 1 Sekunde entspricht  FCPU / Prescaler = 8000000 / 8 = 1000000 entspricht 1µs Auflösung
      // schnellste Geschwindigkeit: 100km/h entspricht 2,988ms Mindest-Auflösung
      // 1 km/h entspricht 298,8 ms (ganze Periode): bzw Zeit zwischen Flankenwechsel: 149,4 ms
      // --> Geschwindigkeit = 149400 µs / Flankenzeit
      // --> Geschwindigkeit in Zehntel-km/h = 1494000 µs / Flankenzeit
      
      // langsamste Geschwindigkeit: 0,1 km/h entspricht 14940000 µS
      if ((TachoTime > 0) && (TachoTime < 15000000))
       CurrentSpeed =  1494000 / TachoTime;
      else
       CurrentSpeed = 0;
      /**
      SpeedBuffer[SpeedBufferPointer] =  CurrentSpeed;
       
      if (SpeedBufferPointer < SpeedBufferSize)
       SpeedBufferPointer++;
      else
       SpeedBufferPointer = 1;
      
      CurrentSpeed = 0;
      U8 i1;
      for (i1 = 1; i1 < SpeedBufferSize; i1++)
       CurrentSpeed = CurrentSpeed + SpeedBuffer[i1];
      CurrentSpeed = CurrentSpeed / SpeedBufferSize;
      **/
      LCD_Cursor (1, 1);
      LCD_Zahl (CurrentSpeed);
     }
        return(0); 
    }
     
    // Tacho-Eingang Signalwechsel:
    SIGNAL (INT0_vect)
    {
     TachoTime = TachoTimeCounterHigh;
     TachoTime = TachoTime<<8;
     U8 tmp = TCNT1L;
     TachoTime = TachoTime + TCNT1H;
     TachoTime = TachoTime<<8;
     TachoTime = TachoTime + tmp;
     TCNT1L = 0;
     TCNT1H = 0;
     TachoTimeCounterHigh = 0;
    }
     
    // Tacho-Eingang-Zeitmessung:
    SIGNAL (SIG_TIMER1_OVF)
    {
     if (TachoTimeCounterHigh < 0xFFFF)
      TachoTimeCounterHigh++;
    }
    Das Tacho-Signal springt immer noch wild durcheinander. Selbst mit Glättung.

    Hüüüülfe! Das sollte doch eigentlich ganz easy sein!

    Viele Grüße
    Andreas

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    20.08.2008
    Ort
    Karlsruhe
    Alter
    37
    Beiträge
    1.225
    Hallo Andreas,

    Mal vorne angefangen. Arrays in C werden von 0 bis Größe-1 indiziert, du verwendest 1-Größe (und zerballerst damit 4 Bytes nach deinem Array, in denen andere Variablen liegen). Dann fehlt dir eine Synchronisation zwischen Hauptschleife und ISR. Volatile garantiert dir nicht, dass im Hauptprogramm TachoTime atomar ausgelesen wird!

    Vorschläge:
    1. Arrayzugriffe korrigieren
    2. Die Neuberechnung der TachoTime kannst du ruhig auch in der Hauptschleife machen, wenn du den Code in der ISR halten möchtest, solltest du die Zwischenergebnisse in einer lokalen Variable halten und erst am Ende nach TachoTime schreiben. Grund: Volatile sagt dem Compiler, dass er IMMER aus der im SRAM liegenden Variable lesen bzw. JEDE Änderung direkt dorthin zurückschreiben muss. Es würde also jede deiner Zuweisungen einmal in den SRAM geschrieben, obwohl es wesentlich effektiver wäre, die Zwischenergebnisse in den Registern zu nutzen.
    3. Locking: Lies in der Hauptschleife TachoTime (oder die Rohdaten falls du die Berechnung aus der ISR rausnimmst) in lokale Puffervariablen und schalte während des Lesevorganges Interrupts aus. Um das zu vereinfachen gibt es in util/atomic.h den ATOMIC_BLOCK, es sollte aber auch reichen, den Kopiervorgang in die lokale Variable mit cli() bzw. sei() zu umgeben.

    mfG
    Markus

    EDIT: Zu 1: Informatiker am Bahnhof - 0, 1, 2 ... wo ist mein dritter Koffer?
    Geändert von markusj (12.08.2011 um 11:27 Uhr) Grund: Informatiker am Bahnhof ...

  3. #3
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Außerdem wird das Zurücksetzen des Timers nicht richtig funktionieren, weil falsche Reihenfolge der Zugriffe. Warum überhaupt einzelne Zugriffe auf Low- und High-Byte? Warum nicht einfach:
    Code:
      TachoTime = TachoTimeCounterHigh;
      TachoTime = TachoTime<<16;
      TachoTime = TachoTime + TCNT1;
      TCNT1 = 0;
      TachoTimeCounterHigh = 0;
    Besser und genauer wäre es natürlich, das Input-Capturing des Timers zu benutzen.
    MfG
    Stefan

Ähnliche Themen

  1. IR-Sensor Erfassung mit Servo
    Von JeyBee im Forum Sensoren / Sensorik
    Antworten: 1
    Letzter Beitrag: 28.10.2008, 17:29
  2. optische Erfassung der Sonne
    Von duc750 im Forum Sensoren / Sensorik
    Antworten: 24
    Letzter Beitrag: 23.01.2007, 22:22
  3. Drehzahl erfassung
    Von ceekay im Forum AVR Hardwarethemen
    Antworten: 1
    Letzter Beitrag: 16.09.2005, 22:16
  4. Tacho Signal beim A3932 von Allegro
    Von demir im Forum Elektronik
    Antworten: 2
    Letzter Beitrag: 01.02.2005, 13:21
  5. Erfassung Pulslänge mir RN-Mega8
    Von Hellmut im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 9
    Letzter Beitrag: 31.10.2004, 20:37

Berechtigungen

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

fchao-Sinus-Wechselrichter AliExpress