Sida 6 av 6

Re: Lågpassfilter i mjukvara!

Postat: 3 maj 2011, 22:52:39
av jesse
jag hoppades att snigelen skull tända på idén och presentera färdiga kurvor här så jag slipper :D

Re: Lågpassfilter i mjukvara!

Postat: 3 maj 2011, 23:08:49
av snigelen
Nja z-plan och så var väl kanske inte nödvändigt att dra in, jag bara tänkte att det skulle bli ett lite bättre filter med min modifikation, men fortfarande enkelt. Annars är det med hjälp av Z-transformen man hamnar i z-planet, det är väl ungefär den tids-diskreta mosvarigheten till Laplace-transformen.

Lägger du till flera gamla insignaler så blir det väl fortfarande LP-filter, men det går mer och mer mot ett kam-filter (tror jag) som blockar flera jämnt utspridda frekvenser. Men då finns det väl bättre sätt att göra högre ordningens LP-filter. Men inte lika enkelt som detta...

Re: Lågpassfilter i mjukvara!

Postat: 24 juli 2011, 13:43:22
av Icecap
Nu har jag lekt lite med detta rent praktisk och jag är mycket nöjd!

Det mynnade ut i denna fil:
/*----------------------*/
/* File: Low_Pass_100.h */
/* Date: 20110711 */
/* ---------------------*/

/* How to use this software low pass filter: */
/* - Incoming is the value to be filtered. */
/* - Intermediate is a static value, one location for each different value to filter */
/* - Return value is the normalized filtered value. */
/* - Shifts is the number of shifts to do, high number means slower rise */
/* - With a suitable randomness in the input signal extra bits can be extracted from the Intermediate-value */

int Low_Pass(int * Incoming, long * Intermediate, int Shifts)
{
*Intermediate = (*Intermediate - (*Intermediate >> Shifts)) + *Incoming;
return(*Intermediate >> Shifts);
}

Jag har testat att använda denna rutin till lite olika saker i ett projekt och jag fick lite bättre värden än med det förra sätt men det gick åt en del mindre programplats. Jag är mycket glad för att detta blev lagt in, tack Jesse.

Re: Lågpassfilter i mjukvara!

Postat: 24 juli 2011, 14:34:08
av Korken
Mycket bra filter! :tumupp:

Re: Lågpassfilter i mjukvara!

Postat: 24 juli 2011, 15:24:25
av jesse
Kul att nån har glädje av det! :)

>jag fick lite bättre värden än med det förra

hmm... är de inte identiska i funktionen, men att du använder pekare istället för vanliga variabler?

Originalkod:

Kod: Markera allt

filter_reg =  filter_reg  -   ( filter_reg >> FILTER_SHIFT)  +  filter_input ;
output  =  filter_reg >> FILTER_SHIFT
Varför måste du skicka med intermediate som argument i varje anrop? kan du inte ha den som en statisk variabel inuti funktionen? Och Shifts kan ju (oftast) vara en kostant lagrad i en macro:

Kod: Markera allt

#define SHIFTS 8
int Low_Pass(int * Incoming)
{
static  long Intermediate = START_VALUE;
Intermediate = (Intermediate - (Intermediate >> SHIFTS)) + *Incoming;
return(Intermediate >> SHIFTS);
}

Re: Lågpassfilter i mjukvara!

Postat: 24 juli 2011, 15:35:28
av Icecap
"Med det förra" var bristfälligt skrivit, det skulle nog stå "med det sätt jag gjorde förut" för att det skulle vara korrekt.

Och jag kan INTE ha Intermediate som en static i funktionen, jag använder samma filter på 8 kanaler fast med lite olika shift-steg, därav pekarna.

Jag använder samma rutin till att filtrera 7 kanaler direkt från AD-omvandlaren med relativt låga värden på shift, sedan använder jag den till att "rensa" lambda-värdet och då är det med ett ganska högt shift-värde vilket ger trögheten jag vill ha.

Re: Lågpassfilter i mjukvara!

Postat: 24 juli 2011, 15:38:25
av jesse
>Och jag kan INTE ha Intermediate som en static i funktionen, jag använder samma filter på 8 kanaler fast med lite olika shift-steg, därav pekarna.

Ah, visst ja. :doh:

Själv kör jag samma filter på 96 ADC-kanaler parallellt, och då pekar pekarna direkt till en array. jag skickar bara ADC-kanalens nummer som argument, så hittar den själv indata, utdata och "intermediate"-data.

Re: Lågpassfilter i mjukvara!

Postat: 24 juli 2011, 15:42:47
av Icecap
Jag testade att ha funktionen direkt i AD-ISN'n innan jag lade ut den i egen fil och jag testade att kompilera båda versioner.

Det visade sig att versionen med pekare var programmet kännbart mindre, sannolikt för att den inte ska räkna index vid båda läsa o skriva - fler gångar. Med färre programsteg bör programmet gå lite snabbare också och det gillar jag!

Re: Lågpassfilter i mjukvara!

Postat: 16 maj 2014, 11:38:09
av bearing
Med bakgrund av mitt inlägg i Lågpassfilter i C-kod, tänkte jag att jag kan uppdatera den här tråden också.

Jag har kommit på att man kan göra filtret lite snabbare enbart genom att stuva om, samt deklarera en extra static:

Kod: Markera allt

//FILTER_SHIFTS = log2(RC_constant * calls_per_second)
#define FILTER_SHIFTS 10
uint16_t low_pass_filter(uint16_t input)
{
  static uint16_t output;
  static uint32_t intermediate;

  intermediate -= output;
  intermediate += input;

  output = intermediate >> FILTER_SHIFTS;

  return output;
}
Nu behövs bara en skiftoperation, istället för två.
(Har inte kompilerat koden)

Vet inte om det stod tidigare i tråden, men jag har iaf förstått hur såna här filter beter sig jämfört med ett vanligt RC-filter. Filtrets svar påverkas av hur ofta filterfunktionen körs, vilket kanske inte är helt självklart från början. Om man önskar att filtret ska motsvara ett RC-filter, samt vet hur ofta filterfunktionen körs, kan man räkna ut hur många skiftningar som behövs, med hjälp av log2. (Om din miniräknare saknar log2 kan du istället använda log10 eller naturliga logaritmen (ln), såhär:
//FILTER_SHIFTS = ln(RC_constant * calls_per_second) / ln(2)

Re: Lågpassfilter i mjukvara!

Postat: 16 maj 2014, 12:35:09
av jesse
Mycket bra :bravo:

Formeln var trevlig att få. Hade säkert kunnat räkna ut den själv, men det har aldrig blivit av.
Den kommer jag att ha nytta av!

Re: Lågpassfilter i mjukvara!

Postat: 16 maj 2014, 13:26:56
av Andax
Intressant kod. Dock bör man väl initiera static variablerna.
Hur blir det eftersom man trunkerar intermediate när man tilldelar output. Kan det bli konstiga effekter att intermediate driver?
Ska se om jag har tid att testa för det är ju definitivt en kompakt och effektiv lösning.

Re: Lågpassfilter i mjukvara!

Postat: 16 maj 2014, 13:56:00
av bearing
Ja, det kan man göra. Var inte menat som komplett kod. Jag brukar ibland deklarera intermediate utanför funktionen, och initiera till min första input << FILTER_SHIFTS. output borde man också initiera - till input, men det har jag inte tänkt på tidigare.

EDIT: angående att intermediate driver förstår jag inte riktigt vad du menar?
Om man ändrar till return intermediate; i slutet, för att få en förstärkning, kommer intermediate fastna på slumpvärdet ifall input och output är 0.