Aus RN-Wissen.de
Wechseln zu: Navigation, Suche
Rasenmaehroboter Test

 
(Layout verändert, Kommentare gefärbt)
Zeile 9: Zeile 9:
 
=== Header ===
 
=== Header ===
 
;FloatingAverage.h
 
;FloatingAverage.h
<pre>
 
#ifndef FLOATING_AVERAGE_H
 
#define FLOATING_AVERAGE_H
 
  
#include <inttypes.h>
+
#ifndef FLOATING_AVERAGE_H
 +
#define FLOATING_AVERAGE_H
 +
 +
#include <inttypes.h>
 +
 +
{{ccomment|Ueber wieviele Werte soll der gleitende Mittelwert berechnet werden?}}
 +
{{ccomment|Zulaessige Werte 1..255}}
 +
#define SIZE_OF_AVG  8
 +
 +
{{ccomment|Datentyp, ueber den der gleitende Mittelwert berechnet werden soll.}}
 +
typedef uint16_t tFloatAvgType;
 +
{{ccomment|typedef float tFloatAvgType;}}
 +
 +
{{ccomment|Wird nur intern fuer die Durchschnittsberechnung benutzt.}}
 +
{{ccomment|Muss Zahlen fassen koennen, die SIZE_OF_AVG mal groesser als tFloatAvgType sind.}}
 +
typedef uint32_t tTempSumType;
 +
{{ccomment|typedef float tTempSumType;}}
 +
 +
{{ccomment|Die Struktur, in der die Daten zwischengespeichert werden}}
 +
typedef struct
 +
  {
 +
tFloatAvgType aData[SIZE_OF_AVG];
 +
uint8_t IndexNextValue;
 +
  } tFloatAvgFilter;
 +
 +
 +
{{ccomment|Initialisiert das Filter mit einem Startwert.}}
 +
void InitFloatAvg(tFloatAvgFilter * io_pFloatAvgFilter,
 +
  tFloatAvgType i_DefaultValue);
 +
 +
{{ccomment|Schreibt einen neuen Wert in das Filter.}}
 +
void AddToFloatAvg(tFloatAvgFilter * io_pFloatAvgFilter,
 +
  tFloatAvgType i_ui16NewValue);
 +
 +
{{ccomment|Berechnet den Durchschnitt aus den letzten SIZE_OF_AVG eingetragenen Werten.}}
 +
tFloatAvgType GetOutputValue(tFloatAvgFilter * io_pFloatAvgFilter);
 +
 +
#endif
  
// Ueber wieviele Werte soll der gleitende Mittelwert berechnet werden?
 
// Zulaessige Werte 1..255
 
#define SIZE_OF_AVG  8
 
 
// Datentyp, ueber den der gleitende Mittelwert berechnet werden soll.
 
typedef uint16_t tFloatAvgType;
 
//typedef float tFloatAvgType;
 
 
// Wird nur intern fuer die Durchschnittsberechnung benutzt.
 
// Muss Zahlen fassen koennen, die SIZE_OF_AVG mal groesser als tFloatAvgType sind.
 
typedef uint32_t tTempSumType;
 
//typedef float tTempSumType;
 
 
// Die Struktur, in der die Daten zwischengespeichert werden
 
typedef struct
 
{
 
tFloatAvgType aData[SIZE_OF_AVG];
 
uint8_t IndexNextValue;
 
} tFloatAvgFilter;
 
 
 
// Initialisiert das Filter mit einem Startwert.
 
void InitFloatAvg(tFloatAvgFilter * io_pFloatAvgFilter,
 
  tFloatAvgType i_DefaultValue);
 
 
// Schreibt einen neuen Wert in das Filter.
 
void AddToFloatAvg(tFloatAvgFilter * io_pFloatAvgFilter,
 
  tFloatAvgType i_ui16NewValue);
 
 
// Berechnet den Durchschnitt aus den letzten SIZE_OF_AVG eingetragenen Werten.
 
tFloatAvgType GetOutputValue(tFloatAvgFilter * io_pFloatAvgFilter);
 
 
#endif
 
</pre>
 
  
  
 
=== Quellcode ===
 
=== Quellcode ===
 
;FloatingAverage.c
 
;FloatingAverage.c
<pre>
+
#include "FloatingAverage.h"
+
#include "FloatingAverage.h"
 +
 +
void InitFloatAvg(tFloatAvgFilter * io_pFloatAvgFilter,
 +
  tFloatAvgType i_DefaultValue)
 +
{
 +
  {{ccomment|Den Buffer mit dem Initialisierungswert fuellen:}}
 +
for (uint8_t i = 0; i < SIZE_OF_AVG; ++i)
 +
{
 +
io_pFloatAvgFilter->aData[i] = i_DefaultValue;
 +
}
 +
{{ccomment|Der naechste Wert soll an den Anfang des Buffers geschrieben werden:}}
 +
io_pFloatAvgFilter->IndexNextValue = 0;
 +
}
 +
 +
 +
void AddToFloatAvg(tFloatAvgFilter * io_pFloatAvgFilter,
 +
  tFloatAvgType i_NewValue)
 +
{
 +
{{ccomment|Neuen Wert an die dafuer vorgesehene Position im Buffer schreiben.}}
 +
io_pFloatAvgFilter->aData[io_pFloatAvgFilter->IndexNextValue] =
 +
i_NewValue;
 +
{{ccomment|Der naechste Wert wird dann an die Position dahinter geschrieben.}}
 +
io_pFloatAvgFilter->IndexNextValue++;
 +
{{ccomment|Wenn man hinten angekommen ist, vorne wieder anfangen.}}
 +
io_pFloatAvgFilter->IndexNextValue %= SIZE_OF_AVG;
 +
 +
 +
 +
tFloatAvgType GetOutputValue(tFloatAvgFilter * io_pFloatAvgFilter)
 +
{
 +
tTempSumType TempSum = 0;
 +
{{ccomment|Durchschnitt berechnen}}
 +
for (uint8_t i = 0; i < SIZE_OF_AVG; ++i)
 +
{
 +
TempSum += io_pFloatAvgFilter->aData[i];
 +
}
 +
{{ccomment|Der cast is OK, wenn tFloatAvgType und tTempSumType korrekt gewaehlt wurden.}}
 +
tFloatAvgType o_Result = (tFloatAvgType) (TempSum / SIZE_OF_AVG);
 +
return o_Result;
 +
}
  
void InitFloatAvg(tFloatAvgFilter * io_pFloatAvgFilter,
 
  tFloatAvgType i_DefaultValue)
 
{
 
// Den Buffer mit dem Initialisierungswert fuellen:
 
for (uint8_t i = 0; i < SIZE_OF_AVG; ++i)
 
{
 
io_pFloatAvgFilter->aData[i] = i_DefaultValue;
 
}
 
// Der naechste Wert soll an den Anfang des Buffers geschrieben werden:
 
io_pFloatAvgFilter->IndexNextValue = 0;
 
}
 
 
 
void AddToFloatAvg(tFloatAvgFilter * io_pFloatAvgFilter,
 
  tFloatAvgType i_NewValue)
 
{
 
// Neuen Wert an die dafuer vorgesehene Position im Buffer schreiben.
 
io_pFloatAvgFilter->aData[io_pFloatAvgFilter->IndexNextValue] =
 
i_NewValue;
 
// Der naechste Wert wird dann an die Position dahinter geschrieben.
 
io_pFloatAvgFilter->IndexNextValue++;
 
// Wenn man hinten angekommen ist, vorne wieder anfangen.
 
io_pFloatAvgFilter->IndexNextValue %= SIZE_OF_AVG;
 
}
 
 
 
tFloatAvgType GetOutputValue(tFloatAvgFilter * io_pFloatAvgFilter)
 
{
 
tTempSumType TempSum = 0;
 
// Durchschnitt berechnen
 
for (uint8_t i = 0; i < SIZE_OF_AVG; ++i)
 
{
 
TempSum += io_pFloatAvgFilter->aData[i];
 
}
 
// Der cast is OK, wenn tFloatAvgType und tTempSumType korrekt gewaehlt wurden.
 
tFloatAvgType o_Result = (tFloatAvgType) (TempSum / SIZE_OF_AVG);
 
return o_Result;
 
}
 
</pre>
 
  
  
 
=== Anwendungsbeispiel ===
 
=== Anwendungsbeispiel ===
 
Hier folgt ein Beispiel, das die Anwendung in einem PC-Konsolen-Programm demonstriert
 
Hier folgt ein Beispiel, das die Anwendung in einem PC-Konsolen-Programm demonstriert
<pre>
 
 
#include <stdio.h>
 
#include "FloatingAverage.h"
 
 
int main(void)
 
{
 
        //Datenstruktur anlegen:
 
        tFloatAvgFilter FilterVoltageBatt;
 
 
        // initialisieren und mit 0 fuellen)
 
        InitFloatAvg(&FilterVoltageBatt, 0);
 
 
        AddToFloatAvg(&FilterVoltageBatt, 100);
 
        // jetzt steht 1 mal 100 und 7 mal 0 im Buffer:
 
        printf("100/8 = %d\n", GetOutputValue(&FilterVoltageBatt));
 
  
        AddToFloatAvg(&FilterVoltageBatt, 200);
 
        // jetzt steht 1 mal 100, 1 mal 200 und 6 mal 0 im Buffer:
 
        printf("300/8 = %d\n", GetOutputValue(&FilterVoltageBatt));
 
  
        AddToFloatAvg(&FilterVoltageBatt, 300);
+
#include <stdio.h>
        AddToFloatAvg(&FilterVoltageBatt, 200);
+
#include "FloatingAverage.h"
        // jetzt steht 1 mal 100, 2 mal 200, 1 mal 300 und 4 mal 0 im Buffer:
+
        printf("800/8 = %d\n", GetOutputValue(&FilterVoltageBatt));
+
int main(void)
 +
{
 +
        {{ccomment|Datenstruktur anlegen:}}
 +
        tFloatAvgFilter FilterVoltageBatt;
 +
 +
        {{ccomment|initialisieren und mit 0 fuellen}}
 +
        InitFloatAvg(&FilterVoltageBatt, 0);
 +
 +
        AddToFloatAvg(&FilterVoltageBatt, 100);
 +
        {{ccomment|jetzt steht 1 mal 100 und 7 mal 0 im Buffer:}}
 +
        printf("100/8 = %d\n", GetOutputValue(&FilterVoltageBatt));
 +
 +
        AddToFloatAvg(&FilterVoltageBatt, 200);
 +
        {{ccomment|jetzt steht 1 mal 100, 1 mal 200 und 6 mal 0 im Buffer:}}
 +
        printf("300/8 = %d\n", GetOutputValue(&FilterVoltageBatt));
 +
 +
        AddToFloatAvg(&FilterVoltageBatt, 300);
 +
        AddToFloatAvg(&FilterVoltageBatt, 200);
 +
        {{ccomment|jetzt steht 1 mal 100, 2 mal 200, 1 mal 300 und 4 mal 0 im Buffer:}}
 +
        printf("800/8 = %d\n", GetOutputValue(&FilterVoltageBatt));
 +
 +
        return 0;
 +
}
  
        return 0;
 
}
 
</pre>
 
  
 
[[Kategorie:Quellcode C]]
 
[[Kategorie:Quellcode C]]

Version vom 5. November 2009, 11:25 Uhr

Dieser Artikel ist noch lange nicht vollständig. Der Auto/Initiator hofft das sich weitere User am Ausbau des Artikels beteiligen.

Das Ergänzen ist also ausdrücklich gewünscht! Besonders folgende Dinge würden noch fehlen:

viel mehr erklärender Text


Verwendung

Um beispielsweise verrauschte Messwerte zu glätten, wird häufig der Mittelwert über die letzten gemessenen Werte gebildet. Details dazu hier: [1]

C-Code

Auf Optimierungen, inline-Funktionen etc. wurde vorerst zugunsten der Lesbarkeit verzichtet.

Header

FloatingAverage.h
#ifndef FLOATING_AVERAGE_H
#define FLOATING_AVERAGE_H

#include <inttypes.h>

// Ueber wieviele Werte soll der gleitende Mittelwert berechnet werden?
// Zulaessige Werte 1..255
#define SIZE_OF_AVG  8

// Datentyp, ueber den der gleitende Mittelwert berechnet werden soll.
typedef uint16_t tFloatAvgType;
// typedef float tFloatAvgType;

// Wird nur intern fuer die Durchschnittsberechnung benutzt.
// Muss Zahlen fassen koennen, die SIZE_OF_AVG mal groesser als tFloatAvgType sind.
typedef uint32_t tTempSumType;
// typedef float tTempSumType;

// Die Struktur, in der die Daten zwischengespeichert werden
typedef struct
 {
	tFloatAvgType aData[SIZE_OF_AVG];
	uint8_t IndexNextValue;
 } tFloatAvgFilter;


// Initialisiert das Filter mit einem Startwert.
void InitFloatAvg(tFloatAvgFilter * io_pFloatAvgFilter,
		  tFloatAvgType i_DefaultValue);

// Schreibt einen neuen Wert in das Filter.
void AddToFloatAvg(tFloatAvgFilter * io_pFloatAvgFilter,
		   tFloatAvgType i_ui16NewValue);

// Berechnet den Durchschnitt aus den letzten SIZE_OF_AVG eingetragenen Werten.
tFloatAvgType GetOutputValue(tFloatAvgFilter * io_pFloatAvgFilter);

#endif


Quellcode

FloatingAverage.c
#include "FloatingAverage.h"

void InitFloatAvg(tFloatAvgFilter * io_pFloatAvgFilter, 
		  tFloatAvgType i_DefaultValue)
{ 
 	// Den Buffer mit dem Initialisierungswert fuellen:
	for (uint8_t i = 0; i < SIZE_OF_AVG; ++i)
	{
		io_pFloatAvgFilter->aData[i] = i_DefaultValue;
	}
	// Der naechste Wert soll an den Anfang des Buffers geschrieben werden:
	io_pFloatAvgFilter->IndexNextValue = 0;
} 


void AddToFloatAvg(tFloatAvgFilter * io_pFloatAvgFilter,
		   tFloatAvgType i_NewValue)
{ 
	// Neuen Wert an die dafuer vorgesehene Position im Buffer schreiben.
	io_pFloatAvgFilter->aData[io_pFloatAvgFilter->IndexNextValue] =
		i_NewValue;
	// Der naechste Wert wird dann an die Position dahinter geschrieben.
	io_pFloatAvgFilter->IndexNextValue++;
	// Wenn man hinten angekommen ist, vorne wieder anfangen.
	io_pFloatAvgFilter->IndexNextValue %= SIZE_OF_AVG;
}  


tFloatAvgType GetOutputValue(tFloatAvgFilter * io_pFloatAvgFilter)
{
	tTempSumType TempSum = 0;
	// Durchschnitt berechnen
	for (uint8_t i = 0; i < SIZE_OF_AVG; ++i)
	{
		TempSum += io_pFloatAvgFilter->aData[i];
	}
	// Der cast is OK, wenn tFloatAvgType und tTempSumType korrekt gewaehlt wurden.
	tFloatAvgType o_Result = (tFloatAvgType) (TempSum / SIZE_OF_AVG);
	return o_Result;
}


Anwendungsbeispiel

Hier folgt ein Beispiel, das die Anwendung in einem PC-Konsolen-Programm demonstriert


#include <stdio.h>
#include "FloatingAverage.h"

int main(void)
{
        // Datenstruktur anlegen:
        tFloatAvgFilter FilterVoltageBatt;

        // initialisieren und mit 0 fuellen
        InitFloatAvg(&FilterVoltageBatt, 0);

        AddToFloatAvg(&FilterVoltageBatt, 100);
        // jetzt steht 1 mal 100 und 7 mal 0 im Buffer:
        printf("100/8 = %d\n", GetOutputValue(&FilterVoltageBatt));

        AddToFloatAvg(&FilterVoltageBatt, 200);
        // jetzt steht 1 mal 100, 1 mal 200 und 6 mal 0 im Buffer:
        printf("300/8 = %d\n", GetOutputValue(&FilterVoltageBatt));

        AddToFloatAvg(&FilterVoltageBatt, 300);
        AddToFloatAvg(&FilterVoltageBatt, 200);
        // jetzt steht 1 mal 100, 2 mal 200, 1 mal 300 und 4 mal 0 im Buffer:
        printf("800/8 = %d\n", GetOutputValue(&FilterVoltageBatt));

        return 0;
}

LiFePO4 Speicher Test