loading
Two things that I really like to do are: play guitar and tinker with my Arduino. I was very interested at the thought of this project, so I decided to do it. I am new to programming, so this was a real challenge to me!

This machine works with an electric guitar. It takes the electrical signal transmitted from the guitar and analyzes the code. It all starts with the Op Amp circuit. The circuit itself and the code was designed by amandaghassaei, and I want to thank her for helping me get a running start on my project. 

Here is the list of processes in a nutshell:
1. The string is picked, and the electrical signal is sent through the stereo cable, which carries the sound waves.
2. The female stereo adapter receives the sound waves and puts it into the Op Amp circuit.
3. The Op Amp circuit takes the sound waves and increases the amplitude, so that the Arduino can read it easily. It then sends the signal into the Arduino to be sampled.
4. The Arduino samples the frequency of the sound waves, and records it on the serial port so the user can see.
5. The Arduino looks at which direction the 6-way rotary switch is in, so that it can determine which string it is tuning.
6. The position of the rotary switch determines what the desired frequency is for the string to be at (with a margin of error of 2Hz)
7. If the String is not in tune, then the motor moves accordingly.
8. This process repeats until the string is tuned, then the user moves on to the next string.
I am currently working on the schematic. I will post it as soon as possible. As far as the audio input circuit, go to amandaghassaei's arduino audio input instructable. Thank you for your interest!
<p>can i know what the component that u use in this project?.. </p>
<p>Is this code working properly? Because I compiled it and didn't work.</p><p>Thanks</p>
<p>The below code compiled</p><p>#include &lt;Servo.h&gt;</p><p>Servo Servo1; //declaration of servo object </p><p>int angleStill = 90; //stores servo position </p><p>int angle = 90; //stores servo position </p><p>int trim = 0; //trim adjustment to zero position </p><p>int servoPin = 8; //Arduino pin assigned to servo </p><p>int clockwisespeed = 120; //the speed to go in the clockwise direction </p><p>int countclockwisespeed = 60; //the speed to go in the counter clockwise direction </p><p>boolean clipping = 0; //clipping indicator variables </p><p>//data storage variables </p><p>byte newData = 0; </p><p>byte prevData = 0; </p><p>unsigned int time = 0;//keeps time and sends values to store in timer[] occasionally </p><p>int timer[10];//sstorage for timing of events </p><p>int slope[10];//storage fro slope of events </p><p>unsigned int totalTimer;//used to calculate period </p><p>unsigned int period;//storage for period of wave </p><p>byte index = 0;//current storage index </p><p>float frequency;//storage for frequency calculations </p><p>int maxSlope = 0;//used to calculate max slope as trigger point </p><p>int newSlope;//storage for incoming slope data </p><p>int minfreq; //it will be changed according to its string </p><p>int maxfreq; //it will be hanged according to to its string </p><p>int basefreq = 0; //define baseline noise to ignore any frequency less than this value </p><p>//int highstring;//says if you are tuning high string or not </p><p>//variables for decided whether you have a match </p><p>byte noMatch = 0;//counts how many non-matches you've received to reset variables if it's been too long </p><p>byte slopeTol = 3;//slope tolerance- adjust this if you need </p><p>int timerTol = 10;//timer tolerance- adjust this if you need </p><p>int notenum = 0; //set the guitar string number I want to tune </p><p>int notenumPrior = 0; //holds the previously selected guitar string </p><p>//------------------------------------------------------------------------------------------------------------- </p><p>//all Arduino programs must have a setup routine </p><p>//Starts Setup routine </p><p>void setup(){ </p><p> Serial.begin(9600); //begins sampling the serial port for monitoring purposes </p><p> pinMode(13, OUTPUT); //clipping indicator </p><p> pinMode(12, OUTPUT); //wave period indicator </p><p> pinMode(11, OUTPUT); //freq too low </p><p> pinMode(10, OUTPUT); //freq spot on </p><p> pinMode(9, OUTPUT); //freq too high </p><p>//sets all three pitch indicator lights off </p><p> digitalWrite(11, LOW); </p><p> digitalWrite(10, LOW); </p><p> digitalWrite(9, LOW); </p><p> pinMode(7, INPUT);// different paths from dip switch indicating the notenum value (output) </p><p> pinMode(2, INPUT); </p><p> pinMode(3, INPUT); </p><p> pinMode(4, INPUT); </p><p> pinMode(5, INPUT); </p><p> pinMode(6, INPUT); </p><p> digitalWrite(7, HIGH);// making sure the input pins are set high, so when pressed they will be on low </p><p> digitalWrite(2, HIGH); </p><p> digitalWrite(3, HIGH); </p><p> digitalWrite(4, HIGH); </p><p> digitalWrite(5, HIGH); </p><p> digitalWrite(6, HIGH); </p><p> Servo1.attach(servoPin); //attaches servo on pin x to servo object </p><p>//ADC - Handle Analog to Digital Conversion of Guitar Signal</p><p>cli(); //disables interrupts </p><p>//set up continuous sampling of analog pin 0 at 38.5kHz </p><p>//clear ADCSRA and ADCSRB registers </p><p>ADCSRA = 0; </p><p>ADCSRB = 0; </p><p>ADMUX |= (1 &lt;&lt; REFS0); //set reference voltage </p><p>ADMUX |= (1 &lt;&lt; ADLAR); //left align the ADC value- so we can read highest 8 bits from ADCH register only </p><p>ADCSRA |= (1 &lt;&lt; ADPS2) | (1 &lt;&lt; ADPS0); //set ADC clock with 32 prescaler- 16mHz/32=500kHz </p><p>ADCSRA |= (1 &lt;&lt; ADATE); //enabble auto trigger </p><p>ADCSRA |= (1 &lt;&lt; ADIE); //enable interrupts when measurement complete </p><p>ADCSRA |= (1 &lt;&lt; ADEN); //enable ADC </p><p>ADCSRA |= (1 &lt;&lt; ADSC); //start ADC measurements </p><p>sei();//enable interrupts </p><p>} </p><p>void reset() </p><p>{//clea out some variables </p><p> index = 0;//reset index </p><p> noMatch = 0;//reset match couner </p><p>maxSlope = 0;//reset slope </p><p>}</p><p>//Launch Continuous Interupt Service Routine (ISR) for Sampling Analog to Digital Conversion of Guitar Audio Input </p><p>ISR(ADC_vect) </p><p>{//when new ADC value ready </p><p>PORTB &amp;= B11101111;//set pin 12 low </p><p>prevData = newData;//store previous value </p><p>newData = ADCH;//get value from A0 </p><p>if (prevData &lt; 127 &amp;&amp; newData &gt;=127){//if increasing and crossing midpoint </p><p>newSlope = newData - prevData;//calculate slope </p><p>if (abs(newSlope-maxSlope)) //record new data and reset time </p><p>slope[index] = newSlope; </p><p>timer[index] = time; </p><p>time = 0; </p><p>if (index == 0)</p><p> {//new max slope just reset </p><p>PORTB |= B00010000;//set pin 12 high </p><p>noMatch = 0; </p><p>index++;//increment index </p><p> } </p><p>else if ( abs(timer[0]-timer[index]) ) //sum timer values </p><p>totalTimer = 0 ; </p><p>for (byte i=0;i= totalTimer+=timer[i];) </p><p> { </p><p>period = totalTimer;//set period </p><p>//reset new zero index values to compare with </p><p>timer[0] = timer[index]; </p><p>slope[0] = slope[index]; </p><p>index = 1;//set index to 1 </p><p>PORTB |= B00010000;//set pin 12 high </p><p>noMatch = 0; </p><p> }</p><p>}</p><p>else{//crossing midpoint but not match </p><p>index++;//increment index </p><p> if (index &gt; 9)</p><p> { </p><p> reset(); </p><p> } </p><p> else if (newSlope&gt;maxSlope)</p><p> {//if new slope is much larger than max slope </p><p> maxSlope = newSlope; </p><p> time = 0;//reset clock </p><p> noMatch = 0; </p><p> index = 0;//reset index </p><p> } </p><p> else{ //slope not steep enough </p><p> noMatch++;//increment no match counter </p><p> }</p><p>}</p><p>if (noMatch&gt;9){ </p><p>reset(); </p><p>} </p><p>if (newData == 0 || newData == 1023){//if clipping </p><p>PORTB |= B00100000;//set pin 13 high- turn on clipping indicator led </p><p>clipping = 1;//currently clipping </p><p>} </p><p>time++;//increment timer at rate of 38.5kHz </p><p>} </p><p>//--------------------------------------------------------------------------------------------------- </p><p>//--------------------------------------------------------------------------------------------------- </p><p>void checkClipping(){//manage clipping indicator LED </p><p>if (clipping){//if currently clipping </p><p>PORTB &amp;= B11011111;//turn off clipping indicator led </p><p>clipping = 0; </p><p>} </p><p>} </p><p>//---------------------------------------------------------------------------------------------- </p><p>//Start of Main Arduino Loop </p><p>void loop() // loop </p><p>{ </p><p>//highstring = 0; </p><p>frequency = 38462/float(period); //calculate frequency timer rate/period </p><p>// added for debugging and visualizing data </p><p>Serial.print(frequency); </p><p>Serial.println(&quot; hz&quot;); </p><p>Serial.println(&quot; &quot;); </p><p>Serial.println(&quot;string picked: &quot;); </p><p>Serial.print(notenum); </p><p>notenum_val(); //call function to determine value of note/string we want to tune </p><p>freq_range_identify(); //set frequency threshold ranges for string previously selected </p><p>checkClipping(); //frequency determining and led indicator loop </p><p>set_indicator_lights(); //checks value of current frequency and lights correct indicator light. Then moves servo accordingly </p><p>//Serial.println(angle); </p><p>move_motor(); //move tuning servo motor </p><p>//delay(1000); //turn on to control debouncing </p><p>notenumPrior = notenum; </p><p>} //end of main loop </p><p>//----------------------------------------------------------------------------------------------- </p><p>//Determine String selected from rotary switch and voltage values on designated arduino pins </p><p>void notenum_val() </p><p>{ </p><p>int val_1 = digitalRead(2); //read the value of rotary switch pins </p><p>int val_2 = digitalRead(3); </p><p>int val_3 = digitalRead(4); </p><p>int val_4 = digitalRead(5); </p><p>int val_5 = digitalRead(6); </p><p>int val_6 = digitalRead(7); </p><p>if (val_1 == LOW &amp;&amp; val_2 == HIGH &amp;&amp; val_3 == HIGH &amp;&amp; val_4 == HIGH &amp;&amp; val_5 == HIGH &amp;&amp; val_6 == HIGH) //switch set on pressed, then notenum = 1 </p><p>{ </p><p>if (notenumPrior != 1) </p><p>{ </p><p>delay(5000); </p><p>notenum = 1; </p><p>} </p><p>else </p><p>{ </p><p>notenum = 1; </p><p>} </p><p>} </p><p>else if (val_1 == HIGH &amp;&amp; val_2 == LOW &amp;&amp; val_3 == HIGH &amp;&amp; val_4 == HIGH &amp;&amp; val_5 == HIGH &amp;&amp; val_6 == HIGH) //Switch 3 pressed, noenum = 2 </p><p>{ </p><p>if (notenumPrior != 2 ) </p><p>{ </p><p>delay(5000); </p><p>notenum = 2; </p><p>} </p><p>else </p><p>{ </p><p>notenum = 2; </p><p>} </p><p>} </p><p>else if (val_1 == HIGH &amp;&amp; val_2 == HIGH &amp;&amp; val_3 == LOW &amp;&amp; val_4 == HIGH &amp;&amp; val_5 == HIGH &amp;&amp; val_6 == HIGH) //switch 4 pressed, notenum = 3 </p><p>{ </p><p>if (notenumPrior != 3) </p><p>{ </p><p>delay(5000); </p><p>notenum = 3; </p><p>} </p><p>else </p><p>{ </p><p>notenum = 3; </p><p>} </p><p>} </p><p>else if (val_1 == HIGH &amp;&amp; val_2 == HIGH &amp;&amp; val_3 == HIGH &amp;&amp; val_4 == LOW &amp;&amp; val_5 == HIGH &amp;&amp; val_6 == HIGH) //switch 5 pressed, notenum = 4 </p><p>{ </p><p>if (notenumPrior != 4) </p><p>{ </p><p>delay(5000); </p><p>notenum = 4; </p><p>} </p><p>else </p><p>{ </p><p>notenum = 4; </p><p>} </p><p>} </p><p>else if (val_1 == HIGH &amp;&amp; val_2 == HIGH &amp;&amp; val_3 == HIGH &amp;&amp; val_4 == HIGH &amp;&amp; val_5 == LOW &amp;&amp; val_6 == HIGH) //switch 6 pressed, notenum = 5 </p><p>{ </p><p>if (notenumPrior != 5) </p><p>{ </p><p>delay(5000); </p><p>notenum = 5; </p><p>} </p><p>else </p><p>{ </p><p>notenum = 5; </p><p>} </p><p>} </p><p>else if (val_1 == HIGH &amp;&amp; val_2 == HIGH &amp;&amp; val_3 == HIGH &amp;&amp; val_4 == HIGH &amp;&amp; val_5 == HIGH &amp;&amp; val_6 == LOW) //switch 7 pressed, notenum = 6 </p><p>{ </p><p>if (notenumPrior != 6) </p><p>{ </p><p>delay(5000); </p><p>notenum = 6; </p><p>} </p><p>else </p><p>{ </p><p>notenum = 6; </p><p>} </p><p>} </p><p>else </p><p>{ </p><p>notenum == 0; </p><p>//sets all three pitch indicator lights off </p><p>digitalWrite(11, LOW); </p><p>digitalWrite(10, LOW); </p><p>digitalWrite(9, LOW); </p><p>} </p><p>} </p><p>//--------------------------------------------------------------------------------------------------- </p><p>// Sets the flat, sharp and spot on frequency thresholds depending on the string we're trying to tune </p><p>void freq_range_identify() </p><p>{ </p><p>switch (notenum) </p><p>{ </p><p>case 1://desired frequency=80-84 -- ideal value is 82 </p><p>minfreq = 80; </p><p>maxfreq = 84; </p><p>break; </p><p>case 2://desired frequency between 108-112 ideal=110 </p><p>minfreq = 108; </p><p>maxfreq = 112; </p><p>break; </p><p>case 3://desired frequency between 145-149 ideal= 147 </p><p>minfreq = 145; </p><p>maxfreq = 149; </p><p>break; </p><p>case 4://desired frequency between 194-198 ideal=196 </p><p>minfreq = 194; </p><p>maxfreq = 198; </p><p>break; </p><p>case 5://desired frequency= 245-249 -- ideal value is 247 </p><p>minfreq = 245; </p><p>maxfreq = 249; </p><p>break; </p><p>case 6: //desired frequency between 328-332 ideal=330 </p><p>minfreq = 328; </p><p>maxfreq = 332; </p><p>//highstring = 1;//stating high string is one being tuned </p><p>break; </p><p>} </p><p>} </p><p>//--------------------------------------------------------------------------------------------------- </p><p>//Sets the 3 appropriate pitch indicator lights and sets the direction and speed of the tuning motor </p><p>void set_indicator_lights() </p><p>{ </p><p>// if (highstring = 1) </p><p>//{ </p><p>// checkfreq(); </p><p>//} </p><p>if (frequency &lt;= basefreq) </p><p>{ </p><p>digitalWrite (11, LOW); </p><p>digitalWrite (10, LOW); </p><p>digitalWrite (9, LOW); </p><p>angle = 90; </p><p>} </p><p>else if (frequency &lt; minfreq &amp;&amp; frequency &gt; basefreq) </p><p>{ </p><p>digitalWrite (11, HIGH); </p><p>digitalWrite (10, LOW); </p><p>digitalWrite (9, LOW); </p><p>angle = countclockwisespeed; </p><p>} </p><p>else if (frequency &gt; maxfreq) </p><p>{ </p><p>digitalWrite (11, LOW); </p><p>digitalWrite (10, LOW); </p><p>digitalWrite (9, HIGH); </p><p>angle = clockwisespeed; </p><p>} </p><p>else </p><p>{ </p><p>digitalWrite (11, LOW); </p><p>digitalWrite (10, HIGH); </p><p>digitalWrite (9, LOW); </p><p>angle = 90; </p><p>delay(1000); </p><p>checkfreq(); </p><p>} </p><p>} </p><p>//--------------------------------------------------------------------------------------------------- </p><p>void checkfreq() </p><p>{ </p><p>frequency = 38462/float(period); //calculate frequency timer rate/period </p><p>Serial.println(&quot;doublecheck&quot;); </p><p>Serial.print(frequency); </p><p>Serial.println(&quot; hz&quot;); </p><p>Serial.println(&quot; &quot;); </p><p>if (frequency &lt;= basefreq) </p><p>{ </p><p>digitalWrite (11, LOW); </p><p>digitalWrite (10, LOW); </p><p>digitalWrite (9, LOW); </p><p>angle = 90; </p><p>} </p><p>else if (frequency &lt; minfreq &amp;&amp; frequency &gt; basefreq) </p><p>{ </p><p>digitalWrite (11, HIGH); </p><p>digitalWrite (10, LOW); </p><p>digitalWrite (9, LOW); </p><p>angle = countclockwisespeed; </p><p>} </p><p>else if (frequency &gt; maxfreq) </p><p>{ </p><p>digitalWrite (11, LOW); </p><p>digitalWrite (10, LOW); </p><p>digitalWrite (9, HIGH); </p><p>angle = clockwisespeed; </p><p>} </p><p>else </p><p>{ </p><p>digitalWrite (11, LOW); </p><p>digitalWrite (10, HIGH); </p><p>digitalWrite (9, LOW); </p><p>angle = 90; </p><p>Serial.println(&quot;String is tuned! Please move on!&quot;); </p><p>Serial.println(&quot; &quot;); </p><p>delay(5000); </p><p>} </p><p>} </p><p>//Turns the tuning motor appropriately </p><p>void move_motor() </p><p>{ </p><p>Servo1.write(angle+trim); </p><p>delay(50); </p><p>Servo1.write(angleStill+trim); </p><p> }</p>
Last time I checked it compiled correctly and worked with the circuit. I will work on cleaning up the code and making a schematic so you can hopefully make your own!
<p>what kind of microphone did you use?</p>
<p>Can anyone link Amanda's stuff on here for me? I'm having trouble finding it</p>
<p>The low E on a guitar is 82.41 Hz. If you go low by 2 Hz (your margin of error) then you end up about halfway to Eb. That quarter tone is *very* noticeable. </p><p>I'm not saying this to discourage you, or discount your work. On the contrary, I think this is a fantastic idea and great work. I just want to see it get even better!</p>
<p>Nice!! What kind of servo motor you have use? and can you get schematics?</p>
<p>Did you ever find out what kind of servo is being used?</p>
<p>no but i used AAS-750MG servo. it has enought torque. </p>
<p>Has anyone been able to replicate this, and if so, how did you wire the 2 pol 6 way switch with the arduino? </p>
<p>wow !!! awesome </p>
Owhhh..hmmm, let say i do exactly your project like on the picture and take your code. Will the project works? Or i need to refer to amandaghassaei's project too?
The audio input and frequency detection I used are identical to amandaghassaei's. I reccommend you follow her instructables to make them, simply because I am working on cleaning up the code and making a schematic so you can make your own. Thanks.
<p>can i get a schematic pls?</p>
I will get on it. Sorry I have been absent, I have been rather busy recently. I will do whatever I can to help! I do not have a schematic, but I will make one. Thanks for your interest!
<p>can i get a schematic pls?</p>
<p>can i get a schematic pls?</p>
<p>can i get a schematic pls?</p>
<p>can i get a schematic pls?</p>
I used amandaghassaei's audio input circuit and arduino frequency detection instructables to both make the Op amp circuit and to code the frequency detection.
Can i know how did you set the frequency of the sound? Is it just set it at the coding of the arduino?
is auwsome :) im interested in your project...can tell more detail about your project that wht kind component you use it? and diagram schematic
post please the electronic diagram or schematic
so glad to see a video of this! love the way you implemented it!
1) Awesome project, very good idea. <br>2) Maybe you could ensure don't put the contraption on a wrong string. A sort of coded switch for each string, in the wood of the guitar where you put the tuner. <br>3) The final result, at 2:09 and more, does not seem the guitar is well tuned.
1) Thank you very much. <br>2) Yes, I have thought of that but I decided against it only because this is a prototype. <br>3) I have done research and asked professional guitarists about the frequency of standard tuning notes. All of these values are plugged into the code, with an acceptance for + or - 2 Hz. The poor audio may be due to a bad camera. Though it may not sound in tune, it is.
Sorry to disappoint you but no, it isn't in tune. I have some experience with the guitars of all kinds (from classic to electric) and that is not in tune, no matter of how poor the camera might be.
If that is your opinion, I am fine with that. <br> <br>There are a couple things that happened during my final test that could have made it sound out of tune: <br> <br>1. A servo motor was turning at the time, causing another background noise to sift through to get to the noise of the guitar. <br>2. I have heavy gauge strings on my guitar so the sound produced (even while not plugged into an amp) is slightly different. <br>3. I was using a metal pick, which also produces a slightly different sound. <br>4. It seems I plucked the strings a little hard. <br> <br>Also, if it means anything, after I made this video and was done tuning my guitar, I played a couple melodies and they sounded in-tune. <br> <br>Anyways, your opinion is none of my concern. Thank you for your interest in my project, though!
Try to pluck the strings softly over the 12th fret. This produces less harmonics.
Here is the code: <br> <br> <br> <br>#include //servo library <br> <br>Servo Servo1; //declaration of servo object <br> <br>int angleStill = 90; //stores servo position <br>int angle = 90; //stores servo position <br>int trim = 0; //trim adjustment to zero position <br> <br>int servoPin = 8; //Arduino pin assigned to servo <br> <br>int clockwisespeed = 120; //the speed to go in the clockwise direction <br>int countclockwisespeed = 60; //the speed to go in the counter clockwise direction <br> <br> <br>boolean clipping = 0; //clipping indicator variables <br> <br>//data storage variables <br>byte newData = 0; <br>byte prevData = 0; <br>unsigned int time = 0;//keeps time and sends values to store in timer[] occasionally <br>int timer[10];//sstorage for timing of events <br>int slope[10];//storage fro slope of events <br>unsigned int totalTimer;//used to calculate period <br>unsigned int period;//storage for period of wave <br>byte index = 0;//current storage index <br>float frequency;//storage for frequency calculations <br>int maxSlope = 0;//used to calculate max slope as trigger point <br>int newSlope;//storage for incoming slope data <br>int minfreq; //it will be changed according to its string <br>int maxfreq; //it will be hanged according to to its string <br>int basefreq = 0; //define baseline noise to ignore any frequency less than this value <br> <br>//int highstring;//says if you are tuning high string or not <br> <br> <br>//variables for decided whether you have a match <br>byte noMatch = 0;//counts how many non-matches you've received to reset variables if it's been too long <br>byte slopeTol = 3;//slope tolerance- adjust this if you need <br>int timerTol = 10;//timer tolerance- adjust this if you need <br> <br>int notenum = 0; //set the guitar string number I want to tune <br>int notenumPrior = 0; //holds the previously selected guitar string <br> <br>//------------------------------------------------------------------------------------------------------------- <br>//all Arduino programs must have a setup routine <br>//Starts Setup routine <br>void setup(){ <br> <br> Serial.begin(9600); //begins sampling the serial port for monitoring purposes <br> <br> pinMode(13, OUTPUT); //clipping indicator <br> pinMode(12, OUTPUT); //wave period indicator <br> pinMode(11, OUTPUT); //freq too low <br> pinMode(10, OUTPUT); //freq spot on <br> pinMode(9, OUTPUT); //freq too high <br> <br> //sets all three pitch indicator lights off <br> digitalWrite(11, LOW); <br> digitalWrite(10, LOW); <br> digitalWrite(9, LOW); <br> <br> pinMode(7, INPUT);// different paths from dip switch indicating the notenum value (output) <br> pinMode(2, INPUT); <br> pinMode(3, INPUT); <br> pinMode(4, INPUT); <br> pinMode(5, INPUT); <br> pinMode(6, INPUT); <br> <br> digitalWrite(7, HIGH);// making sure the input pins are set high, so when pressed they will be on low <br> digitalWrite(2, HIGH); <br> digitalWrite(3, HIGH); <br> digitalWrite(4, HIGH); <br> digitalWrite(5, HIGH); <br> digitalWrite(6, HIGH); <br> <br> Servo1.attach(servoPin); //attaches servo on pin x to servo object <br> <br> <br> <br> <br> //ADC - Handle Analog to Digital Conversion of Guitar Signal <br> cli(); //disables interrupts <br> <br> //set up continuous sampling of analog pin 0 at 38.5kHz <br> <br> //clear ADCSRA and ADCSRB registers <br> ADCSRA = 0; <br> ADCSRB = 0; <br> <br> ADMUX |= (1 &lt;&lt; REFS0); //set reference voltage <br> ADMUX |= (1 &lt;&lt; ADLAR); //left align the ADC value- so we can read highest 8 bits from ADCH register only <br> <br> ADCSRA |= (1 &lt;&lt; ADPS2) | (1 &lt;&lt; ADPS0); //set ADC clock with 32 prescaler- 16mHz/32=500kHz <br> ADCSRA |= (1 &lt;&lt; ADATE); //enabble auto trigger <br> ADCSRA |= (1 &lt;&lt; ADIE); //enable interrupts when measurement complete <br> ADCSRA |= (1 &lt;&lt; ADEN); //enable ADC <br> ADCSRA |= (1 &lt;&lt; ADSC); //start ADC measurements <br> <br> sei();//enable interrupts <br>} <br> <br> <br>//Launch Continuous Interupt Service Routine (ISR) for Sampling Analog to Digital Conversion of Guitar Audio Input <br>ISR(ADC_vect) <br>{//when new ADC value ready <br> <br> PORTB &amp;= B11101111;//set pin 12 low <br> prevData = newData;//store previous value <br> newData = ADCH;//get value from A0 <br> if (prevData &lt; 127 &amp;&amp; newData &gt;=127){//if increasing and crossing midpoint <br> newSlope = newData - prevData;//calculate slope <br> if (abs(newSlope-maxSlope) //record new data and reset time <br> slope[index] = newSlope; <br> timer[index] = time; <br> time = 0; <br> if (index == 0){//new max slope just reset <br> PORTB |= B00010000;//set pin 12 high <br> noMatch = 0; <br> index++;//increment index <br> } <br> else if (abs(timer[0]-timer[index]) //sum timer values <br> totalTimer = 0; <br> for (byte i=0;i totalTimer+=timer[i]; <br> } <br> period = totalTimer;//set period <br> //reset new zero index values to compare with <br> timer[0] = timer[index]; <br> slope[0] = slope[index]; <br> index = 1;//set index to 1 <br> PORTB |= B00010000;//set pin 12 high <br> noMatch = 0; <br> } <br> else{//crossing midpoint but not match <br> index++;//increment index <br> if (index &gt; 9){ <br> reset(); <br> } <br> } <br> } <br> else if (newSlope&gt;maxSlope){//if new slope is much larger than max slope <br> maxSlope = newSlope; <br> time = 0;//reset clock <br> noMatch = 0; <br> index = 0;//reset index <br> } <br> else{//slope not steep enough <br> noMatch++;//increment no match counter <br> if (noMatch&gt;9){ <br> reset(); <br> } <br> } <br> } <br> <br> if (newData == 0 || newData == 1023){//if clipping <br> PORTB |= B00100000;//set pin 13 high- turn on clipping indicator led <br> clipping = 1;//currently clipping <br> } <br> <br> time++;//increment timer at rate of 38.5kHz <br> } <br> //--------------------------------------------------------------------------------------------------- <br> void reset() <br> {//clea out some variables <br> index = 0;//reset index <br> noMatch = 0;//reset match couner <br> maxSlope = 0;//reset slope <br>} <br> <br> <br>//--------------------------------------------------------------------------------------------------- <br>void checkClipping(){//manage clipping indicator LED <br> if (clipping){//if currently clipping <br> PORTB &amp;= B11011111;//turn off clipping indicator led <br> clipping = 0; <br> } <br>} <br> <br> <br> <br>//---------------------------------------------------------------------------------------------- <br>//Start of Main Arduino Loop <br>void loop() // loop <br>{ <br> <br> //highstring = 0; <br> <br> frequency = 38462/float(period); //calculate frequency timer rate/period <br> <br> // added for debugging and visualizing data <br> Serial.print(frequency); <br> Serial.println(&quot; hz&quot;); <br> <br> Serial.println(&quot; &quot;); <br> <br> Serial.println(&quot;string picked: &quot;); <br> Serial.print(notenum); <br> <br> notenum_val(); //call function to determine value of note/string we want to tune <br> <br> <br> freq_range_identify(); //set frequency threshold ranges for string previously selected <br> <br> checkClipping(); //frequency determining and led indicator loop <br> <br> set_indicator_lights(); //checks value of current frequency and lights correct indicator light. Then moves servo accordingly <br> <br> //Serial.println(angle); <br> move_motor(); //move tuning servo motor <br> <br> //delay(1000); //turn on to control debouncing <br> <br> notenumPrior = notenum; <br> <br>} //end of main loop <br> <br> <br> <br>//----------------------------------------------------------------------------------------------- <br>//Determine String selected from rotary switch and voltage values on designated arduino pins <br>void notenum_val() <br>{ <br> int val_1 = digitalRead(2); //read the value of rotary switch pins <br> int val_2 = digitalRead(3); <br> int val_3 = digitalRead(4); <br> int val_4 = digitalRead(5); <br> int val_5 = digitalRead(6); <br> int val_6 = digitalRead(7); <br> <br> if (val_1 == LOW &amp;&amp; val_2 == HIGH &amp;&amp; val_3 == HIGH &amp;&amp; val_4 == HIGH &amp;&amp; val_5 == HIGH &amp;&amp; val_6 == HIGH) //switch set on pressed, then notenum = 1 <br> { <br> if (notenumPrior != 1) <br> { <br> delay(5000); <br> notenum = 1; <br> } <br> else <br> { <br> notenum = 1; <br> } <br> } <br> else if (val_1 == HIGH &amp;&amp; val_2 == LOW &amp;&amp; val_3 == HIGH &amp;&amp; val_4 == HIGH &amp;&amp; val_5 == HIGH &amp;&amp; val_6 == HIGH) //Switch 3 pressed, noenum = 2 <br> { <br> if (notenumPrior != 2 ) <br> { <br> delay(5000); <br> notenum = 2; <br> } <br> else <br> { <br> notenum = 2; <br> } <br> } <br> else if (val_1 == HIGH &amp;&amp; val_2 == HIGH &amp;&amp; val_3 == LOW &amp;&amp; val_4 == HIGH &amp;&amp; val_5 == HIGH &amp;&amp; val_6 == HIGH) //switch 4 pressed, notenum = 3 <br> { <br> if (notenumPrior != 3) <br> { <br> delay(5000); <br> notenum = 3; <br> } <br> else <br> { <br> notenum = 3; <br> } <br> } <br> else if (val_1 == HIGH &amp;&amp; val_2 == HIGH &amp;&amp; val_3 == HIGH &amp;&amp; val_4 == LOW &amp;&amp; val_5 == HIGH &amp;&amp; val_6 == HIGH) //switch 5 pressed, notenum = 4 <br> { <br> if (notenumPrior != 4) <br> { <br> delay(5000); <br> notenum = 4; <br> } <br> else <br> { <br> notenum = 4; <br> } <br> } <br> else if (val_1 == HIGH &amp;&amp; val_2 == HIGH &amp;&amp; val_3 == HIGH &amp;&amp; val_4 == HIGH &amp;&amp; val_5 == LOW &amp;&amp; val_6 == HIGH) //switch 6 pressed, notenum = 5 <br> { <br> if (notenumPrior != 5) <br> { <br> delay(5000); <br> notenum = 5; <br> } <br> else <br> { <br> notenum = 5; <br> } <br> } <br> else if (val_1 == HIGH &amp;&amp; val_2 == HIGH &amp;&amp; val_3 == HIGH &amp;&amp; val_4 == HIGH &amp;&amp; val_5 == HIGH &amp;&amp; val_6 == LOW) //switch 7 pressed, notenum = 6 <br> { <br> if (notenumPrior != 6) <br> { <br> delay(5000); <br> notenum = 6; <br> } <br> else <br> { <br> notenum = 6; <br> } <br> } <br> else <br> { <br> notenum == 0; <br> <br> //sets all three pitch indicator lights off <br> digitalWrite(11, LOW); <br> digitalWrite(10, LOW); <br> digitalWrite(9, LOW); <br> } <br>} <br> <br>//--------------------------------------------------------------------------------------------------- <br>// Sets the flat, sharp and spot on frequency thresholds depending on the string we're trying to tune <br>void freq_range_identify() <br> <br>{ <br> switch (notenum) <br> { <br> case 1://desired frequency=80-84 -- ideal value is 82 <br> minfreq = 80; <br> maxfreq = 84; <br> break; <br> case 2://desired frequency between 108-112 ideal=110 <br> minfreq = 108; <br> maxfreq = 112; <br> break; <br> case 3://desired frequency between 145-149 ideal= 147 <br> minfreq = 145; <br> maxfreq = 149; <br> break; <br> case 4://desired frequency between 194-198 ideal=196 <br> minfreq = 194; <br> maxfreq = 198; <br> break; <br> case 5://desired frequency= 245-249 -- ideal value is 247 <br> minfreq = 245; <br> maxfreq = 249; <br> break; <br> case 6: //desired frequency between 328-332 ideal=330 <br> minfreq = 328; <br> maxfreq = 332; <br> //highstring = 1;//stating high string is one being tuned <br> break; <br> } <br>} <br>//--------------------------------------------------------------------------------------------------- <br>//Sets the 3 appropriate pitch indicator lights and sets the direction and speed of the tuning motor <br>void set_indicator_lights() <br>{ <br> <br> // if (highstring = 1) <br> //{ <br> // checkfreq(); <br> //} <br> <br> if (frequency &lt;= basefreq) <br> { <br> digitalWrite (11, LOW); <br> digitalWrite (10, LOW); <br> digitalWrite (9, LOW); <br> <br> angle = 90; <br> } <br> else if (frequency &lt; minfreq &amp;&amp; frequency &gt; basefreq) <br> { <br> digitalWrite (11, HIGH); <br> digitalWrite (10, LOW); <br> digitalWrite (9, LOW); <br> <br> angle = countclockwisespeed; <br> } <br> else if (frequency &gt; maxfreq) <br> { <br> digitalWrite (11, LOW); <br> digitalWrite (10, LOW); <br> digitalWrite (9, HIGH); <br> <br> angle = clockwisespeed; <br> } <br> else <br> { <br> digitalWrite (11, LOW); <br> digitalWrite (10, HIGH); <br> digitalWrite (9, LOW); <br> <br> angle = 90; <br> <br> delay(1000); <br> <br> checkfreq(); <br> } <br>} <br>//--------------------------------------------------------------------------------------------------- <br> <br> <br> <br>void checkfreq() <br>{ <br> frequency = 38462/float(period); //calculate frequency timer rate/period <br> <br> Serial.println(&quot;doublecheck&quot;); <br> Serial.print(frequency); <br> Serial.println(&quot; hz&quot;); <br> <br> Serial.println(&quot; &quot;); <br> <br> if (frequency &lt;= basefreq) <br> { <br> digitalWrite (11, LOW); <br> digitalWrite (10, LOW); <br> digitalWrite (9, LOW); <br> <br> angle = 90; <br> } <br> else if (frequency &lt; minfreq &amp;&amp; frequency &gt; basefreq) <br> { <br> digitalWrite (11, HIGH); <br> digitalWrite (10, LOW); <br> digitalWrite (9, LOW); <br> <br> angle = countclockwisespeed; <br> } <br> else if (frequency &gt; maxfreq) <br> { <br> digitalWrite (11, LOW); <br> digitalWrite (10, LOW); <br> digitalWrite (9, HIGH); <br> <br> angle = clockwisespeed; <br> } <br> else <br> { <br> digitalWrite (11, LOW); <br> digitalWrite (10, HIGH); <br> digitalWrite (9, LOW); <br> <br> angle = 90; <br> <br> <br> Serial.println(&quot;String is tuned! Please move on!&quot;); <br> Serial.println(&quot; &quot;); <br> <br> delay(5000); <br> } <br>} <br> <br> <br> <br> <br> <br> <br> <br>//Turns the tuning motor appropriately <br>void move_motor() <br>{ <br> Servo1.write(angle+trim); <br> delay(50); <br> Servo1.write(angleStill+trim); <br>} <br> <br> <br> <br> <br> <br>
Code?
https://www.instructables.com/files/deriv/F67/LTKF/HKM94B2Q/F67LTKFHKM94B2Q.SQUARE.jpg <br> <br>This is a picture of my contraption, since you can't really see it in the video

About This Instructable

12,424views

28favorites

More by angrycho:Automatic Guitar Tuner 
Add instructable to: