Hallo zusammen, ich wollte mir einen Digitalen Drehzahlmesser mit einer LCD-Anzeige fürs Auto bauen. Es sollte eine Drehzahl von ca. 1000 – 7000 U/min gemessen werden können. Das entspricht einer Frequenz von 16,6 Hz - 116,6 Hz. Um die Drehzahl zu erfassen wollte ich mittels Polling die Low-Zeit zählen. Da ich mich mit der Programmiersprache C recht gut auskenne sollte das eigentlich kein Problem sein. Ich habe auch schon ein Programm geschrieben mit dem ich eigentlich die Low-Zeit einer Rechteck-Spannung in ms messe und die auf das LC-Display ausgeben kann. Zum testen habe ich einen Frequenz-Generator an den Atmega16 angeschlossen, der mir eine 5V Rechteck-Spannung generiert. Jetzt zu meinem Problem. Egal welche Frequenz ich auf den Eingang gebe zeigt mir das Display irgendwelchen Murks an. Die Zahlen auf dem LC-Display schwanken unregelmäßig von ca. 550 – 1050. Eigentlich sollte auf dem LC-Display bei einer Frequenz von 1Hz ja 500 zu lesen sein, da ich ja nur das Low-Signal Messe. Berechne derzeit noch nicht die U/min, sondern lasse die Zeit des Low-Signal anzeigen. Bei 10 Hz zeigt mir das Display 60-105 an. Bei 100Hz zeigt mir das Display 7-13 an. Nutze derzeit noch die 1MHz des internen Quarzes. Woran kann das liegen? Ist die Lösung eigentlich für eine Frequenz von 16,6 Hz - 116,6 Hz geeignet?
Der interne RC-Generator (intere Quarze gibts so nicht) ist nicht sehr genau, kann man aber kalibrieren. Drehzahlmessungen brauchen aber eine recht genaue Zeitbasis. Per Polling wird se nicht ordentlich Funktionieren da ja der Zeitpunkt des Messbegins und Endes nicht exakt zur Flanke des Signals kommen, daher die schwankendem Messwerte. Besser mit dem Inputcapture des Timers oder Interruptgesteuerter Abfrage arbeiten.
Daniel wrote: > Auto bauen. Es sollte eine Drehzahl von ca. 1000 – 7000 U/min gemessen > werden können. Das entspricht einer Frequenz von 16,6 Hz - 116,6 Hz. Das ist rechnerisch richtig. Physikalisch kann je nach Messprinzip in deinem Auto eine andere Frequenz an deinem Drehzahlsensor anliegen. Wenn du nicht direkt dir Kurbelwellenumdrehungen misst, sondern die Zündimpulse, kommt es u.a. auf Zylinderzahl und Motorprinzip (Viertakt/Zweitakt) an.
Ich messe mit einem Initiator die Umdrehungen an der Riemenscheibe, die direkt auf der Kurbelwelle sitzt. Das erschien mir am sinnvollsten. Zündimpulse hat mein Diesel nicht. Des weiteren währe mir das zu Riskant, da ich mir nicht sicher bin, wie der Atmega und die Beschaltung auf die elektromagnetischen Einflüsse durch die Induktion an den Zündspulen / Zündkerze reagiert.
Hab ich das richtig verstanden: Du misst die Zeit, in der der Sensor ein low-Pegel ausgibt? Üblicher ist Vorgehensweise, bei der Impulse gezählt werden. D.h. dass du enweder über Polling überprüfst, ob ein Pegelwechsel (z.B. von low nach high) stattgefunden hat und addierst die Wechsel. Das ganze machst du über eine gewisse Zeit (Timer) und errechnest dir daraus die Frequenz. Eine weitere Möglichkeit wäre einen Timer nicht per Quarztakt, sondern mit einem extern angeschlossenen Takt (deinem Sensor) hochzählen zu lassen. Danach wieder die Frequenz mit der verstrichenen Zeit berechnen. Der Nachteil: Du brauchst mehrere Umdrehungen für die Frquenzberechnung. Das wird dir fürs Auto wohl zu langsam sein. Ansonsten: Bleib bei deiner Methode und arbeite mit einem externen Interrupt. -> von low nach high -> Timer start, beim nächsten low nach high -> Timer stop. Im Timer hast du dann deine Zeit. Wenn du nur die Low-Zeit misst, weißt du die Frequenz ja nicht. Die High-Zeit spielt da auch mit rein.
> Der interne RC-Generator (intere Quarze gibts so nicht) > ist nicht sehr genau, kann man aber kalibrieren. Das betrifft eher die absolute Genauigkeit und die Temperaturabhängigkeit. Im Kurzzeitbereich (Minuten) kann die Frequenz als konstant angesehen werden. D.h. evtl. wird ein falscher Wert angezeigt, aber der ist dann konstant. > Eigentlich sollte auf dem LC-Display bei einer Frequenz von 1Hz > ja 500 zu lesen sein, da ich ja nur das Low-Signal Messe. Wie sieht denn dein Signal aus? Hast du wirklich ein Tastverhältnis von 50%? Üblicherweise wird die Frequenz eines Signals von z.B. der steigenden Flanke zur nächsten steigenden Flanke gemessen.
Bei meinem Frequenzgenerator habe ich eine Tastverhältnis von 50%, also bei 1 Hz 500ms high dann 500ms low. Ich wollte so erstmal Testweise die Low-Zeit messen, da ich später in der Realität bei 1 Hz ca 25ms ein High-Signal habe und dann 975ms ein Low-Signal. Ob ich jetzt die gesamte Periode oder nur das Low-Signal messe, geht es mir erstmal ja gar nicht. Ich Frage mich, warum die Werte auf dem Display so stark von den errechneten abweichen. Mit einigen % Abweichung habe ich ja gerechnet und währen ja auch verkraftbar aber teilweise über 50% ist schon etwas seltsam, wie ich finde. Ich sehe da auch kein System hinter. Der Zahlenwirwar gleicht eher Zufallszahlen die ausgegeben werden. Habe ich in dem Quelltext, den ich oben gepostet habe irgendwo doch einen Fehler drin? Wüsste zumindest nicht wo. Währe euch sehr verbunden da mal einen Blick rein zu werfen.
Wahrscheinlich braucht die Ausgabe auf dem Display recht lange, locker einige zig Millisekunden. Die erste Abfrageschleife kannst Du auch aus der Endlosschleife rausziehen. Am besten wäre wirklich eine Interrupt-gesteuerte Auswertung. Dann könntest im Interrupt die Zeit abspeichern und in der Hauptschleife neu gemessene Werte ausgeben. Gruß, Roland
Der Code sieht eigentlich ok aus. Kreativ, aber lebensfähig. > Bei 10 Hz zeigt mir das Display 60-105 an. > Bei 100Hz zeigt mir das Display 7-13 an. Schon recht eigenartig, du kommst nicht mal annähernd in den Bereich, der zu erwarten wäre... 10 Hz -> 50ms low, 50ms high. Die Verwaltung der Schleife braucht auch noch Zeit, so dass ausschliesslich Werte unter 50 herauskommen müssten. Wie sieht denn jetzt dein Signal aus: Signalgenerator mit 0V/5V Rechteck und 50% Tastverhältnis? Das hast du mit einem Oszi gemessen? Oder glaubst du das nur? Versuch doch mal den umgekehrten Weg: Gib ein Signal an einen uC-Pin aus, und miss nach, ob das jittert. Also nur z.B.
1 | // angenommen am Pin D0 hängt eine LED
|
2 | main { |
3 | DDRD = 1; |
4 | while(1) { |
5 | PORTD = 1; |
6 | _delay_ms(1000); |
7 | PORTD = 0; |
8 | _delay_ms(1000); |
9 | }
|
10 | }
|
Das kannst du schon alleine mit dem Auge und einer Uhr kontrollieren. Mit kleineren Verzögerungszeiten ist ein Oszi besser.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.