Some project ideas for the code presented here include:
pitch reactive projects- change the color of RGB LEDs with pitch, or make a lock that only opens when you sing a certain pitch or melody
audio to MIDI conversion- get the Arduino to translate an incoming signal into a series of MIDI messages. See my instructable about getting the Arduino to send and receive MIDI for lots of example code to get started
audio effects- use the frequency information to reconstruct an audio signal from the tone() library or with some stored samples to make a cool effects box/synthesizer
The first step of this project is to set up the audio input circuit. I wrote a detailed Instructable about that here.
Remove these ads by
Signing UpStep 1: Detection of Signal Slope
The important portion of the code is reproduced below. All of this code takes place in the ADC interrupt (interrupts and runs each time a new analog in value is ready from A0, more info about what interrupts are and why we use them can be found here)
prevData = newData;//store previous value
newData = ADCH;//get value from A0
if (newData > prevData){//if positive slope
PORTB |= B00010000;//set pin 12 high
}
else if (newData < prevData){if negative slope
PORTB &= B11101111;//set pin 12 low
}
I should note here that in this tutorial I use direct port manipulation to turn off and on the output pin (pin 12) of the Arduino. I did this because port manipulation is a much faster way of addressing the Arduino's pins than the digitalWrite() command. Since I had to put all the code above inside an interrupt routine that was going off at 38.5kHz, I needed the code to be as efficient as possible. You can read more about port manipulation on the Arduino website, or see the comments I've written above to understand what each line does. You'll also notice in the code below that I used some unfamiliar commands in the setup() function so that I could get the Arduino's analog input to sample at a high frequency. More info on that can be found in my Arduino Audio Input tutorial.
Fig 1 shows the pulse output in blue and the sine wave in yellow on an oscilloscope. Notice how the pulse output toggles each time the sine wave reaches a maximum or minimum. Fig 2 shows the pulse output in blue for an arbitrary waveshape in yellow. Notice here how pulse wave takes on an irregular duty cycle because the incoming signal (yellow) is much more complicated than a sine wave.









































Visit Our Store »
Go Pro Today »




I've found that the code stops measuring frequencies as soon as I try analogRead() from a different analog pin. At the moment I don't fully understand the lower level programming of the ADC that you've done. Is there any way to read from the other analog pins without interfering with the pitch measurement?
http://arduino.cc/en/Tutorial/RCtime
http://www.instructables.com/id/Arduino-Basics-RCtime/
hope that works for what you're doing.
I am currently running the algorithm on a atmega16 with an external cystal at 8MHz, also i modify the code so i get that sampling at 20KHz (adc) beacuse i have an antialiasing filter of about 10KHz ...the program work nice and is fairly precise...
Now i decided to make it work on a ATMEGA128 but this time with a 11.059200MHz i set up the :
// 1 0 0 = 16 means 11MHz/16=691200Hz
//Set ADC prescalar to 16
ADCSRA |= (1 << ADPS2) | (0 << ADPS1) | (0 << ADPS0);
Also i got a delay so it exactly scans at 20KHz (adc) and on my main i have:
if(checkMaxAmp>ampThreshold)
{
frequency = 20000/period; //Timer rate divided into Period
printf("Frequency is : %u Hz\r\n",(u32)frequency);
}
Now the program doesnt work and spits a lot of ramdon frequencies...
Any ideas, do you think the the ext oscillator speed could be affecting it ??
if the current frequency of the wave is less than 82Hz, then the servo motor will spin _ degrees counter clockwise, and if it is more than 82Hz then the servo will spin _degrees clockwise. I can fine tune the code, but I need this to start (and I can't make this code) --Thanks
I want to use this to create an audio password - i.e. when a sequence of pitches are heard, an action takes place. I don't know exactly how to implement that type of code, but I'm going to give it a shot!
I look forward to learning more about Arduino and instructables!
i wonder what would have to be done to use this as an oscilloscope for +- 50v. A friend of mine uses audacity with some limiting circuitry on the line-in input on a sound card.
There are some really good things for people to learn here especially the problem of triggering which you cover with your version of the scope trigger. Its quite hard to get over that trigger ambiguity.
However the fixed crossing reference of 2.5V you measure around can be made flexible by creating a calculated imaginary reference by just continually adding the ADC output values. So for a sine wave all the positive values and negative values will sum close or very near to zero. The same works for a square wave however the imaginary reference will now run somewhere through the center of the square wave as if someone had drawn a horizontal line on you scope screen (i.e not around zero but some positive value). The trigger will now follow around an evolved reference over time. Not sure about a triangular wave...
Hopefully it might even fit in the code?
thanks for the comments!