FIFO-Buffer befüllung

Gast #1697741
Lesenswert?

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;
Gast #1697818
Lesenswert?

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.
Angehängte Dateien:
#1697831
Lesenswert?

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.
Gast #1697850
Lesenswert?

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...
#1697871
Lesenswert?

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.
#1697883
Lesenswert?

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 ....
Gast #1698089
Lesenswert?

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!
Gast #1698165
Lesenswert?

Hallo

So könntest du deinen Buffer machen, spart Zeit:

#define BUFFER_SIZE      30


#define BUFFER_SUCCESS   0x00
#define BUFFER_OVERFLOW  0x01
#define BUFFER_EMPTY     0x02

int buffer[BUFFER_SIZE];
int bufferDataPoitner=0;

unsigned char fillBuffer(int value)
{
    if(bufferDataPointer>=BUFFER_SIZE-1)
    {
        return BUFFER_OVERFLOW;
    }
    buffer[bufferDataPointer]=newValue;
    bufferDataPointer++;
    return BUFFER_SUCCESS;
}

unsigned char getBufferVal(int *value)
{
    if(bufferDataPointer<0)
    {
        return BUFFER_EMPTY;
    }
    *value=buffer[bufferDataPointer];
    bufferDataPointer--;
    return BUFFER_SUCCESS;
}

lg
#1698217
Lesenswert?

oliver schrieb:

> Danke für weitere Ratschläge!


sieh dir mal folgende Version an
(Warnung: ungetesteter Code, direkt im Forum eingetippt)
1
#define NR_VALUES   30
2

3
uint32_t  avgSum;
4
uint16_t  adcBuffer[ NR_VALUES ];
5
uint16_t  actAdcNr;
6
float     avg;
7

8
void fillBuffer( uint16_t nextVal )
9
{
10
  adcActNr++;
11
  if( adcActNr == NR_VALUES )
12
    adcActNr = 0;
13

14
  avgSum -= adcBuffer[ actAdcNr ];
15
  adcBuffer[ actAdcNr ] = nextVal;
16
  avgSum += nextVal;
17

18
  avg = avgSum / (double)NR_VALUES;
19

20
#ifdef CHECK_VALUES
21
  // zu Kontrollzwecken
22
  over_threshold = 0;
23
  for( uint16_t = 0; i < NR_VALUES; ++i )
24
  {
25
    uint16_t j = i + actAdcNr;
26
    if( j >= NR_VALUES )
27
      j -= NR_VALUES;
28
 
29
    if( adcBuffer[j] > THRESHOLD_VALUE )
30
      over_threshold++;
31
    sprintf( s, "%02d: buffer[%02d]: %3d\r\n", i, j, adcBuffer[j] );
32
    uputs( s );
33
  }
34
  uputs( "\r\n" );
35
  sprintf( s, "avg: %f\r\n" , avg );
36
  uputs( s );
37
  sprintf( s, "over_threshold: %d\r\n", over_threshold );
38
  uputs( s );
39
#endif
40
}

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.
Moderator (Firma: Titel) Persönliche Seite #1698260
Lesenswert?

> 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
Gast #1701817
Lesenswert?

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.
#1701824
Lesenswert?

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.
Gast #1701829
Lesenswert?

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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren