Forum: Mikrocontroller und Digitale Elektronik Frequenzmessung ICP spinnt


von Peter (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen, nun wurde das eine Problem mit dem Graycode gelöst, 
schon kommt das nächste.
Und zwar versuche ich von einem Anemometer die Umdrehungen/min bzw m/s 
zu erfassen. Soweit, so gut. Das gute Stück hat einen Reedkontakt der 
pro Umdrehung zwei mal schaltet. Der Kontakt hängt am ICP (PD6).
Als Hilfe habe ich mich an den Beispielen die man so im Netz findet 
bedient. Nun dachte ich mir das ich als ersten Schritt die Periodendauer 
am Eingang messe und diese per UART ausgebe. Funktioniert soweit 
eigentlich, aber die Werte die da rauskommen, da kann ich mir keinen 
Reim drauf machen. Ich bitte um Beistand! :-)

ATmega32, 16MHz Quarz, im Anhang der Code und die Ausgabe bei etwa 
konstanter Umdrehunggeschwindigkeit.

von Karl H. (kbuchegg)


Lesenswert?

Machs doch nicht sooooo kompliziert
1
volatile uint32_t cap;
2
3
4
ISR(TIMER1_CAPT_vect)                        //  Flanke an ICP pin
5
{
6
  cap = ICR1;
7
8
  if ((cap < 128) && (TIFR & (1<<TOV1)))
9
  {                                // wartenden timer overflow Interrupt vorziehen
10
    ++softtimer;
11
    TIFR = (1<<TOV1);                      // timer overflow int. löschen, da schon hier ausgeführt
12
  }
13
14
  cap |= ((uint32_t)softtimer << 16;                      // obere 16 Bit aus Software Zähler
15
  zeitdifferenz = cap - timestamp;
16
  timestamp = cap;                      // Zeit merken
17
}


Dein Compiler hilft dir schon, so dass du nicht jeden Kleinscheiss 
selber lösen musst.

Deine Werte sehen aus, als ob dein Kontakt mächtig prellt.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz schrieb:

> Deine Werte sehen aus, als ob dein Kontakt mächtig prellt.

Äh. Moment.

Nach einer Messung solltest du softtimer auch wieder auf 0 zurück 
setzen.

von Karl H. (kbuchegg)


Lesenswert?

Um den ganze Sleep Kram
1
      sleep_enable ();                    // Sleep Befehl freigeben
2
      sei();
3
      sleep_cpu();                      // wartet auf irgendeinen Interrupt, z.B. ICP, timer_ovr,...
4
      sleep_disable();                    // Sleep Befehl sperren

kümmert man sich ganz zum SChluss.

Und dafür
1
        ultoa(zeit,puffer,10);                // nach ASCII umwandeln
2
        i = 0;
3
        
4
        while (puffer[i])
5
          {
6
          uart_putc(puffer[i++]);              // Ausgabe
7
          }
8
        uart_putc(13); uart_putc(10);            // Zeilenumbruch senden
9
      }
baut man sich Hilfsfunktionen, die zu den UART Routinen dazu kommen. Da 
du die Fleury Funktionen benutzt, hast du ja bereits ein uart_puts, 
welches einen String ausgeben kann. Perfekt um den String auszugeben, 
den dir ultoa liefert.
1
void uart_putl( uint32_t value )
2
{
3
  char buffer[15];
4
5
  ultoa( value, buffer, 10 );
6
  uart_puts( buffer );
7
}

Kein Grund bei jedem Projekt das Rad immer wieder neu erfinden zu 
müssen. Wenn ein Rad danach stinkt, dass es allgemein benutzbar sein 
wird, dann gibt man es eben zum Vorrat an fertigen Rädern dazu.

1
...
2
   while( 1 )
3
   {
4
     cli();
5
     zeit = zeitdifferenz;
6
     zeitdifferenz = 0;
7
     sei();
8
      
9
     if (zeit > 0)
10
     {
11
       uart_putl( zeit );
12
       uart_puts( "\r\n" );
13
     }
14
  }
15
}

ist doch in der main gleich viel lesbarer, wenn man sich auf das 
wesenetliche konzentrieren kann und sich nicht mit Kleinkram abgeben 
muss.

: Bearbeitet durch User
von Michael S. (captain-stone)


Lesenswert?

Servus Peter,

> Das gute Stück hat einen Reedkontakt der
> pro Umdrehung zwei mal schaltet. Der Kontakt hängt am ICP (PD6).

hab auch schon ein Anemometer (Inspeed Vortex Wind Sensor) eingelesen. 
Hab das Signal aber (über einen Schmitt Trigger) auf einen externen 
Interrupt gelegt, die Impulse gezählt und nach einer Sekunde ausgewertet 
und dann umgerechnet (2,5 mph / Hz).

: Bearbeitet durch User
von Peter (Gast)


Angehängte Dateien:

Lesenswert?

Karl Heinz schrieb:
> Kein Grund bei jedem Projekt das Rad immer wieder neu erfinden zu
> müssen. Wenn ein Rad danach stinkt, dass es allgemein benutzbar sein
> wird, dann gibt man es eben zum Vorrat an fertigen Rädern dazu.

Haha, danke Karl Heinz für den Hinweis. Habe den Code mal angepasst und 
nochmal angefügt.
Aber kann ich davon ausgehen das der Kontakt zwei mal prellt!? Sieht ja 
anscheinend so aus in der Ausgabe.

Also besser mal die Prellroutine einpflegen? Dann werde ich mich damit 
mal beschäftigen.


Michael Steinbauer schrieb:
> Hab das Signal aber (über einen Schmitt Trigger) auf einen externen
> Interrupt gelegt, die Impulse gezählt und nach einer Sekunde ausgewertet
> und dann umgerechnet (2,5 mph / Hz).

Gab es einen bestimmten Grund das du es so gelöst hast?

von Ulrich H. (lurchi)


Lesenswert?

Wie oft so ein Kontakt prellt ist nicht 100% sicher. Zum entprellen 
sollte es ausreichen nach einer Flanke erst einmal eine gewisse Zeit 
(z.B. 1-10 ms) zu warten in der keine neuen Signal erkannt werden, bzw. 
neue Signal erst einmal zu ignorieren.

Es bleibt aber noch das Problem das auch die längeren Zeiten nicht 
stabil sind. Da muss noch was anderes Faul sein. Bis jetzt waren die 
Vorschläge ja vor allem kosmetische Änderungen um den Code lesbarer zu 
machen.

von m.n. (Gast)


Lesenswert?

Peter schrieb:
> Aber kann ich davon ausgehen das der Kontakt zwei mal prellt!? Sieht ja
> anscheinend so aus in der Ausgabe.

Aus Deiner 'Ausgabe' werde ich nicht schlau, aber Du kannst den Kontakt 
ganz einfach mit einem RC-Glied entprellen. Der ICP1-Eingang hat einen 
Schmitttrigger.

Du kannst auch aktiv mit einem RC-Glied entprellen; es kommt darauf an, 
welche Pulsweiten zu verarbeiten sind.

von Michael S. (captain-stone)


Lesenswert?

> Michael Steinbauer schrieb:
>> Hab das Signal aber (über einen Schmitt Trigger) auf einen externen
>> Interrupt gelegt, die Impulse gezählt und nach einer Sekunde ausgewertet
>> und dann umgerechnet (2,5 mph / Hz).

> Gab es einen bestimmten Grund das du es so gelöst hast?

Nein, da ist kein Geheimnis dahinter. Es führen mehrere Wege nach Rom. 
Aber die Kollegen helfen Dir ja schon bei einer der möglichen 
Vorgehensweisen. Bleib ruhig dabei.

Wenn ich soetwas mache, dann sammle ich die Daten nur am µC, schick sie 
zu einem PC und berechne dort alles. Das ist meine Vorgehensweise, die 
ist so gewachsen, weil ich µC in Assembler programmier und am PC in C. 
Also teile ich die Arbeiten so auf. Zur Entprellung: Ich hab das wie 
oben beschrieben in der Hardware mit einem Schmitt-Trigger gemacht, das 
hat völlig ausgereicht, es bedurfte keiner Entprell-Routine beim 
Anemometer.

von Karl H. (kbuchegg)


Lesenswert?

Ulrich H. schrieb:

> Es bleibt aber noch das Problem das auch die längeren Zeiten nicht
> stabil sind. Da muss noch was anderes Faul sein. Bis jetzt waren die
> Vorschläge ja vor allem kosmetische Änderungen um den Code lesbarer zu
> machen.

Nicht ganz
Beitrag "Re: Frequenzmessung ICP spinnt"

OK. das mag im Rest unter gegangen sein, wäre aber nichts desto trotz 
eine mögliche Erklärung.

: Bearbeitet durch User
von Ulrich H. (lurchi)


Lesenswert?

Das zurücksetzen des Softtimers (also der in Software gezählten 
Überläufe) sollte keine Verbesserung bringen, sondern nur noch 
zusätzliche Fehler oder Wartezeit weil der 1. Wert danach nicht mehr 
stimmt.

Auch das Prellen sollte nur für die kurzen Zeiten (etwa < 1000) 
verantwortlich sein, und bei den längeren Werten dann etwa Rauschen um 
vielleicht +-2000 bringen: die kurzen Zeiten gehören im Prinzip zu der 
Nächsten langen dazu, das kann man sogar noch nachträglich korrigieren.

Der 1. Test wäre zu sehen wie das Programm mit einem sauberen Signal 
(etwa ein NE555) funktioniert.

von Peter (Gast)


Angehängte Dateien:

Lesenswert?

Nabend, Programm wurde jetzt so verändert das die Überläufe nach der 
Ausgabe zurückgesetzt werden. Zusätzlich habe ich zur Entprellung ein 
RC-Glied verbaut. Habe jetzt mal mit steigender und fallender Flanke 
experimentiert. Bei beiden Logs habe ich eine Konstante 
Windgeschwindigkeit durch einen Fön aufgezeichnet. Bei fallender Flanke 
sieht das schon ganz gut aus, aber irgendwas funkt da noch mit rein.

Die Log´s und der aktuelle Code sind im Anhang.

von Peter (Gast)


Lesenswert?

Ulrich H. schrieb:
> Der 1. Test wäre zu sehen wie das Programm mit einem sauberen Signal
> (etwa ein NE555) funktioniert.

das ist eine sehr gute Idee!

von Ulrich H. (lurchi)


Lesenswert?

Die sehr großen Werte (fast 2^32) kommen einfach durch das zurücksetzen 
des Zählers. Die Zeit wäre auch viel zu lang um richtig zu sein. Die 
anderen Werte sehen auch bei der steigenden Flanke nicht wirklich gut 
aus. einiges wiederhohlen sich, aber nicht alle. Für mich sieht das mehr 
nach einem Problem mit dem Signal als mit dem Programm aus.

von Peter (Gast)


Angehängte Dateien:

Lesenswert?

So, zurück zum Thema. Habe jetzt den Reedkontakt rausgeschmissen und 
einen Hallsensor TLE4905 verbaut. Der Programmcode ist noch der gleiche, 
außer das ich den Overflow in der Main nicht mehr auf 0 setze.

Die Werte sehen auch ganz gut aus. In der log-Datei wird erst Stufe 2 
eines Föns gemessen, danach Stufe 1.

Wie würdet ihr es jetzt angehen damit man auf einen guten 
Umrechnungsfaktor kommt der m/s ausgibt?

von Peter (Gast)


Lesenswert?

Kann mir jemand mal mit der Umrechnung auf die eigentliche 
Umdrehungsgeschwindigkeit auf die Sprünge helfen? Finde absolut keinen 
Ansatz momentan.

von Hannes J. (Firma: _⌨_) (pnuebergang)


Lesenswert?

Peter schrieb:
> Kann mir jemand mal mit der Umrechnung auf die eigentliche
> Umdrehungsgeschwindigkeit auf die Sprünge helfen? Finde absolut keinen
> Ansatz momentan.

Peter schrieb:
> Das gute Stück hat einen Reedkontakt der
> pro Umdrehung zwei mal schaltet.

-> f = 1 / (2 * t)

von Peter (Gast)


Lesenswert?

Ja ok.

f = 1 / T

das weiß ich auch :)

Aber, angenommen bei einem Quarz von 16MHz und einem Prescaler von 1024, 
habe ich 15625 Zyklen/Sekunde.

Wenn ich jetzt einen Wert von 7625 ausgespuckt bekomme, entspricht das 
dann 2,049 Umdrehungen/Sekunde ?

von MWS (Gast)


Lesenswert?

Peter schrieb:
> Kann mir jemand mal mit der Umrechnung auf die eigentliche
> Umdrehungsgeschwindigkeit auf die Sprünge helfen?

Umdrehungsgeschwindigkeit in Hz, oder Umlaufgeschwindigkeit in m/s oder 
Windgeschwindigkeit in m/s?

Was ist es, ein Schalenanemometer?
Bei dem bremst die vorlaufende Schale und die rücklaufende beschleunigt.

Umdrehungsgeschwindigkeit
Beitrag "Re: Frequenzmessung ICP spinnt"

Umlaufgeschwindigkeit
Frequenz f (wie oben) in Hz mal 2 x r x Pi, r ist der mittlere Radius 
zur Schale

Windgeschwindigkeit
Such' nach Schalenanemometer und Schnelllaufzahl.
Z.B.
http://www.wer-weiss-was.de/physik/schalenkreuzanemometer-fuer-wind-messung
Oder:
Beitrag "Anemometer"

> Wenn ich jetzt einen Wert von 7625 ausgespuckt bekomme, entspricht das
> dann 2,049 Umdrehungen/Sekunde ?

Zählertakt: 16000000 / 1024 = 15625Hz
Gemessen: 15625 / 7625 = 2,049Hz

Wenn "zweimal", nur mit Hallsensor, noch zutrifft:

Peter schrieb:
> Das gute Stück hat einen Reedkontakt der
> pro Umdrehung zwei mal schaltet.

Dann sind's 1,0246 U/s

von Peter (Gast)


Lesenswert?

Super viel dank für die hilfreiche Antwort. Dann war mein Ansatz ja gar 
nicht so verkehrt.

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.