Aus RN-Wissen.de
Version vom 5. November 2009, 11:25 Uhr von Williwilli (Diskussion | Beiträge) (Layout verändert, Kommentare gefärbt)

Wechseln zu: Navigation, Suche
LiFePO4 Speicher Test

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