Hi, wie kann ich mit einem AVR eine Frequenz erzeugen, die sich konstant (z.B. in 2 Hz-Schritten) ändern läst? Es geht konkret um einen Zähler, der 5000x rauf- und runterzählen kann. Bei einem Zählwert von 0 will ich bespielsweise eine Frequenz von 200 Hz haben, bei jeden Zählwert hoch, soll die Frequenz z.B. um 2 Hz ansteigen. Endfrequenz nach oben wäre also 10200 Hz. Somit könnte man den Zählerstand per Frequenz übertragen, messen und als Zahl darstellen. Mit nem 16 Bit-Timer wird das nach meinem rumgerechne so richtig keiner. Gibt da was trikkiges?
Hegy wrote: > Mit nem 16 Bit-Timer wird das nach meinem rumgerechne so richtig keiner. > Gibt da was trikkiges? Der 16 Bit Timer wäre meine erste Wahl. Der hat eine CTC (Clear Timer on Compare) Einheit. Mit der müsste es gehen. Oops sehe gerade, dass nicht feststeht, welcher AVR es denn überhaupt ist. Ich hab jetzt die Zahlen nicht nachgerechnet, das schlimmste was dir passieren kann ist, dass du zwischendurch mal den Teilerfaktor ändern musst. Aber ansonsten sollte das mit der CTC kein Problem sein.
Mit 8MHz und 16-Bit Timer im CTC-Modus ergibt sich eine Abweichung in der Frequenz von maximal 0,12%. Bei 10MHz 0,1%. Bei 12,28MHz 0,08%. Ist das zu viel? Auf ganze Zahlen gerundet dargestellt fällt das gar nicht auf. Bei höheren Taktfrequenzen schlägt bei den mir bekannten AVRs der schlecht skalierbare Prescaler zu: nach Teilerfaktor 1 folgt 8, dann können die 16 Bit nicht mehr ausgenützt werden. Eine bessere Frequenzsynthese fällt mir beim AVR nicht ein. (Wäre ein Stichwort für Google, um Anregungen zu holen) Grüße, Peter
Besser: DDS. Auflösung theoretisch unendlich hoch, allerdings erhält man ein Jitter, und der Rechenaufwand ist höher.
Das geht nach dem DDS-Prinzip. Bei der Wahl der passenden Taktfrequenz lässt sich auch 2 Hz Schrittweite erreichen. siehe auch:www.myplace.nu/avr/minidds/minidds.asm
Mit dem 16bit Timer, der übrigens auch im ATmega48 drin ist, habe ich rumgerechnet (CTC-Modus), mit glatten Quarzfrequenzen (1MHz bis 12 MHz) und eben nur den 2 zu gebrauchenden Prescalerwerten 1 und 8. Damit habe ich mir ne Tabelle gebaut und das mal mit Zählerständen von 1 bis 1000 ausrechnen lassen. Das blöde ist, daß ich nix lineares herausbekomme. Es sieht ungefähr so aus: Z | Freq. | delta (sollte annähernd konst. sein) ---+--------+--------- 1 | 200000 | 2 | 100000 | 100000 3 | 66666 | 33333 4 | 50000 | 16666 5 | 40000 | 10000 6 | 33333 | 6667 7 | 28571 | 4762 ... 1000 | 200,0 | 0,2 1001 | 199,8 | 0,2 1002 | 199,6 | 0,2 .... 4000 | 50 | 0,0125 Je höher der Zählerstand ist, desto geringer wird der Frequenzunterschied zum Zählerstand davor. Bei Zählerständen in der oberen Hälfte ist die Änderung nur noch so gering, daß man einen Präzisionsfrequenzzähler braucht, Abweichung nur noch im Bereich von kleiner 0,01 Hz. Oder gibt es da einen geschickten Algo, der sowas weitgehenst kompensiert (Vorschlag v. Karl Heinz B. & Peter (Gelb))? Variabel ist ja der Zählerstand des Timers und der Prescalerwert. Die Sache mit der Frequenzsynthese kukk ich mir mal nachher an, bin gerade auffe Arbeit, ist dafür nicht so die Zeit für vorhanden.
Hegy wrote: > ich mir ne Tabelle gebaut und das mal mit Zählerständen von 1 bis 1000 > ausrechnen lassen. Das blöde ist, daß ich nix lineares herausbekomme. Es > sieht ungefähr so aus: Was ist das Z in deiner Tabelle. Niemand sagt, dass du deinen Zählerwert direkt als CTC Wert für den Timer nehmen musst. Da dein Zählerwert bis maximal 5000 geht, der CTC Wert im Timer aber bis 65535 gehen kann, hast du doch einigen Spielraum um dein Z so in einen CTC Wert umzurechnen, dass jeder Z Wert in einer eindeutigen Frequenz mündet. Zur Not wirst du wahrscheinlich mitten in deiner Tabelle irgendwo den Vorteiler umschalten müssen. Disclaimer: Ich hab die Mathe dahinter jetzt nicht gemacht. Das du ein nicht konstantes Delta bekommst ist natürlich blöd, liegt aber in der Natur der Sache. Die ganz kleinen CTC Werte würde ich aber meiden, wenn irgend geht.
Das Z in der Tabelle, habe ich vergessen zu erklären, ist der Zählerstand. Und die Mathe dahinter, genau da liegt nämlich der Hund begraben, ist so, daß es nie linear verlaufen kann, weil sieht ungefähr so aus (PRSC = 1): Frequenz = f_Quarz / CTC-Wert und da der CTC-Wert als Divisor auftaucht (und vom Zählerstand geändert werden könnte), wird die Sache keinesfalls mehr linear. Aber vllt. gibt es eine Möglichkeit das zu kompensieren oder eben anders zu realisieren.
Irgendwie verstehe ich dein Problem nicht: In jedem Schritt setzt du den CTC Wert auf f_cpu/Zähler. Und am Ausgang erhälst du eine linear zunehmende Frequenz.
Das ist eine 1/x-Funktion, also eine Hyperbel. Die berechnet man mit einer Division, das dauert zwar, aber ist dann exakt. http://www.mikrocontroller.net/articles/AVR_Arithmetik#Division http://www.atmel.com/dyn/resources/prod_documents/doc0936.pdf AVR200: Multiply and Divide Routines
@Benedikt K. Wenn ich so vorgehe, bin ich nix weiter. Zwar ändert sich die Frequenz linear, aber nur bis zu einem rel. kleinen Zählerstand. Danach wird der Unterschied von einem CTC-Werte zum anderen so klein, daß hintren raus keine Frequenzänderung mehr kommt, wenn der Zählerstand hochgezählt wird. Dann ändert sich die Frequenz nur noch, wenn der Zähler um 2 zulegt, dann um 3, 4, 5....; je höher der Zählerstand desto mehr Zählerstandsänderungen (in eine Richtung) sind nötig, um einer Frequenzänderung zu bekommen.
Bei 10kHz hätte man noch eine Auflösung von 9Hz. Brauchst du wirklich 2Hz ? Ansonsten könntest du einen AVR mit PLL (tiny26x, tiny25 usw.) nehmen, die haben einen Timer der mit 64MHz läuft. Oder eben DDS. Was für dich besser ist, musst du wissen, denn du verrätst ja nicht wozu das gut sein soll.
Was er damit bezwecken will, steht doch oben drin. Den Zählerstand 0...5000 in eine Frequenz umzuwandeln um, zu übertragen und dann z.B. mit nem Zählfrequenzmesser auszuwerten. Sehe ich zumindest so. Und da kann es ruhig DDS sein... wobei ich die Genauigkeit einer solchen Methode eher bezweifle. Gruß Jörg
Sinn und Zweck: Einen Zählerstand (0 bis 5000, Reserve bis -100) in eine Frequenz umsetzen, über eine Leitung übertragen (kontinuierlich), Frequenz messen, Zählerstand ausrechnen, einfach, preiswert, zuverlässig, hineichend genau.... Es muß nicht unbedingt in 2 Hz Schritten erfolgen, war nur ein Beispiel. Auf der anderen Seite sollte die Frequenz nicht zu hoch werden. Irgendwo zw. 50kHz und 100 kHz sollte schon Schluß sein.
Das Interessante ist ja, dass bei der DDS die Auflösung bei hohen Frequenzen höher ist, bei einem Zähler (CTC) bei den niedrigen Frequenzen. Der große Vorteil der DDS ist, dass man mittels LookUpTable beliebige Formen erzeugen kann (die oberen Bits des Phasencounters dienen als Zeiger in die LUT). Wenn Du bei 100 kHz noch einigermassen Auflösung haben willst, brauchst Du wie gesagt eine hohe Basisfrequenz. Die Frage ist, ob Du nicht ein fertiges DDS-ICs verwenden solltest.
@ Hegy (Gast) >Sinn und Zweck: Einen Zählerstand (0 bis 5000, Reserve bis -100) in eine >Frequenz umsetzen, über eine Leitung übertragen (kontinuierlich), >Frequenz messen, Zählerstand ausrechnen, einfach, preiswert, >zuverlässig, hineichend genau.... Na wenn du schon nen uC hast, dann mach doch gleich RS232 oder so. ALles andere ist von hinten durch die Brust ins Auge. >Es muß nicht unbedingt in 2 Hz Schritten erfolgen, war nur ein Beispiel. >Auf der anderen Seite sollte die Frequenz nicht zu hoch werden. Irgendwo >zw. 50kHz und 100 kHz sollte schon Schluß sein. Ich hab mal sowas in unserer Studienarbeit gemacht. Dabei gings um Freqeunzen zwischn 10..15 kHz. Das Ganze per Timer und DDS. Die Mathematik ist bissel tricky, dafür hat die CPU dann wenig zu tun und kann nebenbei noch viel machen ;-) Aber nimm lieber RS232 & Co. MFG Falk
Falk Brunner wrote: > Ich hab mal sowas in unserer Studienarbeit gemacht. Dabei gings um > Freqeunzen zwischn 10..15 kHz. Das Ganze per Timer und DDS. Die > Mathematik ist bissel tricky, dafür hat die CPU dann wenig zu tun und > kann nebenbei noch viel machen ;-) Mathematik ? Das ist doch ganz simpel: Ausgangsfrequenz = Taktfrequenz*Wert/Akkumulatorgröße Das ganze ist ziemlich rechenintensiv, vor allem wenn man wenig Jitter möchte. Es sind zwar ganz simple Operationen (Addieren und LUT Ergebnis ausgeben), aber bei 1MHz Samplerate kommt ein AVR ziemlich ins Schwitzen.
@Falk Mit RS232 habe ich auch schonmal dran gedacht, aber das wird keiner, weil die Leitungsenden an einem Meßgerät enden und nicht am PC oder sonstwas. Außerdem ist wird das nicht nur ein Zähler, sondern 4 und das jetzt noch auf einen Bus zu bringen oder auf 4 serielle Schnitten......neee. Das einzige, was die analog-Daten entgegennimmt ist ein Meßgerät. Derzeit funktioniert die Kiste noch mit Spannungen von 0 bis 5V (oder mehr), ist super ungenau (Poti) und nicht zuverlässig (Poti wird zerbröselt durch Radialkräfte). Beste Datenaufnahme geschieht zurch zählen, beste Übertragungsart ist meiner Meinung nach eben Frequenz und da spielt die Spg. kaum ne Rolle.
@ Benedikt K. (benedikt) >> Ich hab mal sowas in unserer Studienarbeit gemacht. Dabei gings um >> Freqeunzen zwischn 10..15 kHz. Das Ganze per Timer und DDS. Die >> Mathematik ist bissel tricky, dafür hat die CPU dann wenig zu tun und >> kann nebenbei noch viel machen ;-) >Mathematik ? Das ist doch ganz simpel: >Ausgangsfrequenz = Taktfrequenz*Wert/Akkumulatorgröße Denkst DU. Lies nochmal GENAU! >Das ganze ist ziemlich rechenintensiv, Eben NICHT, wenn man es clever (tm) macht. Man muss "nur" den Timer im richtigen Abstand klingeln lassen, soga das Pin togglen kann man per OCP machen. Der "normale" Ansatz, bei dem mit jedem Takt ein Akku inkrementiert wird, geht da natürlich nicht. > vor allem wenn man wenig Jitter möchte. Ist für ne Frequenzmessung hier egal. > Es sind zwar ganz simple Operationen (Addieren und LUT Ergebnis >ausgeben), aber bei 1MHz Samplerate kommt ein AVR ziemlich ins >Schwitzen. Das ist NICHT clever, nur Brute Force. MFG Falk
@ Hegy (Gast) >Schnitten......neee. Das einzige, was die analog-Daten entgegennimmt ist >ein Meßgerät. WAS für eins? > Derzeit funktioniert die Kiste noch mit Spannungen von 0 >bis 5V (oder mehr), ist super ungenau (Poti) und nicht zuverlässig (Poti >wird zerbröselt durch Radialkräfte). Was ist das denn für ein Aufbau? > Beste Datenaufnahme geschieht zurch >zählen, beste Übertragungsart ist meiner Meinung nach eben Frequenz und >da spielt die Spg. kaum ne Rolle. Du legst dich vorzeitg fest, ohne die Alternativen wirklich geprüft zu haben. Naja. MFG Falk
Falk Brunner wrote: > Eben NICHT, wenn man es clever (tm) macht. Man muss "nur" den Timer im > richtigen Abstand klingeln lassen, soga das Pin togglen kann man per OCP > machen. Der "normale" Ansatz, bei dem mit jedem Takt ein Akku > inkrementiert wird, geht da natürlich nicht. Du meint einen fractional Divider (bzw. auch Dual Modulus Teiler gennant) ? Das ist afaik aber keine DDS. Nichtdestotrotz, hättest du einen Programmausschnitt, der die Berechnungen der beiden Werte macht ? Ich hatte sowas auch mal ausprobiert, musste aber die Werte durch ausprobieren anpassen, da sie sich ja gegenseitig beeinflussen und unterschiedlich gewichtet werden müssen.
@ Benedikt K. (benedikt) >Du meint einen fractional Divider (bzw. auch Dual Modulus Teiler >gennant) ? nöö, DDS. >Nichtdestotrotz, hättest du einen Programmausschnitt, der die >Berechnungen der beiden Werte macht ? Ich hatte sowas auch mal Als Assembler. Nur bedingt verdaulich ;-) >ausprobiert, musste aber die Werte durch ausprobieren anpassen, da sie >sich ja gegenseitig beeinflussen und unterschiedlich gewichtet werden >müssen. Kann man alles korrekt berechnen. MFG Falk
Falk Brunner wrote: > @ Benedikt K. (benedikt) > >>Du meint einen fractional Divider (bzw. auch Dual Modulus Teiler >>gennant) ? > > nöö, DDS. Jetzt habe ich ehrlich gesagt garkeine Ahnung was das sein soll. Ich kenne nur die klassische DDS und eben den fraktionalen Teiler.
@Falk Meßgerät: So'n Multimeter (MM) eben, kann Spannung, Strom (beides AC/DC), Ohms, Periodendauer, Frequenz und Temperatur. Diese Werte können mit einem PC ausgelesen werden. Vor dem MM sitzt noch ein Mehrfach-Umschalter, der die einzelenen Leitungen auf den Eingang des MM schaltet. Der Umschalter wird ebenfalls vom PC gesteuert. Und das ist fest, so fest fest, da gibt's nix dran zu rütteln. Kann ich nicht ändern. Ich will nur die Meßwertaufnahme präzisieren, zuverlässiger gestalten und vorallen austauschbar. Ich will hier den Gesamtaufbau garnicht erlären, ist nicht ganz einfach und schon Jahre alt. Deswegen gibt es auch keine tiefgreigfende Änderung am Konzept. Und diese Mechanik mit irgenwelchen Stiften die in irgendwelche Poti eingreifen und die dann drehen, ist eine Konstruktion von -keine Ahnung-, jedenfalls nicht auf meinem Mist gewachsen. Die Stifte haben in den Potis die Eigenschaft auch mal radial auszuscheren, was dann irgendwannmal jedes Poti zerbröseln läst & das wird auf Dauer ziemlich nervig. Und das ist der Jetzt-Zustand. Und aufgrund der Stifte in den Potis, die sich in fast jeder Position plazieren lassen, sind alle Stifte in den Potis unterschiedlich drin, weswegen der Austausch auf die schnelle nicht gemacht werden kann und auch künftig nicht mehr braucht, wenn alles ganz bleiben würde. Und ich will die Stifte in den Potis durch Kontakt und Zähler nach Frequenzumsetzung ersetzen, meiner Meinung nach die einfachste Möglichkeit. Alternativen zu diesem Konzept sind mir in den letzten Wochen/Monaten nicht eingefallen.
@ Benedikt K. (benedikt) >Jetzt habe ich ehrlich gesagt garkeine Ahnung was das sein soll. Ich >kenne nur die klassische DDS und eben den fraktionalen Teiler. Es IST ja auch ne DDS, aber eben nur zur Erzeugeung eines Taktsignals. Es wird nur das MSB des Akkus ausgegeben. Und anstatt x Takte zu machen bis das MSB sich ändert, bei dem jedesmal der Akku erhöht werden muss, berechnet man vorher, wieviel Takte das sind, wartet die per Timer die Zeit und ändert dann das MSB. ;-) Falk
Geht es euch auch so: ich kann mir (noch) überhaupt nicht vorstellen, um was es eigentlich geht. Die Erklärung ohben geht überhaupt nicht darauf ein, was jetzt mit der Frequenz passiert. Oder verstehe das nur ich nicht? @Falk: jetzt machst Du mich aber auch neugierig. Her mit dem Code, mein Magen ist so einiges gewöhnt. Ich kann mir nur vorstellen, dass relativ selten ein relativ hoher variabler (jeweils berechneter) Wert addiert wird.
@ Hegy (Gast) >garnicht erlären, ist nicht ganz einfach und schon Jahre alt. Deswegen >gibt es auch keine tiefgreigfende Änderung am Konzept. Naja, OK. Legacy Support halt. >wenn alles ganz bleiben würde. Und ich will die Stifte in den Potis >durch Kontakt und Zähler nach Frequenzumsetzung ersetzen, meiner Meinung >nach die einfachste Möglichkeit. Geht es um eine Drehzahlmessung? Wozu der AVR? Ne Lichtschranke oder Hallsensor und gut ist. >Alternativen zu diesem Konzept sind mir in den letzten Wochen/Monaten >nicht eingefallen. Dazu müsst erstmal klar dargestellt werden, WAS gemessen werden soll. Das WIE kommt weit danach. MFG Falk
@ eProfi (Gast) >Geht es euch auch so: ich kann mir (noch) überhaupt nicht vorstellen, um >was es eigentlich geht. Die Erklärung ohben geht überhaupt nicht darauf >ein, was jetzt mit der Frequenz passiert. Oder verstehe das nur ich >nicht? Willkommen im Club. ;-) >@Falk: jetzt machst Du mich aber auch neugierig. Her mit dem Code, mein >Magen ist so einiges gewöhnt. Morgen, komm ich jetz auf die Schnelle nicht ran. >Ich kann mir nur vorstellen, dass relativ selten ein relativ hoher >variabler (jeweils berechneter) Wert addiert wird. In die Richtung. MfG Falk
Noch ne Airklärung Was gemessen wird, sind die Umdrehungszahlen von einem Motor. Aber am Motor direkt geht nicht, ist so und wird nicht geändert. An der Motorachse sitzt ein Getrieb mit heftiger Untersetzung, daran gekoppel jener ominöser Stift, der in ein Poti greift. Hat irgendwann mal irgendwer zusammengebastelt. Aufgrund der Untersetzung sind die Drehmoment ziemlichz hoch. Läuft der Motor gegen den Anschlag, stoppt der Motor nicht umbedingt, sondern wird weiter bestromt, nicht schlimm, brennt nix ab, ist so, bleibt so......jedenfalls bringt diese hohe Drehmoment das Getriebe in eine leichte "Schräglage", was die Radialkräfte am Poti freisetzt und dann evtl. das Poti zum zerbröseln bringt. Um zu wissen, wieviel Umdrehungen der Motor gemacht hat bzw. um zu wissen, wo die Karre steht, wird gezählt mittels eines Kontakt (meine Idee). Zählen soll der AVR, wer sonst. Der Motor stoppt übrigens auch zwischendurch und läuft dann weiter oder wieder zurück. Um die Drehrichtung festzustellen sind daher 2 Kontakte nötig, das aber soll der AVR auswerten und daraus eine Frequenz bilden. Am Pezeh wird die Frequenz dann zur Umdrehungszahl zurückgerechnet, z.B. so: (Istfrequenz - Grundfrequenz) / Schrittweite der Frequenz, konkret nen beispiel: (18355 Hz - 500 Hz) / 5 Hz (Schrittweite der Frequenz je Umdrehung) = 3571 gelaufene Umdrehnugen. So, ich mach mal Feierabend, war ja nicht besonders produktiv heute :-} Heute abend nach'm Trehnink kukk ich dann nochmal hier rein, wenn's @home nicht noch Streß gibt, sonst morgen abend.
@ eProfi (Gast) >@Falk: jetzt machst Du mich aber auch neugierig. Her mit dem Code, mein >Magen ist so einiges gewöhnt. Bon Apetit! MFG Falk
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.