Hallo Forum, ich habe einen Frequenzmesser mit dem ATmega programmiert.
Nun mein Problem: Wenn die Frequenz, sagen wir bei 6000 Hz liegt können
da ab und an Schnitzer von 30 Hz gemessen werden. Die Geister wissen
warum. Ich weiß es nicht. Ich lese immer den Timer nach einem Interrupt
aus und da kommt es ab und an vor, daß der Wert eklatant vom eigentliche
erwarteten abweicht. Habt ihr eine Lösung wie ich solche Schnitzer (muß
ja nicht genau 30 Hz sein kann mehr oder weniger sein) die extrem vom
erwarteten abweichen erkennen kann?
Karl Heinz schrieb:> anfänger0815 schrieb:>>> Ich weiß es nicht.>> Ich habe eine Vermutung.> Es könnte an deinem Programm liegen.
Ich tippe eher auf Bug im Compiler oder libc. Sein Programm hört sich
richtig an, so wie er es beschreibt ;-)
Vieleicht ein mikroskopisch kleines schwarzes Loch, das eine
Zeitdilatation verursacht.
Wohnst du vieleicht in der Nähe vom Cern?
Im Ernst:
SOURCECODE, und bitte siehe Netiquette dazu.
Udo Schmitt schrieb:> Vieleicht ein mikroskopisch kleines schwarzes Loch, das eine> Zeitdilatation verursacht.> Wohnst du vieleicht in der Nähe vom Cern
Das klingt schlüssig. Raumschiff Enterprise hatte ja öfter mal Probleme
mit dem Bordcomputer in der Nähe von Singularitäten. Da kann dann auch
mal ganz schnell das Raum-Zeit-Kontinuum instabil werden. Uiuiui.
cyblord ---- schrieb:> Udo Schmitt schrieb:>> Vieleicht ein mikroskopisch kleines schwarzes Loch, das eine>> Zeitdilatation verursacht.>> Wohnst du vieleicht in der Nähe vom Cern>> Das klingt schlüssig. Raumschiff Enterprise hatte ja öfter mal Probleme> mit dem Bordcomputer in der Nähe von Singularitäten. Da kann dann auch> mal ganz schnell das Raum-Zeit-Kontinuum instabil werden. Uiuiui.
Ja, schon. Aber spätestens seit Cpt. Piccard ist ja bekannt, wie man das
löst: Man weißt den Computer an, die Schilde auf ein Zufallsmuster mit
exakt 78.652985% Anteil von weißem Rauschen zu progammieren. Mach es so!
>exakt 78.652985% Anteil
reicht da ein float normaler Genauigkeit aus?
->
Vielleicht erklärst Du erstmal mit wenigen Worten, wie das Programm
arbeiten soll.
;Sollte das Ergebnis negativ sein wird noch das Zweierkomplement gebildet.
2
clc
3
com tmp4
4
com tmp5
5
com tmp6
6
ldi tmp7,1
7
add tmp4,tmp7
8
ldi tmp7,0
9
adc tmp4,tmp7
10
adc tmp5,tmp7
Das brauchst du nicht.
Da du unsigned (also nicht vorzeichenbehaftet) rechnest, kannst du die
Werte bedenkenlos einfach voneinander abziehen. Das Ergebnis ist
trotzdem korrekt. Ob die Subtraktion unterläuft oder nicht, interessiert
hier nicht.
> Ist aber nicht so ganz mein Problem.
Doch,
Denn deine 'Spitzen' sind das Symptom, dass irgendwo im Programm etwas
nicht stimmt. Du willst aber das Problem angehen und nicht die Symptome.
Ein weiteres Problem kann dann entstehen, wenn der Input Capture fast
zeitgleich zum Overflow auftritt. Denn dann hängt es von Mykrosekunden
ab, ob der zum Zählerstand gehörende Overflow gezählt wird oder nicht.
Je nachdem ist aber das Ergebnis korrekt oder du hast einen Overflow zu
viel oder zu wenig gerechnet.
Wenn am Anschluß ICP1 sich der Pegel von Low nach High ändert wird der
Programmteil, den ich sinnigerweise "zaehler1_start_stop" genannt habe
angesprungen. Dort werden die zwei Zählerbytes und das Byte
zaehler1_hoch_temp_temp ausgelesen und für die nächste
Unterbrechungsanforderung abgespeichert. Die drei Bytes werden von den,
von dem letzten Unterbrechungsanforderung, abgespeicherten Zählerbytes
abgezogen. Das Ergebnis ist dann eine Zahl, die im umgekehrten
Verhältnis, unter Einbeziehung des Teilers und der akt. Quarzfrequenz,
zur gemessenen Frequenz steht.
Karl Heinz schrieb:> Ein weiteres Problem kann dann entstehen, wenn der Input Capture fast> zeitgleich zum Overflow auftritt. Denn dann hängt es von Mykrosekunden> ab, ob der zum Zählerstand gehörende Overflow gezählt wird oder nicht.> Je nachdem ist aber das Ergebnis korrekt oder du hast einen Overflow zu> viel oder zu wenig gerechnet.
Das hier schlägt in eine ähnlich Kerbe
wenn ich mir den Rest des Codes dazu denke, den du wieder mal nicht
gezeigt hast, dann ist das in einer Interrupt Routine, die du an den
Input Capture gehängt hast.
Dann willst du dir den Zählerstand aber nicht von TCNT1 holen, sondern
vom Input Capture Register ICR1. Denn genau dazu ist es da: Tritt eine
entsprechende Flanke auf, dann wird der Zählerstand von der Hardware
sofort (also ohne Verzögerung) in ICR1 gespeichert. Die Chancen, das
dieser Wert dann mit den gezählten Overflows dann auch tatsächlich
zusammenpasst steigen dadurch enorm, wenn der Timer gerade von FFFF auf
0000 umspringt, während die Flanke auftritt, bzw. kurz danach.
anfänger0815 schrieb:> Am besten den Overflow weglassen?
Das kommt auf deine zu messenden Frequenzen an. Wenn es sich im dich
interessierenden Bereich so ausgeht, dass du nie mehr als 65535
Zählertakte zu verrechnen hast, dann brauchst du den Overflow nicht
berücksichtigen. Einfach Zählerstand_am_Ende weniger
Zählerstand_am_Anfang rechnen, und es kommt das richtige Ergebnis raus
(selbst wenn da ein Overflow dazwischen lag). Nur dürfen zur
Zeitbestimmung einer Messperiode nicht mehr als 65535 Timer-Takte
anfallen, denn dann muss der erste Overflow entsprechend berücksichtigt
werden.
Bitte verstehe wenn ich den Rest des Codes mit angeben würde, würde ich
den Rahmen sprengen. In der Zwischenzeit habe ich in dem Programm 5558
Bytes, sagt der Assembler zumidest, geschrieben. Aber dasmit dem
Registern muß ich gleich mal testen.
anfänger0815 schrieb:> Bitte verstehe wenn ich den Rest des Codes mit angeben würde
Als Anhang geht das schon.
Es gibt hier genug Leute, die sich auch in 400 Zeilen Assembler
innerhalb kürzester Zeit zurecht finden.
Die Sache mit den zwei Registern scheint zu funktionieren. Ich bastel
jetzt noch a weng rum und melde mich demnächst wieder. Vielen Dank für
die Hilfe.
anfänger0815 schrieb:> Hallo Forum, ich habe einen Frequenzmesser mit dem ATmega programmiert.
und
Karl Heinz schrieb:> Ich habe eine Vermutung.> Es könnte an deinem Programm liegen.
Na klasse. Tolles Vorhaben und dazu passende Antwort vom Mod.
Ich lese in diesem Forum immer wieder, daß gerade Atmel-Fans ganz extrem
dazu neigen, für solche Vorhaben wie Zählfrequenzmesser irgendwelche
Software-Akrobatik mit ihrem ATmega und dessen internen Timern nebst
Capture-Registern zu betreiben - OHNE zuvor die Sache gründlich
durchdacht zu haben. Man zähle z.B. mal die Anzahl von
Firmware-Versionen vom Axel Schwenke zu seinem Projekt. Ja, ja, man
kriegt es nach langer Odyssee schon hin, daß es irgendwie zu
funktionieren beginnt, aber weil eben diese grandiosen
Software-Kunststücke immer wieder sowas wie Sampling-Zeitpunkte, nicht
erfaßte Überläufe, Vorrang zwischen verschiedenen Interrupts usw. nicht
WIRKLICH berücksichtigen, funktioniert das Produkt eben nur meistens und
nicht immer. Der Teufel liegt eben im Detail, das sollten Eleven sich
mal gut einprägen.
Das Schlimme an all diesen scheinbaren Steilvorlagen ist, daß sie von
Neulingen blind nachgebaut werden und selbige sich nie fragen, ob das
verwendete Konzept überhaupt tragfähig ist. Stattdessen wird hier
gefragt "warum geht es nicht wie erwartet, ich hab doch alles richtig
nachgeäfft.."
Mein Ratschlag an den TO ist: Mach es anders, spendiere deinem Projekt
ein paar IC's mehr - wenn's das Problem vereinfacht, sowas kostet nicht
die Welt, aber mach es geradlinig und OHNE Software-Tricks.
W.S.