low pass filter

I found this simple low pass filter code somewhere but it returns only 1023. Is it not complete?

#define FILTER_SHIFT 3
int32_t filter_reg;
int16_t filter_input;
int16_t filter_output;
void setup(){
  Serial.begin(9600);
}
void loop(){

filter_input = analogRead(1);                 // read ADC

// low pass filter to get rid of noise
filter_reg = filter_reg - (filter_reg >> FILTER_SHIFT) + filter_input; 
filter_output = filter_reg >> FILTER_SHIFT;

Serial.println(filter_output);

}

Without know what was plugged into pin 1, and what values are being read into filter_input, it's hard to say whether the 1023 is reasonable.

I notice that pin 1 is not declared an INPUT pin.

The analog input is reading 650~680 from a rectified signal from an LM386 and mic. This sketch is not functioning. Green is never on, blue is on, and red is flashing. I have revised this sketch many ways to make the relative LED’s go LOW without success.

#define FILTER_SHIFT 3

#define redLED 13
#define blueLED 12
#define greenLED 11
#define redThresh 680
#define blueThresh 678
#define greenThresh 0

int32_t filter_reg;
int16_t filter_input;
int16_t filter_output;
void setup(){
  pinMode(redLED,OUTPUT);
  pinMode(blueLED,OUTPUT);
  pinMode(greenLED,OUTPUT); 
  Serial.begin(9600);
 
}
void loop(){

filter_input = analogRead(1);                 // read ADC

// low pass filter to get rid of noise
filter_reg = filter_reg - (filter_reg >> FILTER_SHIFT) + filter_input;
filter_output = filter_reg >> FILTER_SHIFT;
delay(100);

if(filter_output >= redThresh) 
{
digitalWrite(redLED, HIGH);
digitalWrite(blueLED,LOW);
digitalWrite(greenLED, LOW);
delay(100);

}
else{
digitalWrite(redLED, LOW);

}

if((filter_output < redThresh) && (filter_output > greenThresh)) 
{
digitalWrite(blueLED, HIGH);
digitalWrite(redLED, LOW);
digitalWrite(greenLED, HIGH);
delay(100);

}
else{
  digitalWrite(blueLED, LOW);
  

}
if((filter_output >= greenThresh) && (filter_output <= blueThresh)) 
{
digitalWrite(greenLED, HIGH);
digitalWrite(redLED, LOW);
digitalWrite(blueLED, LOW);
delay(100);

}
else{
 digitalWrite(greenLED, LOW); 
}

Serial.println(filter_output);

}

I certainly don't understand what the filter stuff is doing, but I would start with the assumption that it does what its supposed to.

I'd use Serial.println to print the filter_input value, and again to print the filter_output value.

If there is a correlation between the two, I'd assume that it was working, and I'd concentrate on the if statements.

You have some overlap, so there is some possibility that filter_output is on the edge.

Use Serial.print to identify which value is which, and post a brief session. Perhaps we can then help determine where the problem lies.

Another suggestion. Since you only want one LED at a time on, turn all three LEDs off at the start of loop. Then, the if test could look like this:

if(filter_output >= redThresh) // Wow, it's noisy in here
{
   digitalWrite(redLED, HIGH);
   delay(100);
}
else if(filter_output >= blueThresh) // Still loud, but not quite as
{
   digitalWrite(blueThresh, HIGH);
   delay(100);
}
else // Ahh, that's better
{
   digitalWrite(greenLED, HIGH);
   delay(100);
}

A simpler, though possibly less accurate filter would be:

filter_reg = filter_reg - (filter_reg >> FILTER_SHIFT) + (filter_input>> FILTER_SHIFT);

And forget about “filter_output”

This code looks like the input value and existing value are being divided by 8, added together, and the result subtracted from the existing value.

If that's the case, why not use multiplication and division. These operations are intuitively obvious, while bit shifting is not. I understand that bit shifting is faster, but the code is not easily understood, whereas R = (R * 7)/8 + I/8 is relatively easily understood.

Given that OP waits several seconds after this, I'm missing the benefit of this optimization.

Can you explain?

The filter is good, it calculates

filterout = 7/8 * filterout (previous) + 1/8 filter_input and filterreg = 8*filterout.

So it remembers 87% of its previous value and uses 12% of input to update the value.

Try printing out filter_input together with filter output.

If that’s the case, why not use multiplication and division

Good point - but I’m old-school from the days before optimising compilers.
When I see “(x * 7) / 8”, writing “(x - (x >> 3))” actually is more intuitive (for me)!"

x * 10"?
(x << 3) + x + x

True but ... now 3 decimal bits are used in the intermediate calculation of filter_reg and that decreases the digital (truncation) noise in the filter by a factor 8. A very good thing for precise things as motor control, not necessary for some other applications.

It is not about optimizing compilers, it is really about fixed point decimal calculations.

Is there a pattern here?

Left=output Right=input

690 788 681 622 676 636 670 632 667 644 668 680 674 714 681 732 688 736 696 746 697 704 688 632 683 643

Perhaps not a direct correlation, but when the input is larger than the output, the output goes up. When the input is less than the output, the output goes down. So, the filter does seem to be working, in that it is averaging the inputs

I have seen a procedure that calls for new and old values to be compared in order to reject the odd value. Would this be a possible solution to avoid oscillating LED's out of sync?

Here is an Eagle schematic of the circuit.http://i189.photobucket.com/albums/z215/keithgum/noisemonitor.jpg

Here is an Eagle schematic of the circuit

Diode D2 has a ground connection on both sides, that must serve an important function ;D

Lefty

Would a digital mic be better for out application than a simple electret? A Physical Computing circuit does not include the diodes. These came from another source. Would dropping them from the circuit be advisable?

This is the circuit. The “Physical Computing” schematic is exactly the same, minus rectifying diodes. Which is the better choice for our application?

http://itp.nyu.edu/physcomp/sensors/Reports/CondenserMicrophones

Please scroll to the bottom of the page for the last circuit