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

Thema: PWM-Signal messen

  1. #1

    PWM-Signal messen

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Nabend,
    ich möchte in meinem Auto mittels des ATMEGA32 den Benzinverbauch messen. Dazu ist es nötig ein PWM-Signal auszuwerten. Die Länge des Signals wird sich im ms-Bereich bewegen (eine ms entspricht 26ul eingespritztem Kraftstoff). Ich habe leider kein Oszilloskop um das genau prüfen zu können.
    Für die Berechnung brauche ich also den Zeitabstand von steigender zu fallender Flanke. Über die Suche bin ich zu folgender Verfahrensweise gelangt: per Input-Capture die steigende Flanke erkennen, zeitgleich Timer auslösen, dann per Input-Capture die fallende Flanke erkennen und den Timer stoppen/reseten. Die Differenz der beiden Timerwerte ergibt die Dauer des Impulses. Funktioniert mein Ansatz oder schlagt ihr Alternativen vor?

    Ich bin noch relativ neu auf dem Gebiet der AVR-Programmierung, kann mir jemand einen Beispielcode zur Verfügung stellen? Mir geht es nur um die grundlegenden Befehle in Bascom.

  2. #2
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    15.06.2008
    Ort
    Rösrath
    Alter
    40
    Beiträge
    332
    Du kannst den Timer automatisch bei steigender bzw. fallender Flanke auslösen lassen. Musst mal im Datenblatt schauen, da steht das genau drin, hab das selber auch noch nicht gemacht.

  3. #3
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Es gibt von Atmel dazu eine Application note (AVR135). Da wird das Verfahren beschrieben. Vermutlich mit Code in C.
    http://www.atmel.com/dyn/products/ap...?family_id=607

  4. #4
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.214
    @kugelfisch
    Dein Ansatz ist im Prinzip schon richtig.
    Man stellt den Interrupt ( ICP, INTx ) auf steigende Flanke.
    Wird der Interrupt ausgelöst wird der Timer ( bzw. das ICR ) ausgelesen und der Wert abgespeichert. Gleichzeitig wird das Interrupt sensing auf "fallende Flanke" umgestellt.
    Tritt dan der Interrupt bei fallender Flanke wiederum auf, liest man den Timer ( ICR ) erneut aus und zieht den vorher abgespeicherten Wert ab.
    Das Interrupt Sensing wird für die nächste Messung dann wieder auf "steigende Flanke" gestellt.
    Wenn man unsigned Variablen benutzt ist auch die Berechnung bei Überlauf der Timers kein Problem.
    Den Timer ( TCNT1 ) per Software auf 0 zu setzen kann u.U. einen Messfehler verursachen.

    Ich nehm für solche Sachen gerne den Timer1 mit einem Quarz von 8MHz und einem Prescaler von 8 her, weil dann die Werte direkt in µs ausgegeben werden.

    Ein weiteres Problem könnte noch sein, das eine Einspritzdüse während eines Zündvorganges mehrmals mit unterschiedlichen Zeiten einspritzen kann.
    Das könnte man eventuell dadurch lösen, das man einen Drehzahlsensor anbringt und die Einspritzzeiten einer Umdrehung aufaddiert.

    Grundsätzlich gilt für so eine Zeitmessung, wie für alle Interrupts, die Interruptroutinen so kurz wie möglich zu halten.
    Eventuell wäre Assembler sinnvoll.

  5. #5
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    15.06.2008
    Ort
    Rösrath
    Alter
    40
    Beiträge
    332
    Zitat Zitat von wkrug
    Ein weiteres Problem könnte noch sein, das eine Einspritzdüse während eines Zündvorganges mehrmals mit unterschiedlichen Zeiten einspritzen kann.
    Das sollte das Ergebnis ja eigentlich nicht verfälschen - solange man die Gesamteinspritzzeit bei einer konstanten Einspritzmenge feststellt, ist es egal wie of die Düse pro Umdrehung einspritzt, es wird ja nur die Gesamtmenge in Relation zur Zeit benötigt.

  6. #6
    Die Application Note habe ich gelsen und verstehe den Pseudocode auch so weit ganz gut. Das bestätigt mich in meiner geplanten Vorgehensweise.

    Zitat Zitat von wkrug
    Ein weiteres Problem könnte noch sein, das eine Einspritzdüse während eines Zündvorganges mehrmals mit unterschiedlichen Zeiten einspritzen kann.
    Ich fahre einen alten Audi 80, der verfügt noch über eine Zentraleinspritzung (ähnlich Vergaser). Ich habe für alle 4 Zylinder nur eine Einspritzdüse. Damit dürfte das von dir beschriebene Problem entfallen, trotzdem vielen Dank für den Hinweis.


    Mein konkretes Problem ist nach wie vor, dass ich die Theorie verstehe, es aber nicht in Bascom umsetzen kann. Im Wiki gibt es leider auch keinen entsprechenden Artikel zum Theme ICP mit Codebeispielen in Bascom. Hat jemand ein paar entsprechende Codeschnipsel?

  7. #7
    Ich habe in einem Lehrbuch einen Beispielcode gefunden und versucht diesen auf mein Beispiel umzuschreiben. Ziel ist es die Dauer des High-Pulses an PortB.0 zu messen. Leider funktioniert das Programm in der jetzigen Form nicht. Wo liegt mein Fehler?

    Code:
    $regfile = "m32def.dat"
    $framesize = 32
    $swstack = 32
    $hwstack = 32
    $crystal = 8000000
    
    
    'LCD:
     Config Lcd = 16 * 2
     Config Lcdpin = Pin , Db4 = Portc.5 , Db5 = Portc.1 , Db6 = Portc.4 , Db7 = Portc.0 , E = Portc.2 , Rs = Portc.3
     Config Lcdbus = 4
    
    'Variable:
     Dim Pulswert As Word
    
    'Funktionen:
     Declare Function Hochpuls() As Word
    
    'Port B.0:
     Config Pinb.0 = Input
     Set Portb.0.0
     Pulsmesserpin Alias Pinb.0
    
    'Timer1:
     Config Timer1 = Timer , Prescale = 1024
     Enable Timer1
     On Timer1 Interrupttimer1 Nosave
     Enable Interrupts
    
    Cls
     Do
      Cursor Off Noblink
      Locate 1 , 1
      Pulswert = Hochpuls()
      Lcd "Puls:" ; Pulswert
      Loop
     End
    
    
     Function Hochpuls() As Word
      While Pulsmesserpin <> 1 : Wend              'warte auf Lo-Hi an PB0
       Tcnt0 = 0                                                'reset timer1
        Start Timer1
        While Pulsmesserpin = 1 : Wend
        Stop Timer1                                 
        Hochpuls = Tcnt0
      End Function Hochpuls()
    
    'Overflow Timer1 stoppt Timer1 und setzt TCNT1 zu Null (timeout)
      Interrupttimer1:
        !push r24
        Stop Timer1
        Tcnt0 = 0
        !pop r24
        Return

Berechtigungen

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

LiFePO4 Speicher Test