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.
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
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.
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
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
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?
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.
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.
> 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.
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
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.
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.
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!
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.
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?
Kann mir jemand mal mit der Umrechnung auf die eigentliche Umdrehungsgeschwindigkeit auf die Sprünge helfen? Finde absolut keinen Ansatz momentan.
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)
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 ?
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.