About coding for frequency detector

Hello to all.

I'm on my project atm, and I need your help.

I've been on this project for long time, but I haven't had any result so far

and I am getting frustrated each day...

Anyways, this is what I am using.

Board : Arduino UNO
Sensor : MAX4466
(MAX4466 Low-Cost, Micropower, SC70/SOT23-8, Microphone Preamplifiers with Complete Shutdown - Maxim Integrated)

I want to perform following steps.

===============================

  1. When power is on, RED LED blinks continuously. (Like an alarm)

  2. Pushing push button starts sensor to measure frequency.
    RED LED turns off, and GREEN LED turns on.

  3. Measure frequency for a minute and make 'average value' out of it.

  4. When a minute is over, GREEN LED turns off and BLUE LED turns on.

  5. As BLUE LED turns on, sound sensor keep on measure frequency real-time.

  6. As the sensor is measuring, it compares 'average value' and real-time frequency.

  7. If real-time frequency's value is higher than 'certain value(let's call it X)', of 'average value',
    BLUE LED turns off, and RED LED blink.

int Switch = 2; // Switch connected to Slot2
int LEDG = 7; // Green LED connected to Slot7
int LEDB = 8; // Blue LED connected to Slot8
int LEDR = 10; // Red LED connected to Slot10
int sds = A0; // Sound sensor connected to Slot A0

/*

  • Set prev_time to 0.
  • current_time is used to sum prev_time and current time .
  • After sum, get average value for the result.
    */

int unsigned long prev_time = 0;
unsigned long current_time = millis();

void setup() {
Serial.begin(9600); // Serial communication set to 9600.
pinMode(LEDG, OUTPUT); // Green LED set as output.
pinMode(LEDB, OUTPUT); // Blue LED set as output.
pinMode(LEDR, OUTPUT); // Red LED set as output.
pinMode(sds, INPUT); // Sound sensor set as input

}

void loop() {

const long interval = 120000; // set interval to 'const long' value, so it stays
120000(120milliseconds=2min)
int current_time = 0; // set current_time to 0

/*

  • When Switch is off, Red LED blinks
    */

if (digitalRead(Switch) == LOW){
digitalWrite(LEDR, HIGH);
delay(50);
digitalWrite(LEDR, LOW);
delay(50);
}

/*

  • If Switch is on, Red LED turns off and Green LED turns on
    */

else {
digitalWrite(LEDR, LOW);
delay(10);
digitalWrite(LEDG, HIGH);
delay(10);
}

/*

  • If current_time minus prev_time value is greater or equal to interval,
  • prev_time equals to current_time and ave equals to prev_time plus sds value.
  • Then ave value divides by 60 (in order to get average value) to get aved(average value)
    */

if (current_time - prev_time >= interval)
prev_time = current_time;
ave = prev_time + sds;
aved = ave / 60;

/*

  • If aved value is greater or equal to 0, Green LED turns off and Blue LED turns on
    */

if (aved >= 0)

digitalWrite(LEDG, LOW);
delay(10);
digitalWrite(LEDB, HIGH);
delay(10);

Serial.print ("Average noise");
Serial.println(aved);

Serial.print ("Realtime noise");
Serial.println(sds);

Serial.print ("SwitchState");
Serial.println(Switch);

}

=======================================================

This is what I have done so far..

I've uploaded the coding to UNO and it does not work as I expected.

Here are my questions.

  1. What are the things I am missing?? or am I getting wrong??

  2. How can I convert values I get from the sensor(MAX4466) to frequncy?

  3. If I can't convert them, what are the values I get from sensor?

I know this is long, and I thank you for reading this thread.

My English isn't that great, I am from South Korea.

Please understand if I don't get you understand.

If there are any questions on this.

By all mean.. please leave comments.

Thank you once again.

The MAX4466 is just a preamp, nothing to do with frequency detection/analysis. And in your code you never attempt to read anything from it anyway. You do add the pin NUMBER to something and in your Serial.prints you print the pin NUMBER.

Can you provide a step by step description of how you think your program is doing step 3 (measure the frequency for a minute). I can't see any code that's doing anything like that.

Steve

What frequencies are involved? How clean is the audio signal? How variable is the amplitude of the signal?

More importantly what are you actually trying to do?

Yes, please tell us what you're trying to do.

Real world sound contains multiple-simultaneous frequencies so it's not easy and the Arduino may not be powerful enough.

Work on one thing at a time! If you are trying to measure frequency, let's leave-out the LED stuff for now.


If you are not familiar with how digital audio works, the Audacity website has a nice little [u]tutorial[/u] about how audio is sampled with the ADC and how the DAC "connects the dots" at the same sample rate to reconstruct the analog waveform.

And if you download Audacity, it has a "Plot Spectrum" feature so you can record a sound and then look at the frequency content. That can be "educational" for those real world sounds.

My English isn't that great, I am from South Korea.

Your written English is good! And nice job with the code comments!

slipstick:
The MAX4466 is just a preamp, nothing to do with frequency detection/analysis. And in your code you never attempt to read anything from it anyway. You do add the pin NUMBER to something and in your Serial.prints you print the pin NUMBER.

Can you provide a step by step description of how you think your program is doing step 3 (measure the frequency for a minute). I can't see any code that's doing anything like that.

Steve

  1. I know MAX4466 is just a preamp. I thought I could fiddle with it to get frequency values.
    (Like converting volts I get from MAX4466 and somehow convert them into Hz. I guess I haven't done
    much pre-research)

  2. Yes, I have not finished coding yet, but before I finish up the whole chunk, I thought at least I should try
    wrap up sequence for LED (Red LED blinking -> button pressed -> Green LED -> and so on).

  3. Sure, this is How I think my program is doing for step 3.

======================================================

int unsigned long prev_time = 0; // Set 'prev_time' as unsigned long type.
unsigned long current_time = millis(); // Set 'current_time' as unsigned long type. Also set millis function
to work as a 'clock'.

void loop() {

const long interval = 120000; // set 'interval' as const long value, so it stays 120000(120milliseconds=2min)
int current_time = 0; // set current_time to 0

if (current_time - prev_time >= interval)
prev_time = current_time;
ave = prev_time + sds;
aved = ave / 60;

/*

  • This is description for above coding.
  • If 'current_time' minus 'prev_time' greater or equals to 'interval',
  • 'prev_time' equals to 'current_time'.
  • Then ave equals to 'prev_time' plus 'sds', which means time passed from beginning plus
  • 'sound sensor value'.
  • Finally, 'aved' is equal to value of 'ave' divide by 60 which is.. mistake I made.
  • It should've been 120 since it's 2minutes of time it took to measure.
    */

======================================================

Now I read my coding again, it looks messy as hell. I did find few mistakes there too,

but still does not explain why buttons and LED sequence work as I intended.

Anyways, thanks for your reply :slight_smile:

You still didn't say what your trying to do... Are you making a guitar tuner? Some kind of sound activated lighting effect? Etc?

I hope you understand that you can't directly read frequency. You read/sample amplitude over time to get the waveform. Then maybe you can determine the frequency.

There is something called autocorrelation for finding the main or dominant frequency (if you're trying to make a guitar tuner or something like that). Or to analyze the frequency spectrum you can use FFT or FHT. Or, there is a special chip if you want to make a 7-band spectrum analyzer effect or a "color organ'.

ave = prev_time + sds;
  aved = ave / 60;

/*
 * This is description for above coding.
 * If 'current_time' minus 'prev_time' greater or equals to 'interval',
 * 'prev_time' equals to 'current_time'.
 * Then ave equals to 'prev_time' plus 'sds', which means time passed from beginning plus 
 * 'sound sensor value'.

Do you realize that you're trying to add an analog reading to time? But, you're actually adding a pin number to the time without actually reading the pin. Either way that doesn't make any sense.

MarkT:
What frequencies are involved? How clean is the audio signal? How variable is the amplitude of the signal?

More importantly what are you actually trying to do?

MarkT:
What frequencies are involved? How clean is the audio signal? How variable is the amplitude of the signal?

More importantly what are you actually trying to do?

  1. I don't understand what you mean by what frequencies are involved. If you mean range, around 100~5k Hz.

  2. Audio signals are from raw sound of a robot.

  3. It depends on the robot.

  4. Sequences are in the above. What I am trying to do is develop a sensor system
    which will be used in Factory Automation robots. When robots move, it makes specific
    frequency. When there are worn parts for robots, the sensor will detect and sets alarm on
    because of changed frequency, since worn parts will make different frequency and noise.

Yes, it is not a good idea to use arduino for such case. I am just tinkering with arduino
before I purchase industrial sound sensor. I am also thinking of develop a board for the
sensor as well.

I know I have a lot to go yet, but I really want to learn and somehow improve myself by
this project of mine.

Hope it helped :slight_smile:

DVDdoug:
You still didn't say what your trying to do... Are you making a guitar tuner? Some kind of sound activated lighting effect? Etc?

I hope you understand that you can't directly read frequency. You read/sample amplitude over time to get the waveform. Then maybe you can determine the frequency.

There is something called autocorrelation for finding the main or dominant frequency (if you're trying to make a guitar tuner or something like that). Or to analyze the frequency spectrum you can use FFT or FHT. Or, there is a special chip if you want to make a 7-band spectrum analyzer effect or a "color organ'.

ave = prev_time + sds;

aved = ave / 60;

/*

  • This is description for above coding.
  • If 'current_time' minus 'prev_time' greater or equals to 'interval',
  • 'prev_time' equals to 'current_time'.
  • Then ave equals to 'prev_time' plus 'sds', which means time passed from beginning plus
  • 'sound sensor value'.


Do you realize that you're trying to add an analog reading to time? But, you're actually adding a pin number to the time without actually reading the pin. Either way that doesn't make any sense.
  1. Now I think I made my purpose clear in other comment's quote.

  2. I had no idea I can't add analog reading values to time.. it all looks numbers to me.
    I know I don't even have single idea on this.

  3. To be honest, I am new to this field and I have no idea on how to code. I tried copy and type easy samples
    from internet and understand how it works. What I figure out from that is I think I have problems with my
    'coding structure'.. I don't even have idea if that's the right word for it. All I do for now is look at
    reference and try to make it similar structure, then upload to UNO until it doesn't come up with error.

Sorry this project is far too difficult for someone who has no idea how to code. You’d need to spend a long time learning Arduino and logic to get even close because it’s not really the sort of thing that Arduinos are good for anyway.

So if you are not intending to use an Arduino in the eventual product then I think you would just be wasting a lot of your time.

Steve

Sorry to say, you are way over you head. I've "played around" with audio for a long time and I wouldn't try this.

. What I am trying to do is develop a sensor system
which will be used in Factory Automation robots. When robots move, it makes specific
frequency. When there are worn parts for robots, the sensor will detect and sets alarm on
because of changed frequency, since worn parts will make different frequency and noise.

That would require lots of computer power, lots of programing, and I don't know if it's even possible or practical. Also, since I assume the robots don't fail very often, you'd have to know the characteristics of the normal-sound and then "listen" for sounds that don't match.

  1. I had no idea I can't add analog reading values to time.. it all looks numbers to me.
    I know I don't even have single idea on this.

You are adding amplitude and time. It doesn't make any more sense than adding centimeters and time. A standard waveform is drawn with amplitude on the Y-axis and time on the X-axis.

The amplitude read by the Arduino is a value proportional to voltage. The voltage is proportional to the air pressure change from the soundwaves picked-up by the microphone. (The microphone sensor output is normally biased because the Arduino can't read the negative voltages.)

One amplitude reading is meaningless. It's a wave - If you are trying to read the amplitude (height) of a wave in the water you can't just take one random reading... You typically want to find the peak. But one peak reading doesn't tell you anything about the wave shape or the frequency.

---------------------------------------------------------------------------------
If you want to learn more about this, do some research about sound, frequency, and amplitude. i.e. The amplitude/loudness from a loudspeaker depends on how far the speaker moves in-and-out and the frequency depends on how fast it moves in-and-out.

For soundwaves in the air, wavelength is inversely related to frequency. (High frequency has shorter wavelengths and you'll also see that if you look at waveforms in Audacity.)

Amplitude is perceived as loudness and frequency is perceived as pitch. And again, real world sounds contain many different simultaneous frequencies. i.e. A trumpet and a piano sound different when playing the same note (the same fundamental pitch). It's the harmonics and overtones that make them sound different.

Read the [u]tutorial[/u] I linked to.

Download [u]Audacity[/u] and record some sounds (maybe some robot sounds) or just open some sound files. Audacity can also generate pure sine waves (and some other waveforms).

By default, Audacity displays the standard waveform view. You can see the amplitude and if you zoom-in you can "see" the frequency (actually the period) if you have a pure single-frequency tone. But with real world sounds you can't tell much about the frequency content. There is are two ways of viewing the frequency content - You can [u]Plot the Spectrum[/u] or [u]View the Specgtrogram[/u].