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

Gast #4678738
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
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
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.
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
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);
Reinhard M. schrieb:
> Der Original C++ Code lässt sich problemlos compileren.
>
> Vermutlich gibt es bei der C- Implementierung eine
> struct BABYBEFilter o.ähnlich.

Nicht nur vermutlich. Diese Struktur ist in der automatisch generierten 
Datei BABYBEFilter.h definiert. Die Header- und die C-Datei bekommt man 
von der oben genannten Website erstellt.
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
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.
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
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
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
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
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

Eine eigene Frage? Dieser Thread ist über 10 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.