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
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.
@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.