Filter library test

Hello, I changed the code now as recommended:

 // Arduino Signal Filtering an time measurement for Analog Read and Filter


// Arduino Signal Filtering Library
// Copyright 2012-2013 Jeroen Doggen (jeroendoggen@gmail.com)
//http://jeroendoggen.github.io/Arduino-signal-filtering-library/
//http://www.schwietering.com/jayduino/filtuino/


/*
SimPlot Demo
 
Samples Analog Input and sends them over serial port to be plotted in SimPlot.
This Demo software uses the default serial port "Serial".
Upto to 4 channels of data can be plotted.

For details of SimPlot go to
www.negtronics.com/simplot
http://www.negtronics.com/simplot/simplot-code-samples/plot-analog-input-data
 */



#include <SignalFilter.h>

SignalFilter Filter;


unsigned long time_start;
unsigned long time_sampl;
unsigned long time_plot;

int buffer[20]; //Buffer needed to store data packet for transmission
int data1;
int data2;
//int data3;
//int data4;

int incomingByte = 0;




void setup()
{
  Serial.begin(57600);
  Filter.begin();
  Filter.setFilter('c');
  Filter.setOrder(2);
}


void loop()
{


  
   time_start = micros();              //time measurement 
   data1 = analogRead(0);              //for analog 0
   data2 = Filter.run(data1);          // for filter calculation
   time_sampl = micros() - time_start; //time measurement 
  
  
  // time_start = micros();              //time measurement 
  // plot(data1,data2);                   //Plots 2 channels of data
 //  time_plot = micros() - time_start; //time measurement 
  
  
  
  //Read Analog channels. You can connect accelerometer, gyro, temperature sensor etc to these channels
  //I delete the second analogRead and substitute them with the filtered signal 
  data1 = analogRead(0);
  data2= Filter.run(data1);
  // data3 = analogRead(2);
 // data4 = analogRead(3);
 
  //You can plot upto 4 channels of data. Uncomment only one of the options below
 
//   plot(data1,data2,data3,data4);   //Plots 4 channels of data
 // plot(data1,data2,data3);      //Plots 3 channels of data
// plot(data1,data2);            //Plots 2 channels of data
  // plot(data1);                  //Plots 1 channel of data
 
  //delay(1); //Read and plot analog inputs every 1ms. 
  
  

  if (Serial.available() > 0) {
    incomingByte = Serial.read();
    if (incomingByte == 'm') {             // press m and read time in microsec for Filter.run(data1)
      Serial.println(time_sampl, DEC);
        }
      }
   /*   
    if (Serial.available() > 0) {
    incomingByte = Serial.read();
    if (incomingByte == 'n') {             // press n and read time in microsec for plot(data1,data2)
      Serial.println(time_plot, DEC);
        }
      }*/
   
}




 /*
//Function that takes 4 integer values and generates a packet to be sent to SimPlot.
void plot(int data1, int data2, int data3, int data4) 
{
  int pktSize;
 
  buffer[0] = 0xCDAB;             //SimPlot packet header. Indicates start of data packet
  buffer[1] = 4*sizeof(int);      //Size of data in bytes. Does not include the header and size fields
  buffer[2] = data1;
  buffer[3] = data2;
  buffer[4] = data3;
  buffer[5] = data4;
   
  pktSize = 2 + 2 + (4*sizeof(int)); //Header bytes + size field bytes + data
 
  //IMPORTANT: Change to serial port that is connected to PC
  Serial.write((uint8_t * )buffer, pktSize);
}

//Function that takes 3 integer values and generates a packet to be sent to SimPlot.
void plot(int data1, int data2, int data3)
{
  int pktSize;
 
  buffer[0] = 0xCDAB;             //SimPlot packet header. Indicates start of data packet
  buffer[1] = 3*sizeof(int);      //Size of data in bytes. Does not include the header and size fields
  buffer[2] = data1;
  buffer[3] = data2;
  buffer[4] = data3;
   
  pktSize = 2 + 2 + (3*sizeof(int)); //Header bytes + size field bytes + data
 
  //IMPORTANT: Change to serial port that is connected to PC
  Serial.write((uint8_t * )buffer, pktSize);
}  */
/*
//Function that takes 2 integer values and generates a packet to be sent to SimPlot.
void plot(int data1, int data2)
 
 {
  int pktSize;
 
  buffer[0] = 0xCDAB;             //SimPlot packet header. Indicates start of data packet
  buffer[1] = 2*sizeof(int);      //Size of data in bytes. Does not include the header and size fields
  buffer[2] = data1;
  buffer[3] = data2;
   
  pktSize = 2 + 2 + (2*sizeof(int)); //Header bytes + size field bytes + data
 
  //IMPORTANT: Change to serial port that is connected to PC
  Serial.write((uint8_t * )buffer, pktSize);
}   */


 /*
//Function that takes 1 integer value and generates a packet to be sent to SimPlot.
void plot(int data1)
{
  int pktSize;
 
  buffer[0] = 0xCDAB;             //SimPlot packet header. Indicates start of data packet
  buffer[1] = 1*sizeof(int);      //Size of data in bytes. Does not include the header and size fields
  buffer[2] = data1;
   
  pktSize = 2 + 2 + (1*sizeof(int)); //Header bytes + size field bytes + data
 
  //IMPORTANT: Change to serial port that is connected to PC
  Serial.write((uint8_t * )buffer, pktSize);
}   */

I hope I didnt make big errors! Explanation: Only when I enter and send “m” (in serial monitor window) I get time measurement for “AnalogIn0” and “Filter.run(data1);”. It gives me 172usec (attachment: Time_mes_plotoff). So theoretically I have a sample rate of 5.814Hz. I tried also to measure the time for „plot(data1,data2)“, but its unreadable, because of all other symbols in the serial monitor window, read from real time plotting orders (attachment: Time_mes_ploton).
The thing is that I used the real-time-plot only to check if the filter works accurately. Maybe the right description of the problem I have now is the Heisenbug. Wikipedia: “Heisenbugs occur because common attempts to debug a program, such as inserting output statements or running it in a debugger, usually modify the code, change the memory addresses of variables and the timing of its execution.”
In my end project I wouldn`t need the real-time-plot anymore. I want only that a LED switches on when a tone with a certain threshold (amplitude) passes the bandpassfilter. Maybe does it be also a good way to check if the filter library works fine? So with my lowpassfilter (cutoff frequency 300Hz) the LED should be shine until 300Hz and switched off with all frequencies above 300Hz.
Or do you know other, maybe more accurate methods to test the filters?

Or do you know other, maybe more accurate methods to test the filters?

I'd create a big array, 256 or 512 values to store results of the filtering. Like in your initial setup, you feed a sinewave, arduino filterring data and store them to an array. You printing results by request whenever you change input, or like to observe a process.

I checked a library, and author's copy has this:

  if(_order==2) {                                 //ripple -1dB
    _v[0] = _v[1];
    _v[1] = _v[2];
    long tmp = ((((data * 662828L) >>  4)         //= (    7.901529699e-2 * x)
      + ((_v[0] * -540791L) >> 1)                 //+( -0.5157387562*v[0])
      + (_v[1] * 628977L)                         //+(  1.1996775682*v[1])
      )+262144) >> 19;                            // round and downshift fixed point /524288

    _v[2]= (int)tmp;
    return (int)((
      (_v[0] + _v[2])
      +2 * _v[1]));                               // 2^
  }

As you can see, slow float math replaced by integer approximation.
You says:

Then I opened “SignalFilter.cpp” and substitute the Chebyshev Filter of 2nd Order with my new Filter code:
Code:
if(_order==2) {
_v[0] = _v[1];
_v[1] = _v[2];
_v[2] = (4.153748378268e-1 * data)

  • ( -0.4501779675 * _v[0])
  • ( -0.2113213838 * _v[1]);
    return
    (_v[0] + _v[2])
    +2 * _v[1];
    }

Is it code you are testing?

Yes, this was the filter code which I made my first tests. But after I also saw the error. Now I did some tests with this filter:

/// runChebyshev: Low Pass; 2nt Order; cutoff =300Hz; sampling=5000Hz; long type 8bit;
_v[0] = _v[1];
			_v[1] = _v[2];
			long tmp = ((((data * 5342655L) >>  5)	//= (   3.9805879528e-2 * x)
				+ ((_v[0] * -7243194L) >> 2)	//+( -0.4317280064*v[0])
				+ (_v[1] * 5337271L)	//+(  1.2725044883*v[1])
				)+2097152) >> 22; // round and downshift fixed point /4194304

			_v[2]= (short)tmp;
			return (short)((
				 (_v[0] + _v[2])
				+2 * _v[1])); // 2^

I used “long type” whit 8 bit. Without “-1 bit saturation save“.
Are that settings ok?

I have to do more tests but until now it doesn’t work correctly.
Thank you very much for the Idea using a big array for filter validation!

The link to the filter page with my filter settings:
http://www.schwietering.com/jayduino/filtuino/index.php?characteristic=be&passmode=lp&order=2&usesr=usesr&sr=5000&frequencyLow=300&noteLow=&noteHigh=&pw=pw&calctype=long&bitres=8&run=Send

Oh sry, it’s a Bessel filter not a Chebyshev filter but it should work anyway..

Yea, coefficients looks o'k, except I didn't get

I used “long type” whit 8 bit. Without “-1 bit saturation save“.

please check attached picture: :wink:

Hello,
now I wrote a sketch like described in my previous posts.
Switch a LED on if amplitude from filtered signal reaches an arbitrary level:

// Arduino Signal Filtering and LED on if filter amplitude reaches an arbitrary threshold.
// 2014

// Arduino Signal Filtering Library
// Copyright 2012-2013 Jeroen Doggen (jeroendoggen@gmail.com)
//http://jeroendoggen.github.io/Arduino-signal-filtering-library/
//http://www.schwietering.com/jayduino/filtuino/


#include <SignalFilter.h>  // Filter Library
SignalFilter Filter;

//const int analogPin = A0;    // pin that the sensor is attached to
const int ledPin = 13;         // pin that the LED is attached to
const int threshold = 1000;    // an arbitrary threshold level that's in the range of the analog input


unsigned long time_start;    // variable for time measurement start
unsigned long time_sampl;    // variable for time measurement sample


unsigned int data1;      
unsigned int data2;     

int incomingByte = 0;


void setup()
{

  pinMode(ledPin, OUTPUT);     // initialize the LED pin as an output:
  Serial.begin(9600);
  Filter.begin();
  Filter.setFilter('c');       // filter settings: c=Cebycheff  b= Bessel
  Filter.setOrder(2);          // filter settings: order 1 or 2
        
}
/* 
      Filter characteristics are stored in: “SignalFilter.cpp”.
      Current filter settings and code: for “c” “2”

  /// runChebyshev: Low Pass; 2nt Order; cutoff =300Hz; sampling=5000Hz; long type 8bit; 
  “-1bit saturation” enabled;
                        _v[0] = _v[1];
			_v[1] = _v[2];
			long tmp = ((((data * 3009876L) >>  6)	//= (   2.2425325955e-2 * x)
				+ ((_v[0] * -3295982L) >> 1)	//+( -0.7858234574*v[0])
				+ (_v[1] * 3557026L)	//+(  1.6961221536*v[1])
				)+1048576) >> 21; // round and downshift fixed point /2097152

			_v[2]= (short)tmp;
			return (short)((
				 (_v[0] + _v[2])
				+2 * _v[1])); // 2^  
*/


void loop()
{
   
  //Read Analog Input... you can connect accelerometer, gyro, temperature sensor, microphone etc to the channel
  
 // int data1 = analogRead(analogPin);
  data1 = analogRead(0);       //Read Analog channels 
  data2 = Filter.run(data1);   //Read the filtered signal 
 
 
  time_start = micros();               //time measurement 
   data1 = analogRead(0);              // for Analog Pin A0
   data2 = Filter.run(data1);          // for filter calculation
   time_sampl = micros() - time_start; //time measurement math
  
  
  
  if (Serial.available() > 0) {
    incomingByte = Serial.read();
    if (incomingByte == 'm') {         // enter and sent "m" in serial monitor window and read time in microsec for Filter.run(data1) and analog read
    Serial.print("Time Sample = "); 
    Serial.println(time_sampl, DEC);
        }
      }
      
/*
http://arduino.cc/en/Tutorial/IfStatement
the variable called analogValue is used to store the data collected from a Analog Pin A0. 
This data is then compared to a threshold value. 
If the analog value is found to be above the set threshold the LED connected to digital pin 13 is turned on. 
If analogValue is found to be < threshold, the LED remains off. */
      
      // read the value of the microphone:
      // int analogValue = analogRead(analogPin);

  // if the filter value is high enough, turn on the LED:
  if (data2 > threshold) {
    digitalWrite(ledPin, HIGH);
  }
  else {
    digitalWrite(ledPin,LOW);
  }
      
   // print the analog value:
   // Serial.print("In: ");
   // Serial.print(data1);
   // Serial.print(" - Out: ");
   // Serial.println(data2);
   // delay(500);        // delay in between reads for stability 
      
         
}

To check if the sketch works, firstly I did some test directly on A0. I set threshold level to 1000 and it works fine: If I speak in the microphone the LED turns on, if not the LED remains dark.
Then I made tests with the filtered signal. Insert data2 instead of data1 at code:
if (data2 > threshold) {
digitalWrite(ledPin, HIGH);…..
but now the LED switches on and off randomly! :frowning:
I think the filter gives out incorrect numbers. But before Im goning to check this I have another question: Are the input signals correctly for filter computation? Because the microphone gives out a value off ca. 512 (1024/2) if its quite, and when it's loud a signal of 1024 or 0. In the microphone circuit is implemented a DC offset. So the microphone waves doesn't oscillate around 0V but around 2,5V. See also:

Here the schematic, of my microphone:

a plot from Maxy-B:

(see also comments on: SparkFun Electret Microphone Breakout - BOB-12758 - SparkFun Electronics)
This should be correct because you can work whit the whole wave of the input signal.
But are these signals also ok for filter calculation?

Are the input signals correctly for filter computation?

Good question, you should subtract DC offset. Other things, declare data1 and data2 as signed. And you don't need time measurements anymore, otherwise you are reading input twice.

// int data1 = analogRead(analogPin);    <-- int, not unsigned int !
  data1 = analogRead(0) -512;       //Read Analog channels 
  data2 = Filter.run(data1);   //Read the filtered signal

Hello Magician, thank you very much for the support! Now it works!
I tested it with a sweep from 0-1000Hz. LED on until ca. 400Hz (threshold= 512). LED off, for all frequencies above. I set cut off at 300Hz, the LED switches off only at 400Hz. I think this can have to do with the filter curve and the characteristics which defines them… Chebyshev or Bessel; order...
Here the code:

// Arduino Signal Filtering Test
// Turn a LED on if filter amplitude reaches an arbitrary threshold.
// 2014  

// Arduino Signal Filtering Library
// Copyright 2012-2013 Jeroen Doggen (jeroendoggen@gmail.com)
//http://jeroendoggen.github.io/Arduino-signal-filtering-library/
//http://www.schwietering.com/jayduino/filtuino/


#include <SignalFilter.h>  // Filter Library
SignalFilter Filter;

const int ledPin = 13;        // pin that the LED is attached to
const int threshold = 512;    // an arbitrary threshold level that's in the range of the analog input

/* Variable for time measurement
unsigned long time_start;    // variable for time measurement start
unsigned long time_sampl;    // variable for time measurement sample
int incomingByte = 0;        // sets incoming Byte to 0
*/

int data1;     // variable for Analog In 
int data2;     // variable for filter


void setup()
{
  pinMode(ledPin, OUTPUT);     // initialize the LED pin as an output:
 // Serial.begin(9600);        // used only printing (debugging)
  Filter.begin();
  Filter.setFilter('c');       // filter settings: c=Cebycheff  b= Bessel
  Filter.setOrder(2);          // filter settings: order 1 or 2     
}

/* 
      Filter characteristics are stored in: “SignalFilter.cpp”.
      Current filter settings and code: for “c” “2”

  /// runChebyshev: Low Pass; 2nt Order; cutoff =300Hz; sampling=5000Hz; long type 8bit; 
  “-1bit saturation” enabled;
                        _v[0] = _v[1];
			_v[1] = _v[2];
			long tmp = ((((data * 3009876L) >>  6)	//= (   2.2425325955e-2 * x)
				+ ((_v[0] * -3295982L) >> 1)	//+( -0.7858234574*v[0])
				+ (_v[1] * 3557026L)	//+(  1.6961221536*v[1])
				)+1048576) >> 21; // round and downshift fixed point /2097152

			_v[2]= (short)tmp;
			return (short)((
				 (_v[0] + _v[2])
				+2 * _v[1])); // 2^  
*/


void loop()
{
 // Read Analog Input... you can connect accelerometer, gyro, temperature sensor, microphone etc to the channel
  
  data1 = analogRead(0)-512;      //Read Analog channel (value of microphone) and substract DC-Offset from Microphone "BOB-09964"
  data2 = Filter.run(data1);      //Read the filtered signal 
  
/*
http://arduino.cc/en/Tutorial/IfStatement
the variable called data1 is used to store the data collected from a Analog Pin A0. 
This data is then compared to a threshold value. 
If the the value is found to be above the set threshold the LED connected to digital pin 13 is turned on. 
If analogValue is found to be < threshold, the LED remains off. */


  // if the filter value is high enough, turn on the LED:
  if (data2 > threshold) {
    digitalWrite(ledPin, HIGH);
  }
  else {
    digitalWrite(ledPin,LOW);
  }
   
   /* time measurement for debugging:
 
   time_start = micros();               //time measurement 
   data1 = analogRead(0);              // for Analog Pin A0
   data2 = Filter.run(data1);          // for filter calculation
   time_sampl = micros() - time_start; //time measurement math
  
  if (Serial.available() > 0) {
    incomingByte = Serial.read();
    if (incomingByte == 'm') {         // enter and sent "m" in serial monitor window and read time in microsec for Filter.run(data1) and analog read
    Serial.print("Time Sample = "); 
    Serial.println(time_sampl, DEC);
        }
      } */
}

If you see further errors or if you have improvement suggestions please write me.
Now I’m going to implement a BandPassFilter. Let’s see if I can make it! :wink:

Hello, I have a further question now:
Beside the filter I want also generate sine-waves (0Hz-500Hz) with the Arduino.
I thought I could use one of these methods:
DDS
http://interface.khm.de/index.php/lab/experiments/arduino-dds-sinewave-generator/
DAC (Digital Analog Converter)

but they are maybe to heavy for the microcontroller (slow sample rate). I did some tests and the filter didn’t work anymore.
What do you think, it’s principally possible to use a filter and generate sine-waves simultaneously?
I found also this Audio Shield:

Maybe that’s a good solution because it works “asynchronously as an interrupt, so the Arduino can perform tasks while the audio is playing.”

What do you think about? Do you know maybe other methods to generate sine-waves which don’t overload the microcontroller?

What do you think, it’s principally possible to use a filter and generate sine-waves simultaneously?

Sure, it's possible. 500 Hz is quite low freq.,

I did some tests and the filter didn’t work anymore.

It happenes, when two subfunction interfere with each other.

It happenes, when two subfunction interfere with each other.

I did a little bit of research in the last 2 days. I don’t know if I’m right, but I think a good solution to run two subroutines (subfunction) in a like simultaneous way is the use of interrupts:

I tried to understand how this project works:

“We use timer2 to regularly interrupt the CPU and call a special function to load…”
So they are already using interrupts and the processor should have enough time to calculate filter.
Consideration this I did further tests with this sketch and the filter sketch merged together:

// Arduino: 
// Generating sine waves
//http://makezine.com/projects/make-35/advanced-arduino-sound-synthesis/
// Filter 
// Turn a LED on if filter amplitude reaches an arbitrary threshold.
// 2014  

// Arduino Signal Filtering Library
// Copyright 2012-2013 Jeroen Doggen (jeroendoggen@gmail.com)
//http://jeroendoggen.github.io/Arduino-signal-filtering-library/
//http://www.schwietering.com/jayduino/filtuino/

// and generate a Sinewave
/******** Load AVR timer interrupt macros ********/
//http://makezine.com/projects/make-35/advanced-arduino-sound-synthesis/


#include <avr/interrupt.h>  // library for Sinewave

 //Sine wave parameters 
#define PI2     6.283185  // 2 * PI - saves calculating it later
#define AMP     127       // Multiplication factor for the sine wave
#define OFFSET  128       // Offset shifts wave to just positive values

// Lookup table 
#define LENGTH  256  // The length of the waveform lookup table
byte wave[LENGTH];   // Storage for the waveform




#include <SignalFilter.h>  // Filter Library
SignalFilter Filter;

const int ledPin = 13;        // pin that the LED is attached to
const int threshold = 480;    // an arbitrary threshold level that's in the range of the analog input

/* // Variable for time measurement
unsigned long time_start;     // variable for time measurement start
unsigned long time_sampl;     // variable for time measurement sample
int incomingByte = 0;         // sets incoming Byte to 0 */


int data1;     // variable for Analog In 
int data2;     // variable for filter


void setup()
{
  
 // Filter Parameters 
  pinMode(ledPin, OUTPUT);      // initialize the LED pin as an output:
  /* Serial.begin(9600);        // used only for printing (debugging) */
  Filter.begin();
  Filter.setFilter('c');       // filter settings: c=Cebycheff  b= Bessel
  Filter.setOrder(2);          // filter settings: order 1 or 2    
 
 
 // Sinewave Parameters
 // Populate the waveform lookup table with a sine wave 
  for (int i=0; i<LENGTH; i++) {          // Step across wave table
    float v = (AMP*sin((PI2/LENGTH)*i));  // Calculate current entry
    wave[i] = int(v+OFFSET);              // Store value as integer
  }
  
  // Set timer1 for 8-bit fast PWM output 
  pinMode(9, OUTPUT);       // Make timer's PWM pin an output
  TCCR1B  = (1 << CS10);    // Set prescaler to full 16MHz
  TCCR1A |= (1 << COM1A1);  // PWM pin to go low when TCNT1=OCR1A
  TCCR1A |= (1 << WGM10);   // Put timer into 8-bit fast PWM mode
  TCCR1B |= (1 << WGM12); 

  // Set up timer 2 to call ISR 
  TCCR2A = 0;               // We need no options in control register A
  TCCR2B = (1 << CS21);     // Set prescaller to divide by 8
  TIMSK2 = (1 << OCIE2A);   // Set timer to call ISR when TCNT2 = OCRA2
  OCR2A = 32;               // sets the frequency of the generated wave (32=246.94Hz)
  sei();                    // Enable interrupts to generate waveform!
  
}


/* 
      Filter characteristics are stored in: “SignalFilter.cpp”.
      Current filter settings and code: for “c” “2”

/// runChebyshev: Bandpass 220Hz; 1. Order; lower corner=215Hz; upper corner=225Hz; sampling=5000Hz; long type 8bit; enabled "-1 bit saturation";
			_v[0] = _v[1];
			_v[1] = _v[2];
			long tmp = ((((data * 3360365L) >>  8)	//= (   6.2591678898e-3 * x)
				+ ((_v[0] * -4141801L) >> 1)	//+( -0.9874824279*v[0])
				+ (_v[1] * 4009861L)	//+(  1.9120508347*v[1])
				)+1048576) >> 21; // round and downshift fixed point /2097152

			_v[2]= (short)tmp;
			return (short)((
				 (_v[2] - _v[0]))); // 2^
*/


void loop()
{
 // Read Analog Input... you can connect accelerometer, gyro, temperature sensor, microphone etc to the channel
  
  data1 = analogRead(0)-512;      //Read Analog channel (value of microphone) and substract DC-Offset from microphone "BOB-09964"
  data2 = Filter.run(data1);      //Read the filtered signal 
  

// http://arduino.cc/en/Tutorial/IfStatement

  // if the filter value is high enough, turn on the LED:
  if (data2 > threshold) {
    digitalWrite(ledPin, HIGH);
  }
  else {
    digitalWrite(ledPin,LOW);
  }
   
   /*
    // time measurement for debugging:
   time_start = micros();               //time measurement 
   data1 = analogRead(0);              // for Analog Pin A0
   data2 = Filter.run(data1);          // for filter calculation
   time_sampl = micros() - time_start; //time measurement math
  
  if (Serial.available() > 0) {
    incomingByte = Serial.read();
    if (incomingByte == 'm') {         // enter and sent "m" in serial monitor window and read time in microsec for Filter.run(data1) and analog read
    Serial.print("Time Sample = "); 
    Serial.println(time_sampl, DEC);
        }
      }*/    
}   

  //Called every time TCNT2 = OCR2A 
ISR(TIMER2_COMPA_vect) {  // Called each time TCNT2 == OCR2A
  static byte index=0;    // Points to successive entries in the wavetable
  OCR1AL = wave[index++]; // Update the PWM output
  asm("NOP;NOP");         // Fine tuning
  TCNT2 = 6;              // Timing to compensate for time spent in ISR
}

As filter I used a Bandpassfilter where a frequency of 220Hz should pass. I set the lower cut off frequency at 215Hz and the upper cut off frequency at 225Hz (more details in the posted sketchs).
The good news is that the sketch works, but instead that pass my desired frequency of 220Hz, passes a frequency of 275Hz.
To exclude errors I did also tests with my Filter-LED sketch:

// Arduino Signal Filtering Test
// Turn a LED on if filter amplitude reaches an arbitrary threshold.
// 2014  

// Arduino Signal Filtering Library
// Copyright 2012-2013 Jeroen Doggen (jeroendoggen@gmail.com)
//http://jeroendoggen.github.io/Arduino-signal-filtering-library/
//http://www.schwietering.com/jayduino/filtuino/


#include <SignalFilter.h>  // Filter Library
SignalFilter Filter;

const int ledPin = 13;        // pin that the LED is attached to
const int threshold = 512;    // an arbitrary threshold level that's in the range of the analog input

/* // Variable for time measurement
unsigned long time_start;    // variable for time measurement start
unsigned long time_sampl;    // variable for time measurement sample
int incomingByte = 0;        // sets incoming Byte to 0
*/

int data1;     // variable for Analog In 
int data2;     // variable for filter


void setup()
{
  pinMode(ledPin, OUTPUT);     // initialize the LED pin as an output:
 // Serial.begin(9600);        // used only printing (debugging)
  Filter.begin();
  Filter.setFilter('c');       // filter settings: c=Cebycheff  b= Bessel
  Filter.setOrder(2);          // filter settings: order 1 or 2     
}

/* 
      Filter characteristics are stored in: “SignalFilter.cpp”.
      Current filter settings and code: for “c” “2”

/// runChebyshev: Band Pass 220Hz; 1. Order; lower corner =215Hz; upper corner 225Hz; sampling=5000Hz; long type 8bit; enabled "-1 bit saturation";
			_v[0] = _v[1];
			_v[1] = _v[2];
			long tmp = ((((data * 3360365L) >>  8)	//= (   6.2591678898e-3 * x)
				+ ((_v[0] * -4141801L) >> 1)	//+( -0.9874824279*v[0])
				+ (_v[1] * 4009861L)	//+(  1.9120508347*v[1])
				)+1048576) >> 21; // round and downshift fixed point /2097152

			_v[2]= (short)tmp;
			return (short)((
				 (_v[2] - _v[0]))); // 2^
*/


void loop()
{
 // Read Analog Input... you can connect accelerometer, gyro, temperature sensor, microphone etc to the channel
  
  data1 = analogRead(0)-512;      //Read Analog channel (value of microphone) and substract DC-Offset from Microphone "BOB-09964"
  data2 = Filter.run(data1);      //Read the filtered signal 
  
/*
http://arduino.cc/en/Tutorial/IfStatement
the variable called data1 is used to store the data collected from a Analog Pin A0. 
This data is then compared to a threshold value. 
If the the value is found to be above the set threshold the LED connected to digital pin 13 is turned on. 
If analogValue is found to be < threshold, the LED remains off. */


  // if the filter value is high enough, turn on the LED:
  if (data2 > threshold) {
    digitalWrite(ledPin, HIGH);
  }
  else {
    digitalWrite(ledPin,LOW);
  }
   
   /* // time measurement for debugging:
 
   time_start = micros();               //time measurement 
   data1 = analogRead(0);              // for Analog Pin A0
   data2 = Filter.run(data1);          // for filter calculation
   time_sampl = micros() - time_start; //time measurement math
  
  if (Serial.available() > 0) {
    incomingByte = Serial.read();
    if (incomingByte == 'm') {         // enter and sent "m" in serial monitor window and read time in microsec for Filter.run(data1) and analog read
    Serial.print("Time Sample = "); 
    Serial.println(time_sampl, DEC);
        }
      } */
}

But also there nearly the same problem: 220Hz doesn’t pass but a frequency of 306Hz?! :~
Do you understand this bug? Are there maybe more variables from filter depends?

But also there nearly the same problem: 220Hz doesn’t pass but a frequency of 306Hz?!

Probably, your sampling rate isn't defined at 5 kHz, but vary above the spec.
Do you have a scope? If not, i could suggest to use your PC as a freq. meter, set one digital pin as output, and drive it high/low in the loop. Than using audacity or something else, use PC sound card to measure freq. Don't forget to attenuate a voltage from the pin with resistive divider, and put a DC blocking cap

Probably, your sampling rate isn't defined at 5 kHz, but vary above the spec.

Yes, you are right! :slight_smile:
I have a digital oscilloscope and did the measurement how as suggested by you. Here the sketch:

// Arduino Signal Filtering Test
// Turn a LED on if filter amplitude reaches an arbitrary threshold.
// 2014  

// Arduino Signal Filtering Library
// Copyright 2012-2013 Jeroen Doggen (jeroendoggen@gmail.com)
//http://jeroendoggen.github.io/Arduino-signal-filtering-library/
//http://www.schwietering.com/jayduino/filtuino/


#include <SignalFilter.h>  // Filter Library
SignalFilter Filter;

int Pin8 = 8;   // for sampling measurement 

const int ledPin = 13;        // pin that the LED is attached to
const int threshold = 512;    // an arbitrary threshold level that's in the range of the analog input

/* // Variable for time measurement
unsigned long time_start;    // variable for time measurement start
unsigned long time_sampl;    // variable for time measurement sample
int incomingByte = 0;        // sets incoming Byte to 0
*/

int data1;     // variable for Analog In 
int data2;     // variable for filter


void setup()
{
  pinMode(Pin8, OUTPUT);        // for sampling measurement 
  pinMode(ledPin, OUTPUT);     // initialize the LED pin as an output:
 // Serial.begin(9600);        // used only printing (debugging)
  Filter.begin();
  Filter.setFilter('c');       // filter settings: c=Cebycheff  b= Bessel
  Filter.setOrder(2);          // filter settings: order 1 or 2     
}

/* 
      Filter characteristics are stored in: “SignalFilter.cpp”.
      Current filter settings and code: for “c” “2”

/// runChebyshev: Band Pass 220Hz; 1. Order; lower corner =215Hz; upper corner 225Hz; sampling=5000Hz; long type 8bit; enabled "-1 bit saturation";
			_v[0] = _v[1];
			_v[1] = _v[2];
			long tmp = ((((data * 3360365L) >>  8)	//= (   6.2591678898e-3 * x)
				+ ((_v[0] * -4141801L) >> 1)	//+( -0.9874824279*v[0])
				+ (_v[1] * 4009861L)	//+(  1.9120508347*v[1])
				)+1048576) >> 21; // round and downshift fixed point /2097152

			_v[2]= (short)tmp;
			return (short)((
				 (_v[2] - _v[0]))); // 2^
*/


void loop()
{
 // Read Analog Input... you can connect accelerometer, gyro, temperature sensor, microphone etc to the channel
  
  data1 = analogRead(0)-512;      //Read Analog channel (value of microphone) and substract DC-Offset from Microphone "BOB-09964"
  data2 = Filter.run(data1);      //Read the filtered signal 
  
/*
http://arduino.cc/en/Tutorial/IfStatement
the variable called data1 is used to store the data collected from a Analog Pin A0. 
This data is then compared to a threshold value. 
If the the value is found to be above the set threshold the LED connected to digital pin 13 is turned on. 
If analogValue is found to be < threshold, the LED remains off. */


  // if the filter value is high enough, turn on the LED:
  if (data2 > threshold) {
    digitalWrite(ledPin, HIGH);
  }
  else {
    digitalWrite(ledPin,LOW);
  }
   
 
    digitalWrite(Pin8, HIGH);  // PIN Output High Sample Measurement
    digitalWrite(Pin8, LOW);   // PIN Output Low Sample Measurement 
    
    
   /* // time measurement for debugging:
 
   time_start = micros();               //time measurement 
   data1 = analogRead(0);              // for Analog Pin A0
   data2 = Filter.run(data1);          // for filter calculation
   time_sampl = micros() - time_start; //time measurement math
  
  if (Serial.available() > 0) {
    incomingByte = Serial.read();
    if (incomingByte == 'm') {         // enter and sent "m" in serial monitor window and read time in microsec for Filter.run(data1) and analog read
    Serial.print("Time Sample = "); 
    Serial.println(time_sampl, DEC);
        }
      } */
}

It gives me a frequency between 6,350 KHz and 6,579KHz (attachment).
On my other sketch (filter and sine wave) the sample rate is about 5,9KHz
Are there possibilities to control the sampling frequency?

Perhaps, TimerOne library could help.

I'll check it out.
Many thanks for your precious tips!

http://coolarduino.wordpress.com/2012/06/28/stereo-audio-vu-meter-on-arduino/
sadly doesn`t exist anymore.

Right, virus eats it up completely
[/quote]

Is the attached the article that got wiped? From some FFT research I was doing last year.

Ray

Audio VU Meter.pdf (256 KB)

VU_LCD_2_stable_P.ino (6.57 KB)

Hello, I suppose… Magician posted it here http://forum.arduino.cc/index.php?PHPSESSID=h35fsns7ltuls6qpoe2pki8bs4&/topic,164915

IMHO, there is nothing better than FFT for band pass filtering, explained here:
http://coolarduino.wordpress.com/2012/06/28/stereo-audio-vu-meter-on-arduino/

When I have more time I will read the article.
Thankz for your post!! :slight_smile: