Hallo!
ich habe vor, 30 int werte zu speichern. den neuesten Wert speichere ich
mir an stelle 0 in einem array. die anderen schiebe ich durch.
Die Stellen [0] und [1] sind od, leider erhalte ich immer die gleichen
Werte für die anderen Stellen.
meine Befüllung:
for(int i = 29; i >= 1 ;i--)
{
fifo_buffer[i] = fifo_buffer[i-1];
}
fifo_buffer[0] = act_value;
Im geposteten Minimalauschnnit ist nichts falsch (ausser das du deinem
AVR unnötig Arbeit machst, indem du i als int definierst, ein uint8_t
hätte es auch getan)
Das Problem liegt wieder mal in den nicht geposteten Codeteilen.
> die anderen schiebe ich durch.
Das ist der falsche Ansatz für einen Fifo, weil die Verwaltung
unglaublich viel Rechenleistung verbraucht.
In einem FIFO wandert nicht der Inhalt, sondern nur die Schreib- und
Lese-Zeiger: http://www.lothar-miller.de/s9y/categories/51-Fifo
Die anzahl der Werte soll evlt. ncoh erweitert werden auf eine Zahl, für
die ich auf jeden fall einen int, evtl. einen unsigned int benötige.
Werde ich alles zur einfacheren Bedienung Definen...
hier mal eine Datei im Anhang, an der man den Timerinterrupt und die
aufgerufene fifo_handler funktion sieht.
oliver schrieb:> Die anzahl der Werte soll evlt. ncoh erweitert werden auf eine Zahl, für> die ich auf jeden fall einen int, evtl. einen unsigned int benötige.
OK.
Gerade dann solltest du den FiFo auf jeden Fall auf einen Ringbuffer
umstellen.
void fill_fifo( int value_dB, int *fifo_buffer)
{
for(int i = 29; i >= 1 ;i--)
{
fifo_buffer[i] = fifo_buffer[i-1];
_delay_ms(50);
}
30 mal 50 Millisekunden, macht 1500 Millisekunden. Und das bei einer ISR
die alle 1000 Millisekunden aufgerufen werden soll. Das kann nicht gut
gehen.
Aber abgesehen davon: Du machst viel zu viel in deiner ISR! Und dann
noch dazu alles elends langsame Dinge!
So wirst du das Timing in deinem Programm nie unter Kontrolle kriegen
Aber zurück zum Problem.
Woher weißt du, dass nur die ersten beiden Werte im FiFo stimmen? Ich
sehe nirgends etwas, was dir diesen Umstand verraten könnte.
dieser Umstand wird gesehen in meiner Ausgabe, die ich in meiner
fill_fifo funktion mache.
Dort gebe ich das array komplett aus.
Die zeitliche Verzögerung war nur eine Idee. Ich habe es sogar mit einer
Puffervariablen versucht. den wert in einem einzelnen int gespeichert,
dann an eine andere stelle wieder eingetragen.
Ich weiß nicht, wo mein fehler ist...
oliver schrieb:> dieser Umstand wird gesehen in meiner Ausgabe, die ich in meiner> fill_fifo funktion mache.
Hmm.
Und wieso kann ich dann selbiges nicht auch sehen, wenn ich mir deine
Funktion anschaue und analysiere?
> Dort gebe ich das array komplett aus.
Wo?
Wie?
Mit welchen Formatierungen?
Kann es sein, dass in der Ausgabe ein Fehler war?
Frageb über Fragen.
> Die zeitliche Verzögerung war nur eine Idee.
:-)
War mir schon klar.
Aber Tatsache ist, dass du wirklich viel zu viel in deiner ISR machst.
Und dann auch noch auf die umständlichst mögliche Art und Weise. Was du
da machst ist Beschäftigungstherapie für deinen µC.
Ach ja.
Eines wollte ich noch sagen.
Mit dem langen String bei der Ausgabe kommst du bedenklich nahe an die
Grenze von 32 Charactern für s ran.
Nur mal so als Zwischeneinwand.
> Ich weiß nicht, wo mein fehler ist...
Du musst vor allen Dingen aufhören uns immer nur winzige Codeausschnitte
zu zeigen.
Auch wenn hier keiner wirklich glücklich damit ist, es hilft nichts: Der
komplette Code muss her. So wie er ist. So wie du ihn laufen lässt,
damit du den Fehler siehst.
Alles andere ist: sich selbst und uns anlügen. Es ist sinnlos, wenn wir
hier Fehler in Code suchen, der so nie läuft, oder wenn wir Fehler
suchen, die durch die Interaktion des Codes mit anderen Codeteilen
entstehen. So ist das nun mal bei globalen Variablen: Auch Codeteile,
die scheinbar nichts damit zu tun haben, können über die globalen
Variablen interagieren. Und sei es nur, weil dort irgendwo ein Array
überlaufen wird.
Karl heinz Buchegger schrieb:> Ach ja.> Eines wollte ich noch sagen.> Mit dem langen String bei der Ausgabe kommst du bedenklich nahe an die> Grenze von 32 Charactern für s ran.> Nur mal so als Zwischeneinwand.
Bei einem Blick auf dein zwischenzeitlich geposteten Screenshot würde
ich sogar sagen: Du bist drüber. Weit drüber. Und da das fifo_buffer
Array ein daran benachbartes Array ist ....
Karl heinz Buchegger schrieb:> Hmm.> Und wieso kann ich dann selbiges nicht auch sehen, wenn ich mir deine> Funktion anschaue und analysiere?
Das hier nehme ich übrigens zurück.
Hab die Stelle mitlerweile gefunden
besten Dank für eure Stellungnahmen.
im Prinzip habe ich nur vor, in regelmaßigem(also
timerinterruptgesteuertem) Intvervall den ADC eine Messung machen zu
lassen. Dessen Ergebnis möchte ich in einem Array speichern. evlt werden
es 300 sekunden mit 300 Werten. Also jede sekunde eine Messung.
Wenn ich im Interrupt den ganzen Code nicht ausführen darf, kann ich
dann den Code in mein main schreiben, wo ich in meiner for(;;) ein vom
Interrupt gesetztes flag abfrage und darauf hin funktionen wie read_adc,
fill_fifo usw ausführe? Rechenintensität sollte doch so nicht abnehmen,
macht nur die ISR selbst kleiner und beendet sich schneller. Dann wird
der code zwar außerhalb der ISR ausgef. jedoch ist die rechenzeit die
gleiche !?!
Danke für weitere Ratschläge!
> jedoch ist die rechenzeit die gleiche !?!
Klar, aber mal angenommen, du hast jetzt noch einen RS232-Empfang am
Laufen. Dann könnte bei der Verwaltung des Puffers in der ISR einfach
ein RS232-Interrupt verschlampt werden. Deshalb Interrupts kurz und
knackig.
Die Messwerte werden ganz einfach reihum im Array abgelegt. Dadurch,
dass ich weiß, wo der letzte Wert abgelegt wurde (actAdcNr), weiß ich
klarerweise auch, welches der älteste Wert im Buffer ist, er muss an der
nächsten Stelle stehen. Also keine Angst, wenn das logisch 0-te Element
nicht auch am Index 0 gespeichert ist. Das ist kein allzugrosses
Problem, wie man in der Ausgabeschleife sieht.
Schau dir auch an, wie ich die ganze Summiererei für die
Mittelwertberechnung durch Einführen einer weiteren Variablen
vereinfacht habe. Ich hebe mir einfach die Summe der Werte auf. Kommt
ein neuer dazu, dann wird der älteste aus der Summe rausgerechnet, dafür
kommt dann der neue dazu. Und schon habe ich wieder die aktuelle Summe,
ohne alle Messwerte aufsummieren zu müssen.
> Ich hebe mir einfach die Summe der Werte auf. Kommt ein neuer dazu,> dann wird der älteste aus der Summe rausgerechnet, dafür kommt> dann der neue dazu.
Für eine einfache Mittelwertbildung wäre mir schon der Speicher für die
letzten 300 Elemente zu schade. Da würde ich einfach ein RC-Glied
nachbilden: http://www.lothar-miller.de/s9y/categories/21-Filter
Gibts ne Gegenüberstellung der Rechnezeiten bei dem System, wo ich das
Array einzeln weiterschiebe und dem Buffer von euch?
Mich würde die Laufzeit interessieren, bei nem buffer von sagen wir 300
Werten mit Durchschnittswertbildung.
Bin auf Antwort gespannt.
oliver schrieb:> Gibts ne Gegenüberstellung der Rechnezeiten bei dem System, wo ich das> Array einzeln weiterschiebe und dem Buffer von euch?>> Mich würde die Laufzeit interessieren, bei nem buffer von sagen wir 300> Werten mit Durchschnittswertbildung.>> Bin auf Antwort gespannt.
Schreib ein Testprogramm mit der einen Systematik. Lade es in den
Simulator und lass dir die Taktzyklen für einen von dir gewählten
Testfall ausgeben.
Dann dasselbe noch einmal für die andere Systematik.
Dann weißt du es genau.
meinst du den Simulator von AVRStudio?
Den kenne ich bisher noch nicht, sollte ich mir aber mal ansehen. Bisher
habe ich geflasht, weil den MK2 kann man bequem stecken lassen auf dem
entwicklungsboard.
oliver schrieb:> meinst du den Simulator von AVRStudio?> Den kenne ich bisher noch nicht, sollte ich mir aber mal ansehen.
Solltest du.
Der hat einen wunderbaren Zyklencounter eingebaut, bei dem er dir genau
sagt, wieviele Taktzyklen von einem Breakpoint zum nächsten vergangen
sind.