Implementieren Filter in C von http://t-filter.appspot.com

Gast #4678738
Lesenswert?

Hallo Zusammen

grad dabei den Filter von http://t-filter.appspot.com
in mein uC Programm zu implementieren.

Ich habe Probleme die Funktionen in double MM_FILTER ordentlich 
aufzurufen und die Funktions Parameter zu übertragen bzw zu lesen. 
Jedenfalls meine Compiler will das nicht compilieren


daweilst lese ich meine C Bücher...
1
C-Code
2
void BABYBEFilter_init(BABYBEFilter* f) {
3
  int i;
4
  for(i = 0; i < BABYBEFILTER_TAP_NUM; ++i)
5
    f->history[i] = 0;
6
  f->last_index = 0;
7
}
8

9
void BABYBEFilter_put(BABYBEFilter* f, double input) {
10
  f->history[f->last_index++] = input;
11
  if(f->last_index == BABYBEFILTER_TAP_NUM)
12
    f->last_index = 0;
13
}
14

15
double BABYBEFilter_get(BABYBEFilter* f) {
16
  double acc = 0;
17
  int index = f->last_index, i;
18
  for(i = 0; i < BABYBEFILTER_TAP_NUM; ++i) {
19
    index = index != 0 ? index-1 : BABYBEFILTER_TAP_NUM-1;
20
    acc += f->history[index] * filter_taps[i];
21
  };
22
  return acc;
23
}    
24

25
      
26
double MM_FILTER ( double SENSOR) // Lowpass http://t-filter.engineerjs.com/
27
{
28

29
 //BABYBEFilter_put(&BABYBEFilter,SENSOR);  //Mein Versuch
30

31
//BABYBEFilter_get(&BABYBEFilter,SENSOR);//Mein Versuch
32

33
return SENSOR;
34

35
      };
Gast #4678740
Lesenswert?

Magst Du vielleicht auch noch die Fehlermeldungen des C-Compilers 
reinkopieren?

Und btw., ist double wirklich nötig? Selbst wenn Dein Controller eine 
FPU hat (wie Cortex-M4 etwa), dann kann die auch nur float, und double 
in Software ist schon arg langsam.
Gast #4678745
Lesenswert?

Was mir auch so schon auffällt, worüber ich als Compiler meckern würde:

Einerseits hast Du:
void BABYBEFilter_init(BABYBEFilter* f)

Dann versuchst Du:
BABYBEFilter_put(&BABYBEFilter,SENSOR);

Das Problem ist, daß BABYBEFilter oben ein Datentyp ist, während Du das 
unten als Variable gebrauchen willst. Das kann nicht gehen.

Zweitens benutzt Du in MM_FILTER die Eingabe SENSOR zwar als Paramater 
für die beiden Filter-Aufrufe, Dein return-Wert ist aber einfach SENSOR. 
MM_FILTER wird also einfach den Wert zurückgeben, den sie erhalten hat, 
also eine Identitätsfunktion.
#4678981
Lesenswert?

Nop schrieb:
> Zweitens benutzt Du in MM_FILTER die Eingabe SENSOR zwar als Paramater
> für die beiden Filter-Aufrufe, Dein return-Wert ist aber einfach SENSOR.
> MM_FILTER wird also einfach den Wert zurückgeben, den sie erhalten hat,
> also eine Identitätsfunktion.

Naja die zwei auskommentierten Zeilen werden nicht kompiliert haben. 
Deswegen sind sie wohl auskommentiert ;-)
Gast #4679306
Lesenswert?

Der Original C++ Code lässt sich problemlos compileren.

Vermutlich gibt es bei der C- Implementierung eine
struct BABYBEFilter o.ähnlich.

Ohne Kenntnis darüber, bleibt nur die Glaskugel.

Aber einfach mal geraten:

BABYBEFilter_put(&f,SENSOR);
#4679485
Lesenswert?

So klappt es  besser:
1.) Im eigenen Code die autogenerierte Header-Datei einbinden.
2.) Im eigenen Code Speicher für das Filter anlegen.
3.) Danach die verschiedenen Funktionen aufrufen. Siehe Beispiel.

1
#include "BABYBEFilter.h"
2
#include <stdio.h>
3

4
int main()
5
{
6
    BABYBEFilter filter1;
7
    
8
    BABYBEFilter_init(&filter1);
9
    
10
    BABYBEFilter_put(&filter1, 2.0);
11
    
12
    double filtered_value = BABYBEFilter_get(&filter1);
13
    printf("Filtered value: %f\n", filtered_value);
14
    
15
    return 0;
16
}
Gast #4680318
Lesenswert?

Raph schrieb:
> daweilst lese ich meine C Bücher...

Naja, lies lieber dort: "http://www.dspguide.com/";
Das Ganze gibt's auch als PDF zum Herunterladen.

Ich hab vergeblich versucht, in deinem Geposteten irgend einen Sinn zu 
erkennen. Gleiches gilt für die genannte Internet-Seite. Hab dort mal 
versucht, einen Bandpaß für 100 Hz .. 2.7 kHz bei 44.1 kHz Samplerate 
einzugeben - geht nicht.

Was für ein Filter soll das eigentlich werden?
Mein Vorschlag wäre ein FIR Filter und den Filterkernel als sin(x)/x mit 
anschließendem Blackman-Fenster. Das geht leicht, auch in C - und es 
liefert ne ordentlich glatte Durchlaßkurve.

Rezept für Bandpaß:
- ersten Tiefpaß für untere Eckfrequenz berechnen, Blackman applizieren
- zweiten Tiefpaß für obere Eckfrequenz berechnen, Blackman applizieren
- beide Tiefpässe normieren
- Spektralinversion auf zweiten Tiefpaß
- beide Tiefpässe addieren, ergibt Bandsperre
- Spektralinversion auf resultierende Bandsperre, ergibt Bandpaß.
- fertig.

W.S.
#4680394
Lesenswert?

Moin,

W.S. schrieb:
> Mein Vorschlag wäre ein FIR Filter und den Filterkernel als sin(x)/x mit
> anschließendem Blackman-Fenster. Das geht leicht, auch in C - und es
> liefert ne ordentlich glatte Durchlaßkurve.

Wenn man nur einen Hammer hat, sehen alle Probleme aus wie Naegel :-)


Raph schrieb:
> Ist keine DSP Problem sondern eine C Sache über Funktions Überageb und
> Structs.

Warum postest du dann im DSP-Unterforum und nicht unter:

"PC-Programmierung
Programmierung auf PCs, Algorithmen, allgemeine Programmierfragen ohne 
direkten Mikrocontroller-Bezug."?

Unn? Watissnu? Geht jetzt dein lustiges C-Programm? Woran hings?


Gruss
WK
Gast #4680770
Lesenswert?

Dergute W. schrieb:
> Wenn man nur einen Hammer hat, sehen alle Probleme aus wie Naegel :-)

Nö.

Der TO will ein Filter selber programmieren und hat sich dazu auf eine 
Inet-Seite eingelassen, die mir ausgesprochen seltsam und nicht 
zielführend zu sein scheint.

Anstatt hier über C-Probleme mit einer Breitseite irgendwelcher 
"Baby"-Filter-Funktionen zu diskutieren, halte ich es für eher 
angebracht, mal den tieferen Sinn und Zweck der Übung kundzutun. Auf 
diesem Wege käme man der Lösung des Problems möglicherweise eher näher - 
oder?

W.S.
Gast #4680778
Lesenswert?

W.S. schrieb:

> Der TO will ein Filter selber programmieren und hat sich dazu auf eine
> Inet-Seite eingelassen, die mir ausgesprochen seltsam und nicht
> zielführend zu sein scheint.

Wieso? Auf der Seite brauch man nur die Eckdaten eines Filters angeben. 
Danach kann der komplette C-Code kann heruntergeladen werden. Dann nur 
noch kompilieren. Fertig.
Gast #4680829
Lesenswert?

Ich werde Troll sachen erst gar nicht durchlesen.

F ist wohl Zeiger auf die Structur BABYBEFilter

der richtige Syntax ist mir noch nicht ganz klar beim Aufruf


(
1
#ifndef BABYBEFILTER_H_
2
#define BABYBEFILTER_H_
3

4
/*
5

6
FIR filter designed with
7
 http://t-filter.appspot.com
8

9
sampling frequency: 2000 Hz
10

11
* 0 Hz - 400 Hz
12
  gain = 1
13
  desired ripple = 5 dB
14
  actual ripple = 4.1393894966071585 dB
15

16
* 500 Hz - 1000 Hz
17
  gain = 0
18
  desired attenuation = -40 dB
19
  actual attenuation = -40.07355419274887 dB
20

21
*/
22

23
#define BABYBEFILTER_TAP_NUM 21
24

25
typedef struct {
26
  double history[BABYBEFILTER_TAP_NUM];
27
  unsigned int last_index;
28
} BABYBEFilter;
29

30
void BABYBEFilter_init(BABYBEFilter* f);
31
void BABYBEFilter_put(BABYBEFilter* f, double input);
32
double BABYBEFilter_get(BABYBEFilter* f);
33

34
#endif
35

36
C-Code
#4681323
Lesenswert?

Raph schrieb:
> Ich werde Troll sachen erst gar nicht durchlesen.
>
> F ist wohl Zeiger auf die Structur BABYBEFilter
>
> der richtige Syntax ist mir noch nicht ganz klar beim Aufruf

Eine Möglichkeit für Deklaration und Aufrufe habe ich doch in diesem 
Thread gepostet. Was daran hast Du nicht verstanden?

Wenn Du hier keine "Troll sachen" lesen willst, dann solltest Du 
vielleicht mal damit anfangen, selbst nicht wie ein Troll zu schreiben.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren