Heey!
Me and a buddy are having a school project. The project is that we are going to do one or more LEDs that flash to bass tones. But it was harder than we thought! At start (before we started to code) we thought that the analog signal from the microphone already was in frequency but it was in amplitude?
We are basicly new to programming and we are here to learn so please dont rage if you see we did something retarded in your opinion. (We have only a basic course experience.)
What we have found out is that the simplest way to do this is to use Goertzel algorithm to find bass tones. This is what we found about Goertzel algorithm that we think we need:
double tandemRTgoertzelFilter(int sample, double freq) {
static double s_prev[2] = {0.0,0.0};
static double s_prev2[2] = {0.0,0.0};
static double totalpower[2] = {0.0,0.0};
static int N=0;
double coeff,normalizedfreq,power,s;
int active;
static int n[2] = {0,0};
normalizedfreq = freq / SAMPLEFREQUENCY;
coeff = 2*cos(2*M_PI*normalizedfreq);
s = sample + coeff * s_prev[0] - s_prev2[0];
s_prev2[0] = s_prev[0];
s_prev[0] = s;
n[0]++;
s = sample + coeff * s_prev[1] - s_prev2[1];
s_prev2[1] = s_prev[1];
s_prev[1] = s;
n[1]++;
N++;
active = (N / RESETSAMPLES) & 0x01;
if (n[1-active] >= RESETSAMPLES) { // reset inactive
s_prev[1-active] = 0.0;
s_prev2[1-active] = 0.0;
totalpower[1-active] = 0.0;
n[1-active]=0;
}
totalpower[0] += sample*sample;
totalpower[1] += sample*sample;
power = s_prev2[active]*s_prev2[active]+s_prev[active]
* s_prev[active]-coeff*s_prev[active]*s_prev2[active];
return power / (totalpower[active]+1e-7) / n[active];
}
Source: Efficiently detecting a frequency using a Goertzel filter | Networking Embedded Systems
We dont know is how to put it in the Arduino code. If someone could explain how to use this code and show which value who is output and input etc.. I've searched but have not found anything.
We did a code for amplitude and we aren't happy about it cuz it doesn't do what we had in our minds when we started the projekt.. I will post it anyway if you have any suggestions to improve it.
const int pinMic = A0; //Analog input.
const int pinLED0 = 7; //digital output LED 0
const int pinLED1 = 8; //digital output LED 1
const int pinLED2 = 12; //digital output LED 2
int count = 0;
int valBaseline;
int delayLED = 0;
void setup() {
Serial.begin(115300);
pinMode(pinLED0, OUTPUT);
pinMode(pinLED1, OUTPUT);
pinMode(pinLED2, OUTPUT);
pinMode(pinMic, INPUT);
}
void loop() {
++delayLED;
int valMic = analogRead(pinMic);
Serial.println(valMic);
int valBaseline = valMic * 0.8;
if (valMic > valBaseline + 108){
digitalWrite(pinLED0, HIGH);
if (valMic > valBaseline + 110){
digitalWrite(pinLED1, HIGH);
if (valMic > valBaseline + 112){
digitalWrite(pinLED2, HIGH);
}
}
}
if(delayLED > 20){
digitalWrite(pinLED0, LOW);
digitalWrite(pinLED1, LOW);
digitalWrite(pinLED2, LOW);
delayLED = 0;
}
}
Feel free to ask anything! I've probably missed something.
Sorry for the awful English...