Forum: Mikrocontroller und Digitale Elektronik [S] Ringspeicher [msp430]


von Bergie B. (bergie)


Lesenswert?

Hi!

Ich messe mit meinem µC (MSP430) Temperaturen. Da meine Temperaturn nur 
selten Sprunghaft ansteigen mache ich eine Mittelwert bildung um 
Messefehler zu minimiren.

Dieses möchte ich in einem Rign Speicher Realiesiernen, bzw habe ich das 
schon gemacht. Die funktion ist auch gegeben, nur die übersichtlichkeit 
ist absulut nicht mehr vorhanden, deswegen würde ich gerne von euch ein 
Beispiel für einen übersichtihcen Ringspeicher sehen über den ich eine 
Mittelwertbildung mache.  Die größe des Speichers soll im Code änderbar 
sein und zwischen 0x02<x<0xFE liegen .. wobei ein Wert um 9 Realistisch 
seien wird denke ich. Darüber hinaus möchte ich einen Mittelwert über 
die letzten 2(oder3,4) Werte Bilden und die mit dem Gesammten Mittelwert 
vergleichen. Fals nun eine zu Große abweichung (+/- Delta_X oder +- 5%) 
bestehen sollte werden die Ringspeicher daten verworfen und neu 
aufgenommen.


LG Bergie

von Karl H. (kbuchegg)


Lesenswert?

1
#include <stdio.h>
2
3
#define RINGBUFFER_SIZE  9
4
#define INVALID_VALUE    -1000
5
#define LAST_MEAN_VALUES 3
6
7
int RingBuffer[ RINGBUFFER_SIZE ];
8
int RingBufferCurrent;               // zeigt an, wo der nächste Wert abgelegt wird
9
10
void InitRingBuffer( void )
11
{
12
  unsigned char i;
13
  
14
  RingBufferCurrent = 0;
15
  for( i = 0; i < RINGBUFFER_SIZE; ++i )
16
    RingBuffer[i] = INVALID_VALUE;
17
}
18
19
void AddValue( int Value )
20
{
21
  RingBuffer[RingBufferCurrent++] = Value;
22
  if( RingBufferCurrent == RINGBUFFER_SIZE )
23
    RingBufferCurrent = 0;
24
}
25
26
int MeanValue( void )
27
{
28
  unsigned char i;
29
  unsigned char nrValues = 0;
30
  long Summ = 0;
31
  
32
  for( i = 0; i < RINGBUFFER_SIZE; ++i ) {
33
    if( RingBuffer[i] != INVALID_VALUE ) {
34
      Summ += RingBuffer[i];
35
      nrValues++;
36
    }
37
  }
38
  
39
  if( nrValues == 0 )
40
    return INVALID_VALUE;
41
    
42
  return Summ / nrValues;
43
}
44
45
int MeanValueOfLast( void )
46
{
47
  long Summ = 0;
48
  unsigned char i = RingBufferCurrent;
49
  unsigned char nrValues = 0;
50
  
51
  do {
52
    if( i == 0 )
53
      i = RINGBUFFER_SIZE - 1;
54
    else
55
      --i;
56
    
57
    if( RingBuffer[i] != INVALID_VALUE ) {
58
      Summ += RingBuffer[i];
59
      nrValues++;
60
    }
61
  } while( nrValues != LAST_MEAN_VALUES && i != RingBufferCurrent );
62
  
63
  if( i == RingBufferCurrent )
64
    return INVALID_VALUE;
65
    
66
  return Summ / nrValues;
67
}
68
69
void PrintValues( void )
70
{
71
  unsigned char i = RingBufferCurrent;
72
  
73
  printf( "Buffer: " );
74
  do {
75
    if( RingBuffer[i] != INVALID_VALUE )
76
      printf( "%d ", RingBuffer[i] );
77
78
    i++;
79
    if( i == RINGBUFFER_SIZE )
80
      i = 0;
81
  } while( i != RingBufferCurrent );
82
  printf( "\n" );
83
}
84
85
      
86
int main()
87
{
88
  InitRingBuffer();
89
  
90
  PrintValues();
91
  printf( "%d  %d\n", MeanValue(), MeanValueOfLast() );
92
  
93
  AddValue( 5 );
94
  PrintValues();
95
  printf( "%d  %d\n", MeanValue(), MeanValueOfLast() );
96
97
  AddValue( 7 );
98
  PrintValues();
99
  printf( "%d  %d\n", MeanValue(), MeanValueOfLast() );
100
 
101
  AddValue( 9 );
102
  PrintValues();
103
  printf( "%d  %d\n", MeanValue(), MeanValueOfLast() );
104
105
  AddValue( 11 );
106
  PrintValues();
107
  printf( "%d  %d\n", MeanValue(), MeanValueOfLast() );
108
109
  AddValue( 20 );
110
  AddValue( 20 );
111
  AddValue( 20 );
112
  AddValue( 20 );
113
  AddValue( 20 );
114
  AddValue( 20 );
115
  AddValue( 20 );
116
117
  PrintValues();
118
  printf( "%d  %d\n", MeanValue(), MeanValueOfLast() );
119
}

Anstelle des Sonderfalls INVALID_VALUE, welcher nur am Anfang zum Tragen 
kommt, wenn der Ringspeicher noch nicht vollständig gefüllt ist, 
könntest du ganz einfach auch den Speicher mit deinem ersten Messwert 
fluten. Dann fallen viele Sonderfälle weg und der Code wird noch 
einfacher.

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
Noch kein Account? Hier anmelden.