Forum: Compiler & IDEs Drehzahlmessung


von Matthias (Gast)


Lesenswert?

Ich will die Drehzahl von einem Lüfter messen. Ich bewerkstellige dies
mit dem Input Capture Interrupt auf einem AT MEGA 644.Das funktioniert
auch ganz gut.
Allerdings hängt er wenn der Lüfter steht(Signal des Lüfters ist dann
high).
Das UP Drehzahlermittlung wird von main aufgerufen und die Drehzahl
anschließend in main seriell audgegeben.

#include <avr/io.h>
#include <stdint.h>
#include <avr/interrupt.h>

uint32_t abs_Zaehler=0;
uint8_t Ueberlauf=0;
uint8_t Ueberlauf_alt=0;
uint32_t Zaehler[2];
uint8_t i=0;
uint8_t p=0;
uint32_t Drehzahl1;

int Drehzahlermittlung(void)
{
    i=0;
    p=0;
    Drehzahl1=0;
    Zaehler[0]=0;
    Zaehler[1]=0;
    Ueberlauf=0;
    Ueberlauf_alt=0;
    abs_Zaehler = 0;

    OCR1A = 11520;
    TIMSK1 |= (1<<ICIE1)|(1<<OCIE1A);
    TCCR1B |= (1<<WGM12)|(1<<CS11)|(1<<CS10);

    PORTC |= (1<<PC4);
    do
    {
   if(i==2)
        {
          abs_Zaehler= ( (Zaehler[1] - Zaehler[0])+((Ueberlauf-
          Ueberlauf_alt)*11520) );
          Drehzahl1 = ( (60*115200)/(abs_Zaehler) );
          return Drehzahl1;
          p=1;
        }
  else
  {
          Drehzahl1 = 0;
  }
     }while( (p |= 1) || (Ueberlauf >= 2) );

     if( (p==0)&&(Ueberlauf >= 3) )
  {
    Drehzahl1 = 0;
    return Drehzahl1;
  }
     PORTC &= ~(1<<PC4);
}

ISR(TIMER1_CAPT_vect)
{
  Zaehler[i] = ICR1;
  if(i==0)
  {
    Ueberlauf_alt = Ueberlauf;
  }
  i++;
}

ISR(TIMER1_COMPA_vect)
{
  Ueberlauf++;
}

von inoffizieller WM-Rahul (Gast)


Lesenswert?

Kommentare wären schön...

von inoffizieller WM-Rahul (Gast)


Lesenswert?

|| (Ueberlauf >= 2)

sollte das nicht eher || (Ueberlauf <= 2) heissen?

von Matthias (Gast)


Lesenswert?

Habe ich der Übersichtlichkeit weggeleassen.

ISR(TIMER1_COMPA_vect)
//tritt auf wenn der Counter 11520 (OCR1A) erreicht

ISR(TIMER1_CAPT_vect)
// kopiert Zählerstand bei Capture Event in Variable.
// bei erstem Auftreten wird der Stand des Überlaufzählersin
//Überlauf_alt gespeichert

int Drehzahlermittlung(void)
//OCR1A = Counter Obergrenze
//TIMSK1 Input Capture Interrupt enable und Counter Interrupt enable
//(wenn Counter Obergrenze erreicht)
//TCCR1B CTC(Clear Counter on Compare Match) Mode4 Prescaler 64
//(Fcpu=7,3728MHz

//if Schleife, falls Capture event 2 mal aufgetreten ist
// berechnet den absoluten Zähler aus Differenz der beiden
//Counterwerte + Eventuelle Counterüberlaufe*der Counterobergrenze
// Drehzahl wird mit der Counterfrequenz berechnet. (1/min!)
//Drehzahl wird an main zurückgegeben und seriell ausgegeben

//falls Capture event noch nicht 2mal aufgetreten, dann Drehzahl =0

//In der do while Schleife wird gewartet bis Capture event 2 mal
//aufgetreten ist und die Drehzahl berechnet wurde. Im Fall, dass der
//Lüfter steht wird gewartet bis der Counter 2 Mal übergelaufen ist
//(Da dann keine ISR auftritt

Ich hoffe das macht meine Absicht deutlich

von Matthias (Gast)


Lesenswert?

>>sollte das nicht eher || (Ueberlauf <= 2) heissen
Das ist richtig. Habe ich auch gesehen, bringt aber auch nicht den
Durchbruch

von inoffizieller WM-Rahul (Gast)


Lesenswert?

>Habe ich der Übersichtlichkeit weggeleassen.

LOL

Welche maximale Frequenz liefert dein Lüfter?
Mit welcher Frequenz läuft dein Controller?

von Matthias (Gast)


Lesenswert?

Der Lüfter hat maximal 116HzHört sich sehr wenig an sind immerhin 6720
1/min).
CPU läuft mit 7,3728MHz, nach dem Prescaler des Counters sind dann noch
115,2kHz übrig.

von johnny.m (Gast)


Lesenswert?

Du benutzt globale Variablen, die sowohl in der ISR als auch im
Hauptprogramm verwendet werden. Die müssen volatile deklariert werden,
damit der Compiler da nicht dran rumoptimiert.

von Magnus Müller (Gast)


Lesenswert?

do
{
   ...
}while( (p |= 1) || (Ueberlauf >= 2) );

Äh... while((p|=1)...) ist doch immer wahr, oder? Wie kommst du dann
jemals aus dieser Schleife raus?

Gruß,
Magnetus

von Matthias (Gast)


Lesenswert?

Das bringt auch nichts. Sobald der Lüfter steht hängt das Programm.

von Matthias (Gast)


Lesenswert?

@Magnus: nein, In der If Schleife (Also wenn ISR 2mal aufgetreten und
die Drehzahl berechnet wurde); wird p = 1 gesetzt.

von inoffizieller WM-Rahul (Gast)


Lesenswert?

Was noch interessant wäre: Wie groß ist die niedrigste
Drehzahl/Frequenz?

von inoffizieller WM-Rahul (Gast)


Lesenswert?

>If Schleife

Gibt es nicht. Es handelt sich dabei um eine Abfrage und keine
Schleife. Schleifen können eine Abfrage zwecks
Abbruchbedingungserfüllungprüfung haben...

p |= 1

Danach ist p auf jeden Fall ungleich 0.
Meinst du vielleicht p!= 1?

von Matthias (Gast)


Lesenswert?

Auf dem Lüfter steht 8...13,2V.
Bei 8V macht er ein Rechtecksignal mit 68Hz. er schafft aber auch noch
weniger bis 26Hz darunter ist es kein Rechteck mehr.

von Matthias (Gast)


Lesenswert?

Ja genau, das hab ich gemeint. Muss ich mich vertippt haben. Das war
mein Gedankengang auf ungleich 1 zu prüfen.

von Magnus Müller (Gast)


Lesenswert?

>> Ja genau, das hab ich gemeint. Muss ich mich vertippt haben. Das
>> war mein Gedankengang auf ungleich 1 zu prüfen

Und funktionierts nun?

Gruß,
Magnetus

von Matthias (Gast)


Lesenswert?

Kann ich noch nicht sagen, bei Programmieren kommt beim anschließenden
lesen ein Fehler, der besagt dass er an einer Speicherstelle etwas
anderes erwartet wie das was er ausließt.

von inoffizieller WM-Rahul (Gast)


Lesenswert?

>der besagt dass er an einer Speicherstelle etwas
>anderes erwartet wie das was er ausließt.

Und was schreibt der Compiler nun wirklich? (Bin des enlischen
mächtig...)

von Matthias (Gast)


Lesenswert?

Reading FLASH.. OK!
WARNING: FLASH byte adress 0x0032 is 0x40(should be 0xCD).. FAILED!
Leaving programming mode.. OK!

von inoffizieller WM-Rahul (Gast)


Lesenswert?

Dann hat dein Controller einen an der Waffel...(mal gegen einen anderen
tauschen?)
Das hat nichts mit deinem Programm zu tun...

von Magnus Müller (Gast)


Lesenswert?

>> Dann hat dein Controller einen an der Waffel...

...oder der Programmer?
...oder die ISP-Strippe?

von FrankW (Gast)


Lesenswert?

... oder den Controller vor dem Flashen nicht gelöscht ?

von Matthias (Gast)


Lesenswert?

@FrankW: Daran lag, das Häkchen bei Erase Device before programming muss
ich versehentlich weggeclickt haben.
Danke

Aber um Grundproblem: Das Programm hängt weiterhin, wenn der Lüfter
steht.

Ist das der richtige interrupt auf den ich warte. Tritt der Counter1
Output Compare A Match auf, wenn mein Counter den Wert in OCR1A
erreicht hat?

von inoffizieller WM-Rahul (Gast)


Lesenswert?

>Ist das der richtige interrupt auf den ich warte

Eigentlich schon...
Vielleicht ist aber auch der Overflow-Interrupt...
Teste es doch mit einer LED, die du im Overflow-Interrupt umschaltest.
Das Flackern sollte man schon erkennen können.

von Matthias (Gast)


Lesenswert?

Ja ist der Richtige.

von Matthias (Gast)


Lesenswert?

ICh habe das Problem eingrenzen können. Der Drehzahl 0 Fall tritt nicht
auf, da Ueberlauf nicht wächst. (Habe es nach der do ahile Schleife
abgefragt).
Hat jemand eine Idee wie ich es anstatt lösen kann.

Ich brauche eine Konstruktion, die wartet bis der Capture Interrupt 2
mal aufgetreten ist, aber maximal bis zB 200ms(wenn der Lüfter steht)

von inoffizieller WM-Rahul (Gast)


Lesenswert?

Der Überlauf-Interrupt wird aber ausgelöst, wenn der Lüfter steht?

von Matthias (Gast)


Lesenswert?

Ja genau, der Überlauf Interrupt wird ausgelöst und mein Zähler wird
auch hochgezählt, wenn ich aber nach der do while Schleife den Zähler
abfrage ist er 0.

von inoffizieller WM-Rahul (Gast)


Lesenswert?

volatile vergessen?

von Matthias (Gast)


Lesenswert?

Nein

von Matthias (Gast)


Lesenswert?

Ich glaube, dass ganze hängt mit der Masse zusammen. Halte ich die Masse
des Lüfters mit der meiner Schaltung getrennt, bekomme ich auch eine
Ausgabe wenn der Lüfter steht, allerdings nichts sinnvolles, sogar
negative Werte.

Da fällt mir überhaupt auf, darf man 2 returns in einem Programm
haben??

von inoffizieller WM-Rahul (Gast)


Lesenswert?

>Da fällt mir überhaupt auf, darf man 2 returns in einem Programm
>haben??

ja, allerdings wird, so weit ich weiß, die Funktion dann auch beendet.
(Siehe k&r...)

von Andreas (Gast)


Lesenswert?

Hi,

ich habe so ziemlich das gleiche Problem wie du. da hier seit langer 
zeit nichts mehr geschrieben wurde, geh ich davon aus, dass dein problem 
erledigt ist.
könntest du mir vllt. den final funktionierenden code zusenden?

danke und grüße

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.