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