Zeit zwischen zwei Pulsen messen

Gast #3563016
Lesenswert?

Hallo,
Ich baue eine Drehzahlmessung. Ein Hallsensor sendet bei jeder Umdrehung 
einen Puls an meinen Atmega2560.

Habe mir überlegt, einen Timer immer von 0 an hochzählen zu lassen. Bei 
einem Puls wird ein Interrupt ausgelöst und der Timer gestoppt sowie die 
Zeit ausgewertet.

Passt das so, oder gibt es einen eleganteren Weg? Das ganze soll 
möglichst nicht die CPU belasten.

Grüsse, 007
(Firma: Brainit GmbH) #3563030
Lesenswert?

Karl Heinz schrieb:

> Alle Lösungen, die keinen Input Capture verwenden, sondern Timer
> starten, stoppen und loeschen , kannst du getrost ignorieren.

Naja... grundsätzlich hast du recht, aber: sobald der ICP-Pin 
anderweitig fest vergeben ist, oder mehr als ein Signal (bzw. mehr als 
ICP-Eingänge vorhanden) gemessen werden muss, kommt man um eine 
Alternative nicht herum... soviel Unterschied zwischen ICP und 
"normalem" PinChange-Int mit Timer auslesen ist dann auch nicht. 
natürlich ist ICP einfacher, sauberer und genauer.
Gast #3563049
Lesenswert?

Ok, hört sich gut an. Danke für die Hinweise. Ich route momentan noch 
das Layout, deshalb kommt es mir vorallem darauf an, den richtigen Pin 
auszuwählen.

Für den High Speed Capture Modus muss ich einen ICP Pin nutzen, richtig?

Laut Datenblatt des ATmega2560 bieten sich an:
PD4(ICP1)
PE6(ICP3)
PL0(ICP4)
PL1(ICP5)

Ist einer zu bevorzugen? So wie ich das verstanden habe, gehört jeder zu 
einem eigenen baugleichen 16-bit Timer. Daher dürfte es wohl egal sein?

007
Gast #3563059
Lesenswert?

Hi

>Für den High Speed Capture Modus muss ich einen ICP Pin nutzen, richtig?

Jain. Alternativ zu den ICP-Pins kann Input Capture auch vom Analog 
Comparator getriggert werden. Und wenn du den ADC nicht benutzt stehen 
dir dadurch auch noch die Pins ADC0...ADC15 zur Verfügung.

MfG Spess
Gast #3563072
Lesenswert?

Hi

>Alternativ zu den ICP-Pins kann Input Capture auch vom Analog
>Comparator getriggert werden.

->Alternativ zu den ICP-Pins kann Input Capture von Timer1 auch vom 
Analog
Comparator getriggert werden.

MfG Spess
Gast #3563083
Lesenswert?

spess53 schrieb:
> Alternativ zu den ICP-Pins

kann man auch jeden Pin-Change-Eingang verwenden, den aktuelle AVRs 
überall haben.
Beitrag "4-Kanal Drehzahlmessung mit ATmega88"
oder für nur einen Kanal
Beitrag "Frequenz / Drehzahl, 4-stell. 7-Segm.-LCD, ATtiny45"

Eine Belastung der CPU findet in der Regel nur dann statt, wenn 
Universalfunktionen wie delay_ms(100) aufgerufen werden :-)
Gast #3563085
Lesenswert?

007 schrieb:
> Habe mir überlegt, einen Timer immer von 0 an hochzählen zu lassen. Bei
> einem Puls wird ein Interrupt ausgelöst und der Timer gestoppt sowie die
> Zeit ausgewertet.

Wozu den Timer stoppen?
ICP ist sicher die beste Lösung, aber es geht auch ohne. Dann aber den 
Timer laufen lassen und lediglich in der ISR den Wert auslesen.
Gast #3563094
Lesenswert?

Genau. Denn dann must Du den Zählerstand per Software auslesen, und die 
kann sich wegen gesperrter Interrupts beliebig verzögern.

Der Input Capture Eingang hingegen ist ein hardware Feature, der 
funktioniert auch, wenn Interrupts global gesperrt sind. Also kann 
dessen Capturing nicht verzögert werden.
Gast #3563111
Lesenswert?

Michael Reinelt schrieb:
> Ja, aber das ist dann streng genommen kein ICP mehr, oder?

Richtig. Aber um zum Beispiel ein 4-stelliges Ergebnis bei 10 
Messungen/s zu erhalten, reicht eine Auflösung der Zeit von <=10µs. ICP 
wird dann notwendig, wenn die Zeit auf <100ns aufgelöst gemessen werden 
muß.

In jedem Fall muß beim ICP- oder PC-Interrupt eine ISR aufgerufen 
werden, die die Ereignisse zählt.
Nimmt man beispielsweise eine Drehzahl von 6000Upm, so sind das 100Hz 
und die ISR wird alle 10ms aufgerufen. Selbst bei suboptimaler 
Programmierung dauert diese ISR <5µs. Die µC-Belastung liegt somit bei 
ca. 0,05%.
Gast #3563181
Lesenswert?

Hi

>In jedem Fall muß beim ICP- oder PC-Interrupt eine ISR aufgerufen
>werden, die die Ereignisse zählt.

Das sind aber zwei paar Schuhe. Bei ICP wird der Zeitpunkt beim 
Eintreffen des Ereignisses gespeichert. Wann die ISR das Ergebnis abholt 
ist irrelevant solange es vor dem nächsten Ereignis erfolgt.

Wenn per PC gemessen wird zählt nicht das Ereignis sondern der 
Zeitpunkt, an dem die ISR aufgerufen wird. Also nur wirklich nutzbar, 
wenn der PC-Interrupt
ständig freie Bahn hat.

MfG Spess
Gast #3563206
Lesenswert?

spess53 schrieb:
> Also nur wirklich nutzbar,
> wenn der PC-Interrupt
> ständig freie Bahn hat.

Man kann dem PCI ja freie Bahn schaffen, indem andere ISRs ihm den Platz 
einräumen.
Auch der ICP-Interrupt muß für jedes Ereignis freie Bahn haben, sonst 
gehen Ereignisse verloren.
Falls Jemand ISRs nicht richtig programmiert, geht es immer schief. Auch 
ICP geht schief, wenn man die Anforderungen (virtuell) immer weiter 
hochschraubt, dass keine Lösung mehr möglich ist. Soll der TO seine 
Anforderungen kundtun, dann kann man sehen, was notwendig und was 
überflüssig ist.
Gast #3563239
Lesenswert?

Stefan us schrieb:
> Genau. Denn dann must Du den Zählerstand per Software auslesen, und die
> kann sich wegen gesperrter Interrupts beliebig verzögern.

Ja. Aber wenn man den Timer weiterlaufen läßt, geht nichts verloren. 
Eine Messung ergibt dann eine minimal längere Zeit, dafür ist sie bei 
der nächsten Messung wieder entsprechend kürzer. Das spielt bei einer 
Drehzahlmessung aber keine große Rolle, da sich die Drehzahlen nicht so 
wahnsinnig schnell ändern. Wenn man einen gleitenden Mittelwert bildet, 
rechnet man damit den Jitter wieder raus - vorausgesetzt, man stoppt den 
Timer nicht.
Gast #3563255
Lesenswert?

m.n. schrieb:
> Soll der TO seine
> Anforderungen kundtun, dann kann man sehen, was notwendig und was
> überflüssig ist.

Es geht um eine Drehzahlmessung für ein Regelung. Es treten Werte im 
Bereich von ca. 1 bis 100 Hz auf. Das ganze soll aber möglichst im 
Hintergrund ablaufen und nicht die CPU belasten. Sobald ein neuer Wert 
erfasst wird, möchte ich einen Interrupt haben, der dann kurz rechnet 
und die Stellgröße des Regelkreises ändert.

007
Gast #3563378
Lesenswert?

007 schrieb:
> Es treten Werte im
> Bereich von ca. 1 bis 100 Hz auf. Das ganze soll aber möglichst im
> Hintergrund ablaufen und nicht die CPU belasten.

Ich habe Dir ja eine Hausnummer (0,05% @ 100Hz) genannt. Für meine 
Begriffe belastet das die CPU nur unwesentlich. Da die untere Frequenz 
bei 1Hz liegt, kann die Regelung auch nicht besonders schnell ausfallen, 
sodass die zeitliche Auflösung Drehzahlerfassung rel. unkritisch ist.
#3563541
Lesenswert?

Worum gehts jetzt eigentlich?

Ob man das auf Biegen und Brechen mit einem Pin Change Interrupt löst 
oder ganz einfach das Feature des Timers einsetzt (Input Capture), 
welches Atmel genau zu diesem Zwecke dem Timer mitgegeben hat, selbst 
wenn man damit auf einen bestimmten Pin festgenagelt ist.

Bitte sagt mir, dass das jetzt nicht das Thema ist.
#3563549
Lesenswert?

> Auch der ICP-Interrupt muß für jedes Ereignis freie Bahn haben, sonst gehen 
Ereignisse verloren.

Ja.
Das ist aber ein ganz anderer Fall als der, bei dem der Pin Change 
Interrupt verzögert kommt, weil ein anderer Timerinterrupt gerade das 
Multiplexing einer 7-Segment Anzeige gemacht hat.

Das der Input Capture ...
1
voaltile uint16_t difference;
2
volatile uint8_t newValue;
3

4
ISR( ... )
5
{
6
  uint16_t now = ICR1;
7
  static uint16_t last;
8

9
  difference = last - now;
10
  newValue = TRUE;
11
}
... auch irgendwann an seine Grenzen kommt, ist klar. Sobald die 1/f der 
zu messenden Schwingung in die Nähe der Ausführungszeit irgendeiner ISR 
kommt, beginnt die Sache haarig zu werden. Aber das ist kein Grund, dass 
ich mir ein Messergebnis von einem anderen Interrupt versauen lasse, in 
dem ich den ICP nicht benutze, weil Pin Change cool ist.
Gast #3563599
Lesenswert?

Karl Heinz schrieb:
> Das ist aber ein ganz anderer Fall als der, bei dem der Pin Change
> Interrupt verzögert kommt, weil ein anderer Timerinterrupt gerade das
> Multiplexing einer 7-Segment Anzeige gemacht hat.

Ich weiß ja, dass Du meine Programmierkünste nicht zu schätzen weiß. Das 
ist aber nicht mein Problem :-)

Sieh Dir mal das Multiplexen einer 7-Segementanzeige an.
Beitrag "Frequenz, Drehzahl, 4x7-Segment LED, Multiplex-Betrieb"

Ich habe die ISR fürs Multiplexen einmal extrahiert:

ISR(TIMER1_COMPB_vect)   // wird mit MPX_FREQUENZ aufgerufen
{
static uint8_t digit_nr;
  OCR1B += MPX_TEILER;   // Intervall nachladen
  sei();                 // und gleich wieder freigeben

Wie man sieht, wird der globale Interrupt wieder zugelassen, sobald 
OCR1B nachgeladen ist. Abhängig vom Compiler, wieviele Register er 
retten muß, sollte der Interrupt bei 16MHz Taktfrequenz nach 1-2µs 
wieder verfügbar sein. Das weitere Multiplexen kann in Ruhe abgearbeitet 
werden.
Mit den von mir genannten 10µs sind wir (ich zumindest) noch weit 
entfernt!
Gast #3564046
Lesenswert?

Die Lösung mit ICP ist die bessere, weil genauer und auch von der CPU 
Belastung klein. Wenn die Anforderungen nicht so hoch sind oder kein ICP 
Pin zur Verfügung steht, geht es auch mit einem Interrupt (z.B. Pin 
Change oder Int0,Int1) - allerdings gibt es da eine Ungenauigkeit durch 
die nicht immer gleiche Reaktionszeit auf den Interrupt. Je nachdem was 
sonst noch an Interrupts läuft können das 10 oder auch 100 Zyklen werden 
- wenn man es schlecht macht natürlich auch mehr.
#3564893
Lesenswert?

m.n. schrieb:
> Karl Heinz schrieb:
>> Das ist aber ein ganz anderer Fall als der, bei dem der Pin Change
>> Interrupt verzögert kommt, weil ein anderer Timerinterrupt gerade das
>> Multiplexing einer 7-Segment Anzeige gemacht hat.
>
> Ich weiß ja, dass Du meine Programmierkünste nicht zu schätzen weiß. Das
> ist aber nicht mein Problem :-)
>
> Sieh Dir mal das Multiplexen einer 7-Segementanzeige an.
> Beitrag "Frequenz, Drehzahl, 4x7-Segment LED, Multiplex-Betrieb"
>
> Ich habe die ISR fürs Multiplexen einmal extrahiert:

Oh geh, bitte.
Ich hab hier im Forum zig 7-Segment Multiplex Routinen geschrieben. 
Denkst du echt, ich wüsste nicht wie das geht?

> > Ich weiß ja, dass Du meine Programmierkünste nicht zu schätzen weiß.

Oh, nein.
Was ich an dir nicht schätze, das ist, dass du alles anders machen 
musst, aus keinem wirklich guten Grund heraus. Du machst es anders und 
du schlägst was anderes vor, nur damit es anders ist. Und dagegen hab 
ich was.
Solange sich das Problem überhaupt nicht stellt, dass alle 4 ICP Pins 
besetzt sind und man das auch hardwaremässig nicht ändern kann, gibt es 
keinen Grund, dem TO einen Pin Change Interrupt schmackhaft zu machen. 
Es ist die einfachste Lösung, die keine Probleme aufwirft (ausser dem 
fast gleichzeitigem Auftreten von Capture und Overflow) und sich auch 
gut in ein nahezu beliebiges Gesamtprogramm einfügt, solange das nur 
einigermassen nach den Regeln der Kunst gebaut ist. Bis jetzt hab ich an 
einer Pin Change Lösung nichts, aber auch gar nichts gesehen, inwiefern 
sie einer Capture Lösung überlegen wäre - ausser der Möglichkeit 
beliebige Pins hernehmen zu können, was ich allerdings als nicht 
wirklich wesentlich erachte wenn 4 mögliche Pins zur Verfügung stehen.

Ich hab nichts gegen 'anders machen'. Aber 'anders machen' nur um des 
'anders machen' Willens, ist mir zu wenig. Es gibt erprobte und gute 
Lösungen, deren Verhalten und Nebenwirkungen gut bekannt sind.
Gast #3565107
Lesenswert?

Karl Heinz schrieb:
> Alle Lösungen, die keinen Input Capture verwenden, ... , kannst du
> getrost ignorieren.

Was ich nicht mag, sind genau diese pauschalen Falschaussagen!
Dabei geht es mir nicht darum, mich mit Unbelehrbaren zu streiten, 
sondern unerfahrenen Personen Mut zu machen, anderer Leute Vorurteile 
nicht  ungeprüft fürs eigene Handeln zu übernehmen.
Für diese Erkenntnis muß man leider erst alt werden, aber besser spät 
als nie :-)

Ulrich schrieb:
> Die Lösung mit ICP ist die bessere, weil genauer und auch von der CPU
> Belastung klein.

Keine Frage! Aber die Praxis zeigt doch, dass man nicht immer einen für 
alle Belange völlig freien Controller zur Verfügung hat. Wenn, wie beim 
ATmega2560, noch viele freie ICPs zur Verfügung stehen, nimmt man sie 
natürlich. (Den ICP vom 90S2313 nutze ich seit 15 Jahren; er kam damals 
wie für mein Problem geschaffen im pinkompatiblen 89C2051 Gehäuse.)

Bei Interrupts kann man natürlich auch viel falsch machen - auf der 
anderen Seite aber auch gut lernen, die Prioritäten im Programm 
sorgfältig zu setzen. Da muß man seine eigenen Erfahrungen machen und 
diese immer wieder neu an neuerer Hardware überprüfen.
Mit "Das machen wir immer so" bleibt man im Kopf stehen!

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren