50% found this document useful (2 votes)
846 views

Guitar Tuner Project Report - EE 6th Sem

1. The document discusses the design of an electronic guitar tuner that uses an Arduino microcontroller. It tunes the guitar by analyzing the input audio signal using algorithms like auto-correlation to determine the fundamental frequency. 2. Key components of the tuner include an op-amp for audio amplification, an ADC to convert the analog audio to digital, and a DSP stage using Arduino to analyze the signal and determine the note using algorithms. An LCD is used for display. 3. The tuner amplifies and offsets the guitar's audio signal to work with Arduino's input range. It then uses auto-correlation to compare the signal to itself at different time lags, detecting the lag with
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
50% found this document useful (2 votes)
846 views

Guitar Tuner Project Report - EE 6th Sem

1. The document discusses the design of an electronic guitar tuner that uses an Arduino microcontroller. It tunes the guitar by analyzing the input audio signal using algorithms like auto-correlation to determine the fundamental frequency. 2. Key components of the tuner include an op-amp for audio amplification, an ADC to convert the analog audio to digital, and a DSP stage using Arduino to analyze the signal and determine the note using algorithms. An LCD is used for display. 3. The tuner amplifies and offsets the guitar's audio signal to work with Arduino's input range. It then uses auto-correlation to compare the signal to itself at different time lags, detecting the lag with
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 44

ABSTRACT:

In order to play beautiful music, a musician needs to have perfectly tuned instruments. If it is not tuned properly, it will not sound good, even if you are playing everything correctly. As any novice musician knows, one of the most frustrating parts of learning how to play guitar is tuning the instrument which can be difficult for the untrained ear. This is where electronic tuners come in. These small devices allow guitarists to perfectly tune their instruments. The tuner is designed using the filtering, measuring and analyzing capabilities of the Arduino. Compared to tuning by ear, where a certain amount of guess work is involved in deciding how much to tighten/loosen a string, the Arduino based tuner is able to give accurate instructions so that tuning can be achieved quicker.

1|Page

ACKNOWLEDGEMENT:
On the very outset of this project, we would like to extend our sincere and heartfelt gratitude towards our guide Mr. Shankar Banwasi for his constant support throughout the course of this venture. We are ineffably indebted to Mrs Abha Tripathi for her conscientious guidance and encouragement to accomplish this assignment. We are extremely thankful and express our earnest gratitude to the faculty members of electrical and electronics department of PESIT for providing us with valuable information in our endeavour. We would also like to show our appreciation for our HOD Dr.B Keshavan and our principal Dr K.N.B Murthy, for providing us with the opportunity to take this task upon ourselves.

2|Page

TABLE OF CONTENTS
Chapter 1: Introduction 1.0: Electric Guitar Theory 1.1: Working of an Electric Guitar Chapter 2: Design 2.0: Block Diagram Representation 2.1: Choice of Components and Cost Analysis 2.1.1: Op-Amp 2.1.2: Digital Signal Processing 2.1.3: LCD Display 2.2: External Circuit 2.3: Selection of Algorithm 2.3.1:Auto-Correlation 2.3.2:Measuring Zero Crossing with Positive Slope Chapter 3: Implementation 3.0: External Circuit 3.0.1: Simulation Results 3.1: Implementation of Algorithm 3.1.1: Measuring Zero Crossing with Positive Slope 3.1.2: Auto-Correlation 3.2: Pitch Calculation 3.3: Output Display 3.4: Bread Board View Chapter 4: Result and Conclusion Chapter 5: Future Enhancements Bibliography 4 5

6 6 7 7 8 9 10

12 12 13 14 15 15 16 17 18

Appendix A1: Source code for Auto-Correlation 19 A2: Source Code for measuring Zero Crossing with Positive Slope 31

3|Page

CHAPTER 1

INTRODUCTION
1.0 ELECTRIC GUITAR THEORY
A guitar is a six stringed musical instrument. It primarily consists of a neck and a body. The six strings are strung along the neck to the bridge on the body. The thickness of each string is different. Along the neck of the guitar are frets. Pressing the strings down onto the fret board changes the length of the string, which changes the note being played. As the stings of the guitar are of a particular length and tension, when played, each string corresponds to a particular note and thus can be tuned to a particular note. Each musical note corresponds to a particular frequency of sound. In western music there are 12 notes, A A# B C C# D D# E F F# G G# The set of these 12 notes make an octave. Given below is the standard tuning of the guitars six strings along with the frequencies, from the thickest to the thinnest string: E: 82.41Hz A: 110.00Hz D: 146.83Hz G: 196.00Hz B: 246.94Hz E: 329.63Hz When the guitar goes out of tune, the frequency of the string does not correspond to that of the expected note. A tuner detects the pitch of the notes played and gives visual feedback, to show how far away the note is from the desired frequency. A guitar note is not made up of a single frequency. It consists of a number of harmonics as well. The difference in the harmonics is what makes a guitar and a violin sound different even while playing the same note. Once a sample note is played on the guitar, its fundamental frequency has to be calculated. A major part of the project is dedicated towards recovering the fundamental frequency from the frequency spectrum of the sample note played on a guitar. Once recovered, it can be compared with the standard to determine if the guitar is in tune.

4|Page

1.1 WORKING OF AN ELECTRIC GUITAR


To produce sound, an electric guitar senses the vibrations of the strings electronically and routes an electronic signal to an amplifier and speaker. The sensing occurs in electro- magnetic pickup mounted under the strings on the guitar's body. The pickup consists of a bar magnet wrapped with as many as 7,000 turns of fine wire. When the metal string is plucked, its vibration in the pickups magnetic field induces a current in the wire of the pickup coil. This is determined by Faradays law which states that, any change in the magnetic environment of a coil of wire will cause an emf to be induced in the coil. The amplifier increases the electrical inputs amplitude and the speaker then converts this to sound.

5|Page

CHAPTER 2

DESIGN
2.0 BLOCK DIAGRAM REPRESENTATION

a) Amplifier stage Amplifier stage contains a simple op-amp based audio amplifier, which amplifies the electrical input obtained from the pickups b) Analog to Digital converter The ADC converts the analog input to a digital signal. The digital signal must have suitable resolution and sampling frequency. c) Digital Signal Processor The DSP stage is used to estimate the fundamental frequency of the incoming signal using suitable algorithms. d) LCD Display The LCD display is used to display how close the signal frequency is to the fixed standards. If the signal frequency matches the standards exactly, the display reflects the note in tune. If the note is a little too high or low relative to the fixed standards, the tuner will show the note as being little sharp or flat respectively.

2.1 CHOICE OF COMPONENTS AND COST ANALYSIS


2.1.1 OP-AMP We chose to use the TL072 (Texas Instruments IC) for the amplification stage. The low harmonic distortion and low noise make the TL072 ideally suited for audio preamplifier applications.

6|Page

2.1.2 DIGITAL SIGNAL PROCESSOR The microcontroller is the ADC and DSP stage. Our choice was between: a) Arduino b) MSP430 Launchpad

Parameters Microcontroller Data Bus Speed Storage RAM Digital I/O Analog I/O IDE Language Kit Cost

MSP430 Launchpad TI M430G2553 16 bit 16MHz 16KB 512B 8 Channels 8 Channels Code Composer Studio Embedded C Rs.500

Arduino ATMega328 8 bit 16Mhz 32KB 2KB 14 Channels 6 Channels Arduino v1.0.1 IDE Arduino C Rs.1200

Arduino is open source and its community support is unmatched compared to the Launchpad. We chose the Arduino as it is easier to prototype on and it has larger RAM space compared to the Launchpad; however the MSP430 is superior to the Arduino in terms of pricing and versatility. Thus as the aim was to prototype, we chose the Arduino. However if we intend to mass produce our tuners, we would use the MSP430. 2.1.3 LCD DISPLAY We use the D6711 7 segment LCD display, for displaying the note. 7 segment displays are used to indicate decimal numerals or alphabets. Once the guitar is tuned, the display will show the alphabet corresponding to the note being played. If the frequency of the played note is too high or too low, this will be indicated by three LEDs one to indicate the note is in tune, and the other two to indicate if the note is higher or lower than the desired note.

7|Page

2.2 EXTERNAL CIRCUIT


Ideally, the circuit would be the amplified output of the guitar connected to the arduino and the arduino after determining the note, would show the required note on the display. However, an audio signal, obtained from the amplifier shows two potential problems when fed directly into the arduinos analog input. The direct signal from the guitar is, Of a very low peak to peak voltage (about 400mV) Varies about the zero reference (whereas the Arduinos analog input reads 0-5V) Hence we must, Amplify the audio signal to bring it to about 2.5V peak to peak Provide a DC offset to the signals reference and make it fall within the 0-5V range. The DC offset changes the reference voltage that the wave oscillates around, i.e. the average voltage of the wave. Thus the reference voltage is brought to 2.5V and the amplified offset wave oscillates between 0V and 5V. We are using the following non-inverting amplifier configuration. Capacitor C3 is used to filter out the high frequency noise. R4, R6 and C2 are used to provide a DC offset to the signal.

8|Page

2.3 SELECTION OF ALGORITHM


2.3.1 AUTO-CORRELATION Autocorrelation is a mathematical technique for the analysis of time series, or signal. It is exactly the same as a cross correlation except, the same signal is correlated with itself. The basic autocorrelation algorithm will now be presented, following which its application in finding the fundamental frequency of the audio signal will be briefly illustrated. Consider a discrete time signal xt and the integration window size is W. The Autocorrelation function is defined as,

In the above equation, is the time lag of the second signal. Consider a composite signal with most of its energy in one frequency, called the fundamental frequency. It also contains a small fraction of the energy within the harmonics of that fundamental frequency. This kind of a spectrum is native to most musical instrument sounds. The timbre of the instrument is characterized by the specific levels of these harmonics and is usually the result of the materials and physical characteristics of the instrument. Either way, the fundamental frequency of the signal is the same regardless of what instrument is played. Consider a composite signal like so.

The magnitude of the autocorrelation function plot with respect to the time lag would result in a graph like so.

9|Page

Since the autocorrelation function works by inducing a time lag to one of the signals, in effect, it compares the phase shifted version of the signal to the original signal. Most of the energy of the signal lies in the fundamental frequency of the signal. Hence, when the phase shift of the signal equals 180o of the fundamental frequency, this results in the cancellation of the fundamental frequency due to the superposition theory. This results in a very low energy at this time lag, thereby resulting in a minimum point in the autocorrelation function. If we measure the time lag (in samples) at this minimum point, it must, more or less be equal to the time lag for 180o phase shift of the fundamental frequency. If the sampling frequency is known, the actual time can be calculated for this lag. The time period of the fundamental would simply by twice the time lag. If sampling frequency is Fs and time lag is tl, then the fundamental frequency F is given by:

This fundamental frequency is then compared to the standard pitches of the musical notes. 2.3.2 MEASURING ZERO CROSSING WITH POSITIVE SLOPE The Arduino has an internal ADC (analog to digital converter) that uses 8 bits for digital encoding. The maximum voltage that can be read by the arduino is 5V, thus this will be read as 255 by it after digital conversion. The reference of 2.5V will be read as 127. We also know that the ADC is setup such that it updates the analog signal at the rate of 38,462Hz. In order to determine the frequency of the input signal, the number of positive slopes encountered is counted. We use interrupts to count the positive slopes. Timer interrupts allow the user to perform a task at very specifically timed intervals regardless of what else is going on in your code. Interrupts are
10 | P a g e

useful for measuring an incoming signal at equally spaced intervals at constant sampling frequency. The following figure should help illustrate this algorithm. The yellow signal is the audio signal. The blue signals spikes indicate the time at which the audio signal crosses the reference with a positive slope. The time between two consecutive spikes will give the time period of the fundamental frequency.

11 | P a g e

CHAPTER 3

IMPLEMENTATION
3.0 EXTERNAL CIRCUIT
3.0.1 SIMULATION RESULTS The following graphs represent the output of the external circuit. - The blue waveform represents the direct output of the guitar. The orange waveform represents the output of the non inverting amplifier. The grey waveform represents the waveform after the DC offset.

Simulation Parameters: - Simulation Tool: www.circuitlab.com - Input: 400mV peak to peak sinusoidal voltage source.

3.1 IMPLEMENTATION OF ALGORITHM


3.1.1 MEASURING ZERO CROSSING WITH POSITIVE SLOPE The following ISR is called every time the ADC samples the analog input. The variable timer is incremented between two positive slopes and reset every time a positive slope is encountered. ISR(ADC_vect) { //when new ADC value ready prevData = newData ; //store previous value newData = ADCH; //get value from A0 if (prevData < 127 && newData >=127){
12 | P a g e

//if increasing and crossing midpoint period = timer; //get period timer = 0; //reset timer } timer++; } Since we know the sampling rate of the ADC, we can use it to calculate the fundamental frequency using the following formula. frequency = 38462/period;//timer-rate/period

3.1.2 AUTOCORRELATION ALGORITHM The following function computes the fundamental frequency using autocorrelation. The array buffer of size N is used as a buffer to store a stream of converted analog values. The array corr stores the result of the autocorrelation of the values stored in buffer. The minIndex variable is used to store the index of the minimum value of the autocorrelation. void compute(void){ //Autocorrelate and find minimum point minIndex=0; for(i=0; i<=N-1; i++){ corr[i] = 0; for(j=0; j<=N-1; j++){ s = j+i; if((j+i)>(N-1)) s = (j+i) - (N-1); corr[i] = corr[i] + (int)buffer[j]*buffer[s]; } if(corr[i]<corr[minIndex]) minIndex = i; } //Calculate Frequency Freq = sampleF/(minIndex*2); } This minimum index is used to find the fundamental frequency using the above formula. Since minIndex corresponds to a 180o phase shift of the fundamental frequency, it must be multiplied by two to obtain the time period.

13 | P a g e

3.2 PITCH CALUCLATION


We first store the standard frequencies of the notes of the lowest octave into their respective variables in the following manner. const int A = 110, As = 116, B = 123, C = 131, Cs = 139, D = 147, Ds = 156, E = 165, F = 171, Fs = 185, G = 196, Gs = 208; Now we decide which octave the incoming signal belongs to. The following code uses Freq obtained from the frequency calculation algorithm. The variable octave is later on used as a multiplier while determining the pitch. int octave = 1; if(Freq > Gs*1) octave = 2; if(Freq > Gs*2) octave =4; if(Freq > Gs*4) octave = 8; The pitch is finally determined using the following if-else construct. The variable t determines the tolerance band between which the frequency must lie in. At the centre of this tolerance band lies the standard note frequency. If the input frequency lies within this tolerance band, it is assumed that the end user intends to tune to that note. if( Freq > (A*octave)*(1-t) && Freq < (A*octave)*(1+t) ){ note = A; /*Signal the 7 seg display with the letter in each of these if statements.*/ seven_seg_A(); } This conditional is repeated for all of the notes.

14 | P a g e

3.3 OUTPUT DISPLAY


Output is displayed in the following manner: - Green LED: Indicates the note is in tune. - Red LED: Indicates the note out of tune and at a higher pitch. - Blue LED: Indicates the note out of tune and at a lower pitch. - Seven Segment Display: Displays the name of the note.

3.4 BREADBOARD VIEW


Following is a diagram of the breadboard view of our final circuit. Software Used: Fritzing

15 | P a g e

CHAPTER 4

RESULT AND CONCLUSION


An accurate, real-time guitar tuner was constructed using an audio amplifier, an Arduino, an LCD display and output LEDs. We tested two algorithms, zero crossing with positive slope and autocorrelation. We noticed that the zero crossing is fast and reasonably accurate. Although, it doesnt work well with increased noise levels and multiple zero crossings per cycle. The autocorrelation algorithm computes the frequency by detecting the relative level of the fundamental with respect to the other frequencies. This ensures accurate result even at very high noise levels as the only requirement is that the maximum energy must be carried by the fundamental.

16 | P a g e

CHAPTER 5

FUTURE ENHANCEMENTS
This project can be extended to include automatic tuning of the guitar strings by using a motor to turn the tuning pegs. These motors can be controlled by a voltage proportional to the amount of turn required. We may estimate the frequency using the same algorithms. We intended to implement the YIN algorithm [1] entirely but we used only the autocorrelation portion of this algorithm as it sufficed our application. The YIN algorithm further uses a cumulative mean normalized difference function along with parabolic interpolation to reduce the error by nearly three times.

17 | P a g e

BIBILIOGRAPHY
[1] Alain de Cheveigne, Hideki Kawahara. YIN, a fundamental frequency estimator for speech and music, 2002. Acoustical Society of America [2] Arduino Frequency Detection by amandaghassaei http://www.instructables.com/id/Arduino-Frequency-Detection/ [3] TL072 Datasheet [4] D6711 Datasheet

18 | P a g e

APPENDIX
A1.SOURCE CODE FOR AUTOCORRELATION ALGORITHM
/******************************************************************************** PESIT EEE 6th Sem Mini Project May 2013 ELECTRONIC GUITAR TUNER Tested on: Arduino Uno Main Algorithm Used: Autocorrelation (for fundamental frequency) Software version: 1.0.1 Test Parameters: INPUT: Emulated Acoustic guitar sound from Guitar Pro V5 (for windows) SIGNAL FLOW: Computer Audio out->Operational Amplifier->Arduino Uno->7 Segment Display USNs: 1PI10EE009 1PI10EE026 1PI10EE019 Source Code: http://pastebin.com/XiU7QHdk ********************************************************************************/ /***************************************************************************** DECLARATIONS ******************************************************************************/ #define N 200 //Buffer Size #define sampleF 38500//Hz #define display_time 5000//ms byte incomingAudio, bIndex=N-1; int buffer[N]; long int corr[N], corrMin; long int t_old, t_new = millis(); int i, j, minIndex,s; int Freq=0; boolean clipping = 0, flag = 0; const int A = 110, //These are the standard note frequencies As = 116, //At the lowest octave B = 123, C = 131, Cs = 139, D = 147, Ds = 156, E = 165, F = 171, Fs = 185, G = 196, Gs = 208; int note = A; int deviation = 0; bool dev; //Higher or lower from the correct note bool correct; //To show that the guitar is in tune

19 | P a g e

/***************************************************************************** FUNCTION TO COMPUTE FUNDAMENTAL FREQUENCY ******************************************************************************/ void compute(void){ //Autocorrelate and find minimum point minIndex=0; for(i=0; i<=N-1; i++){ corr[i] = 0; for(j=0; j<=N-1; j++){ s = j+i; if((j+i)>(N-1)) s = (j+i) - (N-1); corr[i] = corr[i] + (int)buffer[j]*buffer[s]; } if(corr[i]<corr[minIndex]) minIndex = i; } //Calculate Frequency Freq = sampleF/(minIndex*2); } /***************************************************************************** PITCH DETECTION FUNCTION ******************************************************************************/ void pitch(void){ /* This function is used to find the pitch after finding frequency and display the outputs on the 7 segment display and the LEDs */ const float t = 0.035; //tolerance band for note const float t2 = 0.01; //tolerance band for correct note int octave = 1; //FIND OCTAVE if(Freq > Gs*1) octave = 2; if(Freq > Gs*2) octave =4; if(Freq > Gs*4) octave = 8; /*FIND PITCH The following portion is equivalent to checking if 'Freq' lies within a certain band around the given note. The width of this band is set by 't' (a percentage value) Check if: (input_note) lies within required_note +/(percentage*required_note) */ if( Freq > (A*octave)*(1-t) && Freq < (A*octave)*(1+t) ){ note = A;

20 | P a g e

//Signal the 7 seg display with the letter in each of these if statements. seven_seg_A(); } else if( Freq > (As*octave)*(1-t) && Freq < (As*octave)*(1+t) ){ note = As; seven_seg_As(); } else if( Freq > (B*octave)*(1-t) && Freq < (B*octave)*(1+t) ){ note = B; seven_seg_B(); } else if( Freq > (C*octave)*(1-t) && Freq < (C*octave)*(1+t) ){ note = C; seven_seg_C(); } else if( Freq > (Cs*octave)*(1-t) && Freq < (Cs*octave)*(1+t) ){ note = Cs; seven_seg_Cs(); } else if( Freq > (D*octave)*(1-t) && Freq < (D*octave)*(1+t) ){ note = D; seven_seg_D(); } else if( Freq > (Ds*octave)*(1-t) && Freq < (Ds*octave)*(1+t) ){ note = Ds; seven_seg_Ds(); } else if( Freq > (E*octave)*(1-t) && Freq < (E*octave)*(1+t) ){ note = E; seven_seg_E(); } else if( Freq > (F*octave)*(1-t) && Freq < (F*octave)*(1+t) ){ note = F; seven_seg_F(); } else if( Freq > (Fs*octave)*(1-t) && Freq < (Fs*octave)*(1+t) ){ note = Fs; seven_seg_Fs(); } else if( Freq > (G*octave)*(1-t) && Freq < (G*octave)*(1+t) ){ note = G; seven_seg_G(); } else if( Freq > (Gs*octave)*(1-t) && Freq < (Gs*octave)*(1+t) ){ note = Gs; seven_seg_Gs(); } //DISPLAY deviation = Freq - note*octave; if (abs(deviation) < t2*note){ correct = 1; //in tune //Serial.print(" "); //Serial.println("Correct"); } else{ correct = 0; //not in tune if((deviation)>0){ //Serial.print(" "); //Serial.println("Note = deviated HIGH");

21 | P a g e

dev = HIGH; } else { // Serial.print(" "); //Serial.println("Deviated Low"); dev = LOW; } } } /***************END OF PITCH DETECTION FUNCTION****************/ /****************************************************************************** FUNCTIONS FOR 7 SEGMENT DISPLAY *******************************************************************************/ //These are used to display the specific note on the 7 segment display void seven_seg_A(void){ digitalWrite(9, LOW); digitalWrite(8, LOW); digitalWrite(7, LOW); digitalWrite(6, HIGH); digitalWrite(5, LOW); digitalWrite(4, LOW); digitalWrite(3, LOW); digitalWrite(2, HIGH); if(correct == 1) { digitalWrite(12,LOW); digitalWrite(11,HIGH); digitalWrite(10,LOW); } else if(correct == 0) { if(dev == HIGH) { digitalWrite(12,LOW); digitalWrite(11,LOW); digitalWrite(10,HIGH); } else if(dev == LOW) { digitalWrite(12,HIGH); digitalWrite(11,LOW); digitalWrite(10,LOW); } } } void seven_seg_As(void){ digitalWrite(9, LOW); digitalWrite(8, LOW); digitalWrite(7, LOW); digitalWrite(6, HIGH); digitalWrite(5, LOW); digitalWrite(4, LOW); digitalWrite(3, LOW); digitalWrite(2, LOW); if(correct == 1) { digitalWrite(12,LOW);

22 | P a g e

digitalWrite(11,HIGH); digitalWrite(10,LOW); } else if(correct == 0) { if(dev == HIGH) { digitalWrite(12,LOW); digitalWrite(11,LOW); digitalWrite(10,HIGH); } else if(dev == LOW) { digitalWrite(12,HIGH); digitalWrite(11,LOW); digitalWrite(10,LOW); } } } void seven_seg_B(void){ digitalWrite(9, HIGH); digitalWrite(8, HIGH); digitalWrite(7, LOW); digitalWrite(6, LOW); digitalWrite(5, LOW); digitalWrite(4, LOW); digitalWrite(3, LOW); digitalWrite(2, HIGH); if(correct == 1) { digitalWrite(12,LOW); digitalWrite(11,HIGH); digitalWrite(10,LOW); } else if(correct == 0) { if(dev == HIGH) { digitalWrite(12,LOW); digitalWrite(11,LOW); digitalWrite(10,HIGH); } else if(dev == LOW) { digitalWrite(12,HIGH); digitalWrite(11,LOW); digitalWrite(10,LOW); } } } void seven_seg_C(void){ digitalWrite(9, HIGH); digitalWrite(8, HIGH); digitalWrite(7, HIGH); digitalWrite(6, LOW); digitalWrite(5, LOW); digitalWrite(4, HIGH); digitalWrite(3, LOW); digitalWrite(2, HIGH);

23 | P a g e

if(correct == 1) { digitalWrite(12,LOW); digitalWrite(11,HIGH); digitalWrite(10,LOW); } else if(correct == 0) { if(dev == HIGH) { digitalWrite(12,LOW); digitalWrite(11,LOW); digitalWrite(10,HIGH); } else if(dev == LOW) { digitalWrite(12,HIGH); digitalWrite(11,LOW); digitalWrite(10,LOW); } } } void seven_seg_Cs(void){ digitalWrite(9, HIGH); digitalWrite(8, HIGH); digitalWrite(7, HIGH); digitalWrite(6, LOW); digitalWrite(5, LOW); digitalWrite(4, HIGH); digitalWrite(3, LOW); digitalWrite(2, LOW); if(correct == 1) { digitalWrite(12,LOW); digitalWrite(11,HIGH); digitalWrite(10,LOW); } else if(correct == 0) { if(dev == HIGH) { digitalWrite(12,LOW); digitalWrite(11,LOW); digitalWrite(10,HIGH); } else if(dev == LOW) { digitalWrite(12,HIGH); digitalWrite(11,LOW); digitalWrite(10,LOW); } } } void seven_seg_D(void){ digitalWrite(9, HIGH); digitalWrite(8, LOW); digitalWrite(7, LOW); digitalWrite(6, LOW); digitalWrite(5, LOW);

24 | P a g e

digitalWrite(4, HIGH); digitalWrite(3, LOW); digitalWrite(2, HIGH); if(correct == 1) { digitalWrite(12,LOW); digitalWrite(11,HIGH); digitalWrite(10,LOW); } else if(correct == 0) { if(dev == HIGH) { digitalWrite(12,LOW); digitalWrite(11,LOW); digitalWrite(10,HIGH); } else if(dev == LOW) { digitalWrite(12,HIGH); digitalWrite(11,LOW); digitalWrite(10,LOW); } } } void seven_seg_Ds(void){ digitalWrite(9, HIGH); digitalWrite(8, LOW); digitalWrite(7, LOW); digitalWrite(6, LOW); digitalWrite(5, LOW); digitalWrite(4, HIGH); digitalWrite(3, LOW); digitalWrite(2, LOW); if(correct == 1) { digitalWrite(12,LOW); digitalWrite(11,HIGH); digitalWrite(10,LOW); } else if(correct == 0) { if(dev == HIGH) { digitalWrite(12,LOW); digitalWrite(11,LOW); digitalWrite(10,HIGH); } else if(dev == LOW) { digitalWrite(12,HIGH); digitalWrite(11,LOW); digitalWrite(10,LOW); } } } void seven_seg_E(void){ digitalWrite(9, LOW); digitalWrite(8, HIGH);

25 | P a g e

digitalWrite(7, HIGH); digitalWrite(6, LOW); digitalWrite(5, LOW); digitalWrite(4, LOW); digitalWrite(3, LOW); digitalWrite(2, HIGH); if(correct == 1) { digitalWrite(12,LOW); digitalWrite(11,HIGH); digitalWrite(10,LOW); } else if(correct == 0) { if(dev == HIGH) { digitalWrite(12,LOW); digitalWrite(11,LOW); digitalWrite(10,HIGH); } else if(dev == LOW) { digitalWrite(12,HIGH); digitalWrite(11,LOW); digitalWrite(10,LOW); } } } void seven_seg_F(void){ digitalWrite(9, LOW); digitalWrite(8, HIGH); digitalWrite(7, HIGH); digitalWrite(6, HIGH); digitalWrite(5, LOW); digitalWrite(4, LOW); digitalWrite(3, LOW); digitalWrite(2, HIGH); if(correct == 1) { digitalWrite(12,LOW); digitalWrite(11,HIGH); digitalWrite(10,LOW); } else if(correct == 0) { if(dev == HIGH) { digitalWrite(12,LOW); digitalWrite(11,LOW); digitalWrite(10,HIGH); } else if(dev == LOW) { digitalWrite(12,HIGH); digitalWrite(11,LOW); digitalWrite(10,LOW); } } }

26 | P a g e

void seven_seg_Fs(void){ digitalWrite(9, LOW); digitalWrite(8, HIGH); digitalWrite(7, HIGH); digitalWrite(6, HIGH); digitalWrite(5, LOW); digitalWrite(4, LOW); digitalWrite(3, LOW); digitalWrite(2, LOW); if(correct == 1) { digitalWrite(12,LOW); digitalWrite(11,HIGH); digitalWrite(10,LOW); } else if(correct == 0) { if(dev == HIGH) { digitalWrite(12,LOW); digitalWrite(11,LOW); digitalWrite(10,HIGH); } else if(dev == LOW) { digitalWrite(12,HIGH); digitalWrite(11,LOW); digitalWrite(10,LOW); } } } void seven_seg_G(void){ digitalWrite(9, LOW); digitalWrite(8, LOW); digitalWrite(7, LOW); digitalWrite(6, LOW); digitalWrite(5, HIGH); digitalWrite(4, LOW); digitalWrite(3, LOW); digitalWrite(2, HIGH); if(correct == 1) { digitalWrite(12,LOW); digitalWrite(11,HIGH); digitalWrite(10,LOW); } else if(correct == 0) { if(dev == HIGH) { digitalWrite(12,LOW); digitalWrite(11,LOW); digitalWrite(10,HIGH); } else if(dev == LOW) { digitalWrite(12,HIGH); digitalWrite(11,LOW); digitalWrite(10,LOW); }

27 | P a g e

} } void seven_seg_Gs(void){ digitalWrite(9, LOW); digitalWrite(8, LOW); digitalWrite(7, LOW); digitalWrite(6, LOW); digitalWrite(5, HIGH); digitalWrite(4, LOW); digitalWrite(3, LOW); digitalWrite(2, LOW); if(correct == 1) { digitalWrite(12,LOW); digitalWrite(11,HIGH); digitalWrite(10,LOW); } else if(correct == 0) { if(dev == HIGH) { digitalWrite(12,LOW); digitalWrite(11,LOW); digitalWrite(10,HIGH); } else if(dev == LOW) { digitalWrite(12,HIGH); digitalWrite(11,LOW); digitalWrite(10,LOW); } } } void blank(void){ //Blanks out the 7 Segment display digitalWrite(10, LOW); digitalWrite(11, LOW); digitalWrite(12, LOW); digitalWrite(9, HIGH); digitalWrite(8, HIGH); digitalWrite(7, HIGH); digitalWrite(6, HIGH); digitalWrite(5, HIGH); digitalWrite(4, HIGH); digitalWrite(3, HIGH); digitalWrite(2, HIGH); } void test(void){ //To test the 7 Segment display seven_seg_A(); delay(500); seven_seg_As(); delay(500); seven_seg_B(); delay(500); seven_seg_C(); delay(500); seven_seg_Cs();

28 | P a g e

delay(500); seven_seg_D(); delay(500); seven_seg_Ds(); delay(500); seven_seg_E(); delay(500); seven_seg_F(); delay(500); seven_seg_Fs(); delay(500); seven_seg_G(); delay(500); seven_seg_Gs(); delay(500); blank(); } /***************END OF 7 SEG FUNCTIONS****************/ /***************************************************************************** SETUP ******************************************************************************/ void setup(){ pinMode(13,OUTPUT);//led clipping indicator pin cli(); //disable interrupts //set up continuous sampling of analog pin 0 ADCSRA = 0; //clear ADCSRA and ADCSRB registers ADCSRB = 0; ADMUX |= (1 << REFS0); //set reference voltage ADMUX |= (1 << ADLAR); //left align the ADC value- so we can read highest 8 bits from ADCH register only ADCSRA |= (1 << ADPS2) | (1 << ADPS0); //set ADC clock with 32 prescaler16mHz/32=500kHz //ADCSRA |= (1 << ADPS2) | (0 << ADPS1) | (0 << ADPS0); ADCSRA |= (1 << ADATE); //enabble auto trigger ADCSRA |= (1 << ADIE); //enable interrupts when measurement complete ADCSRA |= (1 << ADEN); //enable ADC ADCSRA |= (1 << ADSC); //start ADC measurements sei();//enable interrupts Serial.begin(9600); } /***************************************************************************** INTERRUPT SERVICE ROUTINE ******************************************************************************/ ISR(ADC_vect) {//when new ADC value ready incomingAudio = ADCH;//store 8 bit value from analog pin 0 //t_new = millis(); if (incomingAudio == 0 || incomingAudio == 255){//if clipping digitalWrite(13,HIGH);//set pin 13 high clipping = 1;//currently clipping } //Store in buffer //Works

29 | P a g e

if(bIndex!=N-1){ buffer[bIndex] = incomingAudio; bIndex++; } else{ bIndex = 0; //flag = 1; } } /***************END OF INTERRUPT SERVICE ROUTINE**************/ /***************************************************************************** LOOP ******************************************************************************/ void loop(){ if (clipping){//if currently clipping clipping = 0;// digitalWrite(13,LOW);//turn off clipping led indicator (pin 13) } cli(); compute(); //To print results on serial monitor //Serial.print(Freq); //Serial.println(" hz"); sei(); } /***************END OF LOOP**************/

30 | P a g e

A2.SOURCE CODE FOR ZERO CROSSING WITH POSITIVE SLOPE ALGORITHM


/***************************************************************************** PESIT EEE 6th Sem Mini Project May 2013 ELECTRONIC GUITAR TUNER Tested on: Arduino Uno Main Algorithm Used: Slope detection (for fundamental frequency) Software version: 1.0.1 Test Parameters: INPUT: Emulated Acoustic guitar sound from Guitar Pro V5 (for windows) SIGNAL FLOW: Computer Audio out->Operational Amplifier->Arduino Uno->7 Segment Display USNs: 1PI10EE009 1PI10EE026 1PI10EE019 Source Code: http://pastebin.com/mS1y9FhC *****************************************************************************/

/***************************************************************************** DECLARATIONS ****************************************************************************** / byte incomingAudio; int Freq=0; boolean clipping = 0, flag = 0; const int A = 110, //These are the standard note frequencies As = 116, //At the lowest octave B = 123, C = 131, Cs = 139, D = 147, Ds = 156, E = 165, F = 171, Fs = 185, G = 196, Gs = 208; int note = A; int deviation = 0; bool dev; //Higher or lower from the correct note bool correct; //To show that the guitar is in tune //data storage variables byte newData = 0; byte prevData = 0; unsigned int time = 0; //keeps time and sends vales to store in timer[] occasionally int timer[10]; //sstorage for timing of events int slope[10]; //storage for slope of events unsigned int totalTimer;//used to calculate period

31 | P a g e

unsigned int period; //storage for period of wave byte index = 0; //current storage index float frequency; //storage for frequency calculations int maxSlope = 0; //used to calculate max slope as trigger point int newSlope; //storage for incoming slope data //variables for decided whether you have a match byte noMatch = 0; //counts how many non-matches you've received to reset variables if it's been too long byte slopeTol = 3; //slope tolerance- adjust this if you need int timerTol = 10; //timer tolerance- adjust this if you need //variables for amp detection unsigned int ampTimer = 0; byte maxAmp = 0; byte checkMaxAmp; byte ampThreshold = 30; //raise if you have a very noisy signal /***************END OF INITIAL DECLARATIONS****************/ /***************************************************************************** PITCH DETECTION FUNCTION ****************************************************************************** / void pitch(void){ /* This function is used to find the pitch after finding frequency and display the outputs on the 7 segment display and the LEDs */ const float t = 0.035; //tolerance band for note const float t2 = 0.01; //tolerance band for correct note int octave = 1; //FIND OCTAVE if(Freq > Gs*1){ //Serial.print(" "); //Serial.print("Once Octave"); octave = 2;} if(Freq > Gs*2){ //Serial.print(" "); //Serial.print("twice Octave"); octave =4;} if(Freq > Gs*4) octave = 8; /*FIND PITCH The following portion is equivalent to checking if 'Freq' lies within a certain band around the given note. The width of this band is set by 't' (a percentage value) Check if: (input_note) lies within required_note +/(percentage*required_note) */ if( Freq > (A*octave)*(1-t) && Freq < (A*octave)*(1+t) ){ note = A; //Signal the 7 seg display with the letter in each of these if statements.

32 | P a g e

seven_seg_A(); } else if( Freq > (As*octave)*(1-t) && Freq < (As*octave)*(1+t) ){ note = As; seven_seg_As(); } else if( Freq > (B*octave)*(1-t) && Freq < (B*octave)*(1+t) ){ note = B; seven_seg_B(); } else if( Freq > (C*octave)*(1-t) && Freq < (C*octave)*(1+t) ){ note = C; seven_seg_C(); } else if( Freq > (Cs*octave)*(1-t) && Freq < (Cs*octave)*(1+t) ){ note = Cs; seven_seg_Cs(); } else if( Freq > (D*octave)*(1-t) && Freq < (D*octave)*(1+t) ){ note = D; seven_seg_D(); } else if( Freq > (Ds*octave)*(1-t) && Freq < (Ds*octave)*(1+t) ){ note = Ds; seven_seg_Ds(); } else if( Freq > (E*octave)*(1-t) && Freq < (E*octave)*(1+t) ){ note = E; seven_seg_E(); } else if( Freq > (F*octave)*(1-t) && Freq < (F*octave)*(1+t) ){ note = F; seven_seg_F(); } else if( Freq > (Fs*octave)*(1-t) && Freq < (Fs*octave)*(1+t) ){ note = Fs; seven_seg_Fs(); } else if( Freq > (G*octave)*(1-t) && Freq < (G*octave)*(1+t) ){ note = G; seven_seg_G(); } else if( Freq > (Gs*octave)*(1-t) && Freq < (Gs*octave)*(1+t) ){ note = Gs; seven_seg_Gs(); } //DISPLAY deviation = Freq - note*octave; if (abs(deviation) < t2*note){ correct = 1; //in tune //Serial.print(" "); //Serial.println("Correct"); } else{ correct = 0; //not in tune if((deviation)>0){ //Serial.print(" "); //Serial.println("Note = deviated HIGH"); dev = HIGH; }

33 | P a g e

else { // Serial.print(" "); //Serial.println("Deviated Low"); dev = LOW; } } } /***************END OF PITCH DETECTION FUNCTION****************/ /***************************************************************************** * FUNCTIONS FOR 7 SEGMENT DISPLAY ****************************************************************************** */ //These are used to display the specific note on the 7 segment display void seven_seg_A(void){ digitalWrite(9, LOW); digitalWrite(8, LOW); digitalWrite(7, LOW); digitalWrite(6, HIGH); digitalWrite(5, LOW); digitalWrite(4, LOW); digitalWrite(3, LOW); digitalWrite(2, HIGH); if(correct == 1) { digitalWrite(12,LOW); digitalWrite(11,HIGH); digitalWrite(10,LOW); } else if(correct == 0) { if(dev == HIGH) { digitalWrite(12,LOW); digitalWrite(11,LOW); digitalWrite(10,HIGH); } else if(dev == LOW) { digitalWrite(12,HIGH); digitalWrite(11,LOW); digitalWrite(10,LOW); } } } void seven_seg_As(void){ digitalWrite(9, LOW); digitalWrite(8, LOW); digitalWrite(7, LOW); digitalWrite(6, HIGH); digitalWrite(5, LOW); digitalWrite(4, LOW); digitalWrite(3, LOW); digitalWrite(2, LOW); if(correct == 1) { digitalWrite(12,LOW);

34 | P a g e

digitalWrite(11,HIGH); digitalWrite(10,LOW); } else if(correct == 0) { if(dev == HIGH) { digitalWrite(12,LOW); digitalWrite(11,LOW); digitalWrite(10,HIGH); } else if(dev == LOW) { digitalWrite(12,HIGH); digitalWrite(11,LOW); digitalWrite(10,LOW); } } } void seven_seg_B(void){ digitalWrite(9, HIGH); digitalWrite(8, HIGH); digitalWrite(7, LOW); digitalWrite(6, LOW); digitalWrite(5, LOW); digitalWrite(4, LOW); digitalWrite(3, LOW); digitalWrite(2, HIGH); if(correct == 1) { digitalWrite(12,LOW); digitalWrite(11,HIGH); digitalWrite(10,LOW); } else if(correct == 0) { if(dev == HIGH) { digitalWrite(12,LOW); digitalWrite(11,LOW); digitalWrite(10,HIGH); } else if(dev == LOW) { digitalWrite(12,HIGH); digitalWrite(11,LOW); digitalWrite(10,LOW); } } } void seven_seg_C(void){ digitalWrite(9, HIGH); digitalWrite(8, HIGH); digitalWrite(7, HIGH); digitalWrite(6, LOW); digitalWrite(5, LOW); digitalWrite(4, HIGH); digitalWrite(3, LOW); digitalWrite(2, HIGH);

35 | P a g e

if(correct == 1) { digitalWrite(12,LOW); digitalWrite(11,HIGH); digitalWrite(10,LOW); } else if(correct == 0) { if(dev == HIGH) { digitalWrite(12,LOW); digitalWrite(11,LOW); digitalWrite(10,HIGH); } else if(dev == LOW) { digitalWrite(12,HIGH); digitalWrite(11,LOW); digitalWrite(10,LOW); } } } void seven_seg_Cs(void){ digitalWrite(9, HIGH); digitalWrite(8, HIGH); digitalWrite(7, HIGH); digitalWrite(6, LOW); digitalWrite(5, LOW); digitalWrite(4, HIGH); digitalWrite(3, LOW); digitalWrite(2, LOW); if(correct == 1) { digitalWrite(12,LOW); digitalWrite(11,HIGH); digitalWrite(10,LOW); } else if(correct == 0) { if(dev == HIGH) { digitalWrite(12,LOW); digitalWrite(11,LOW); digitalWrite(10,HIGH); } else if(dev == LOW) { digitalWrite(12,HIGH); digitalWrite(11,LOW); digitalWrite(10,LOW); } } } void seven_seg_D(void){ digitalWrite(9, HIGH); digitalWrite(8, LOW); digitalWrite(7, LOW); digitalWrite(6, LOW); digitalWrite(5, LOW);

36 | P a g e

digitalWrite(4, HIGH); digitalWrite(3, LOW); digitalWrite(2, HIGH); if(correct == 1) { digitalWrite(12,LOW); digitalWrite(11,HIGH); digitalWrite(10,LOW); } else if(correct == 0) { if(dev == HIGH) { digitalWrite(12,LOW); digitalWrite(11,LOW); digitalWrite(10,HIGH); } else if(dev == LOW) { digitalWrite(12,HIGH); digitalWrite(11,LOW); digitalWrite(10,LOW); } } } void seven_seg_Ds(void){ digitalWrite(9, HIGH); digitalWrite(8, LOW); digitalWrite(7, LOW); digitalWrite(6, LOW); digitalWrite(5, LOW); digitalWrite(4, HIGH); digitalWrite(3, LOW); digitalWrite(2, LOW); if(correct == 1) { digitalWrite(12,LOW); digitalWrite(11,HIGH); digitalWrite(10,LOW); } else if(correct == 0) { if(dev == HIGH) { digitalWrite(12,LOW); digitalWrite(11,LOW); digitalWrite(10,HIGH); } else if(dev == LOW) { digitalWrite(12,HIGH); digitalWrite(11,LOW); digitalWrite(10,LOW); } } } void seven_seg_E(void){ digitalWrite(9, LOW); digitalWrite(8, HIGH);

37 | P a g e

digitalWrite(7, HIGH); digitalWrite(6, LOW); digitalWrite(5, LOW); digitalWrite(4, LOW); digitalWrite(3, LOW); digitalWrite(2, HIGH); if(correct == 1) { digitalWrite(12,LOW); digitalWrite(11,HIGH); digitalWrite(10,LOW); } else if(correct == 0) { if(dev == HIGH) { digitalWrite(12,LOW); digitalWrite(11,LOW); digitalWrite(10,HIGH); } else if(dev == LOW) { digitalWrite(12,HIGH); digitalWrite(11,LOW); digitalWrite(10,LOW); } } } void seven_seg_F(void){ digitalWrite(9, LOW); digitalWrite(8, HIGH); digitalWrite(7, HIGH); digitalWrite(6, HIGH); digitalWrite(5, LOW); digitalWrite(4, LOW); digitalWrite(3, LOW); digitalWrite(2, HIGH); if(correct == 1) { digitalWrite(12,LOW); digitalWrite(11,HIGH); digitalWrite(10,LOW); } else if(correct == 0) { if(dev == HIGH) { digitalWrite(12,LOW); digitalWrite(11,LOW); digitalWrite(10,HIGH); } else if(dev == LOW) { digitalWrite(12,HIGH); digitalWrite(11,LOW); digitalWrite(10,LOW); } } }

38 | P a g e

void seven_seg_Fs(void){ digitalWrite(9, LOW); digitalWrite(8, HIGH); digitalWrite(7, HIGH); digitalWrite(6, HIGH); digitalWrite(5, LOW); digitalWrite(4, LOW); digitalWrite(3, LOW); digitalWrite(2, LOW); if(correct == 1) { digitalWrite(12,LOW); digitalWrite(11,HIGH); digitalWrite(10,LOW); } else if(correct == 0) { if(dev == HIGH) { digitalWrite(12,LOW); digitalWrite(11,LOW); digitalWrite(10,HIGH); } else if(dev == LOW) { digitalWrite(12,HIGH); digitalWrite(11,LOW); digitalWrite(10,LOW); } } } void seven_seg_G(void){ digitalWrite(9, LOW); digitalWrite(8, LOW); digitalWrite(7, LOW); digitalWrite(6, LOW); digitalWrite(5, HIGH); digitalWrite(4, LOW); digitalWrite(3, LOW); digitalWrite(2, HIGH); if(correct == 1) { digitalWrite(12,LOW); digitalWrite(11,HIGH); digitalWrite(10,LOW); } else if(correct == 0) { if(dev == HIGH) { digitalWrite(12,LOW); digitalWrite(11,LOW); digitalWrite(10,HIGH); } else if(dev == LOW) { digitalWrite(12,HIGH); digitalWrite(11,LOW); digitalWrite(10,LOW); }

39 | P a g e

} } void seven_seg_Gs(void){ digitalWrite(9, LOW); digitalWrite(8, LOW); digitalWrite(7, LOW); digitalWrite(6, LOW); digitalWrite(5, HIGH); digitalWrite(4, LOW); digitalWrite(3, LOW); digitalWrite(2, LOW); if(correct == 1) { digitalWrite(12,LOW); digitalWrite(11,HIGH); digitalWrite(10,LOW); } else if(correct == 0) { if(dev == HIGH) { digitalWrite(12,LOW); digitalWrite(11,LOW); digitalWrite(10,HIGH); } else if(dev == LOW) { digitalWrite(12,HIGH); digitalWrite(11,LOW); digitalWrite(10,LOW); } } } void blank(void){ //Blanks out the 7 Segment display digitalWrite(10, LOW); digitalWrite(11, LOW); digitalWrite(12, LOW); digitalWrite(9, HIGH); digitalWrite(8, HIGH); digitalWrite(7, HIGH); digitalWrite(6, HIGH); digitalWrite(5, HIGH); digitalWrite(4, HIGH); digitalWrite(3, HIGH); digitalWrite(2, HIGH); } void test(void){ //To test the 7 Segment display seven_seg_A(); delay(500); seven_seg_As(); delay(500); seven_seg_B(); delay(500); seven_seg_C(); delay(500); seven_seg_Cs();

40 | P a g e

delay(500); seven_seg_D(); delay(500); seven_seg_Ds(); delay(500); seven_seg_E(); delay(500); seven_seg_F(); delay(500); seven_seg_Fs(); delay(500); seven_seg_G(); delay(500); seven_seg_Gs(); delay(500); blank(); } /***************END OF 7 SEG FUNCTIONS****************/ /***************************************************************************** INTERRUPT SERVICE ROUTINE ****************************************************************************** / ISR(ADC_vect) {//when new ADC value ready PORTB &= B11101111;//set pin 12 low prevData = newData;//store previous value newData = ADCH;//get value from A0 if (prevData < 127 && newData >=127){//if increasing and crossing midpoint newSlope = newData - prevData;//calculate slope if (abs(newSlope-maxSlope)<slopeTol){//if slopes are == //record new data and reset time slope[index] = newSlope; timer[index] = time; time = 0; if (index == 0){//new max slope just reset PORTB |= B00010000;//set pin 12 high noMatch = 0; index++;//increment index } else if (abs(timer[0]-timer[index])<timerTol && abs(slope[0]newSlope)<slopeTol){//if timer duration and slopes match //sum timer values totalTimer = 0; for (byte i=0;i<index;i++){ totalTimer+=timer[i]; } period = totalTimer;//set period //reset new zero index values to compare with timer[0] = timer[index]; slope[0] = slope[index]; index = 1;//set index to 1 PORTB |= B00010000;//set pin 12 high noMatch = 0; } else{//crossing midpoint but not match index++;//increment index if (index > 9){ reset(); }

41 | P a g e

} } else if (newSlope>maxSlope){//if new slope is much larger than max slope maxSlope = newSlope; time = 0;//reset clock noMatch = 0; index = 0;//reset index } else{//slope not steep enough noMatch++;//increment no match counter if (noMatch>9){ reset(); } } } if (newData == 0 || newData == 1023){//if clipping PORTB |= B00100000;//set pin 13 high- turn on clipping indicator led clipping = 1;//currently clipping } time++;//increment timer at rate of 38.5kHz ampTimer++;//increment amplitude timer if (abs(127-ADCH)>maxAmp){ maxAmp = abs(127-ADCH); } if (ampTimer==1000){ ampTimer = 0; checkMaxAmp = maxAmp; maxAmp = 0; } } void reset(){//clea out some variables index = 0;//reset index noMatch = 0;//reset match couner maxSlope = 0;//reset slope } void checkClipping(){//manage clipping indicator LED if (clipping){//if currently clipping PORTB &= B11011111;//turn off clipping indicator led clipping = 0; } } /***************END OF INTERRUPT SERVICE ROUTINE**************/ /***************************************************************************** SETUP ****************************************************************************** / void setup(){ Serial.begin(9600); pinMode(13,OUTPUT);//led indicator pin

42 | P a g e

pinMode(12,OUTPUT);//output pin cli();//diable interrupts //set up continuous sampling of analog pin 0 at 38.5kHz //clear ADCSRA and ADCSRB registers ADCSRA = 0; ADCSRB = 0; ADMUX |= (1 << REFS0); //set reference voltage ADMUX |= (1 << ADLAR); //left align the ADC value- so we can read highest 8 bits from ADCH register only ADCSRA |= (1 << 16mHz/32=500kHz ADCSRA |= (1 << ADCSRA |= (1 << ADCSRA |= (1 << ADCSRA |= (1 << ADPS2) | (1 << ADPS0); //set ADC clock with 32 prescalerADATE); //enabble auto trigger ADIE); //enable interrupts when measurement complete ADEN); //enable ADC ADSC); //start ADC measurements

sei();//enable interrupts pinMode(13,OUTPUT);//led indicator pin pinMode(12, OUTPUT); pinMode(11, OUTPUT); pinMode(10, OUTPUT); pinMode(9, OUTPUT); pinMode(8, OUTPUT); pinMode(7, OUTPUT); pinMode(6, OUTPUT); pinMode(5, OUTPUT); pinMode(4, OUTPUT); pinMode(3, OUTPUT); pinMode(2, OUTPUT); blank(); //test(); } /***************END OF SETUP**************/ /***************************************************************************** LOOP ****************************************************************************** / void loop(){ checkClipping(); if (checkMaxAmp>ampThreshold){ //calculate frequency timer rate/period Freq = 38462/float(period); //To print results on serial monitor //Serial.print(Freq); //Serial.println(" hz"); } //Detect and display the pitch pitch(); }

43 | P a g e

/***************END OF LOOP**************/

44 | P a g e

You might also like