Arduino Guitar Tuner
Intro: Arduino Guitar Tuner
Build your own electric guitar tuner using the Arduino! I decided to make this because I wanted to experiment with audio input and frequency detection. I used Amanda Ghassaei's method for Arduino Frequency Detection in order to get frequency readings using the Arduino. I used LEDs that light up according to the frequency of the audio input, indicating whether the string being played is sharp, flat, or in tune. This works like any other guitar tuner, but you can make it yourself!
STEP 1: What You Need
(x1) Arduino Uno (RadioShack #276-128)
(x1) TL082 Dual JFET Input Op Amp (RadioShack #276-1715)
(x1) 6x4x2" project enclosure (RadioShack #270-1806)
(x6) 5mm Yellow LED (RadioShack #276-021)
(x6) 5mm Red LED (RadioShack #276-041)
(x1) 5mm Green LED (RadioShack #276-022)
(x13) 150 Ohm Resistor (RadioShack #271-1109)
(x2) 9V Battery (RadioShack #23-1134)
(x2) 9V Snap Connector (RadioShack #270-324)
(x1) M-type power plug (RadioShack #274-1569)
(x1) SPST Rocker Switch (RadioShack #275-693)
(x1) 1/4" Mono Audio Jack (RadioShack #274-255)
(x1) Matching Printed Circuit Board (RadioShack #276-170)
(x1) Grid-Style Printed Circuit Board (RadioShack #276-149)
(x3) 100kOhm Resistor (RadioShack #271-1347)
(x1) 22kOhm Resistor (RadioShack #271-1339)
(x1) 10uF Capacitor (RadioShack #272-1025)
(x1) 100nF Capacitor
(x1) 6x4x.125" Acrylic Sheet
(x1) TL082 Dual JFET Input Op Amp (RadioShack #276-1715)
(x1) 6x4x2" project enclosure (RadioShack #270-1806)
(x6) 5mm Yellow LED (RadioShack #276-021)
(x6) 5mm Red LED (RadioShack #276-041)
(x1) 5mm Green LED (RadioShack #276-022)
(x13) 150 Ohm Resistor (RadioShack #271-1109)
(x2) 9V Battery (RadioShack #23-1134)
(x2) 9V Snap Connector (RadioShack #270-324)
(x1) M-type power plug (RadioShack #274-1569)
(x1) SPST Rocker Switch (RadioShack #275-693)
(x1) 1/4" Mono Audio Jack (RadioShack #274-255)
(x1) Matching Printed Circuit Board (RadioShack #276-170)
(x1) Grid-Style Printed Circuit Board (RadioShack #276-149)
(x3) 100kOhm Resistor (RadioShack #271-1347)
(x1) 22kOhm Resistor (RadioShack #271-1339)
(x1) 10uF Capacitor (RadioShack #272-1025)
(x1) 100nF Capacitor
(x1) 6x4x.125" Acrylic Sheet
STEP 2: Drill
Drill a starter hole on the side of your enclosure using a 1/8" drill bit. Drill into the starter hole using a 13/16" spade bit to create a larger hole for the SPST rocker switch. The rocker switch will serve as an on/off switch for the tuner.
Drill a hole beneath the on/off switch hole using a 23/64" bit. This hole is for your audio jack.
Drill a hole beneath the on/off switch hole using a 23/64" bit. This hole is for your audio jack.
STEP 3: On/Off Switch
Solder the red end of one of your battery snaps to one of the lugs on the switch and solder a red wire to the other lug of the switch.
Feed the snap and wire through the 13/16" hole in your enclosure and fasten it in place with its mounting nut.
Feed the snap and wire through the 13/16" hole in your enclosure and fasten it in place with its mounting nut.
STEP 4: Audio Jack
Solder a green wire to the output terminal and a black wire to the ground terminal on the audio jack.
Insert the audio jack in the 23/64" hole you drilled and fasten it in place with its mounting nut and washer.
Insert the audio jack in the 23/64" hole you drilled and fasten it in place with its mounting nut and washer.
STEP 5: Power Plug
Take apart the M-type power plug.
Solder a red wire to the plug's tip terminal, and a black wire to the plug's barrel terminal.
Thread both wires through the black casing and screw the casing back onto the plug.
Solder a red wire to the plug's tip terminal, and a black wire to the plug's barrel terminal.
Thread both wires through the black casing and screw the casing back onto the plug.
STEP 6: Amplify and Offset
The audio signal coming from the electric guitar needs to be amplified to be about 5V peak to peak and and offset to be centered around 2.5V as opposed to 0V. The signal needs to be between 0 and 5V in order for it to be read by the Arduino's analog pin. It should also have the greatest amplitude possible without clipping in order to get more accurate frequency calculations.
Above is a schematic of the circuit you will need to do this.
I recommend building this circuit on a breadboard and testing it out using an oscilloscope before soldering it together. Your audio input should be the green wire of the audio jack. Connect the black wire of the jack to ground. Attach your scope probe to the output of the DC offset (where the circuit is attached to A0 on the Arduino). Turn the volume on your guitar all the way up and plug your guitar into the audio jack. Play every string and check on the oscilloscope to make sure your signal is centered around 2.5V and that the signal is close to but does not exceed 5V peak to peak.
Try running this modified version of Amanda's code for Arduino Frequency Detection to test out the Arduino's frequency calculation. The only thing I have changed from her code is I removed the clipping indicator LED and instead printed "clipping" in the serial monitor whenever the signal clips.
The serial monitor should print the frequency of the strings being played. The guitar's strings should have the following frequencies:
E - 82.4 Hz
A - 110 Hz
D - 146.8 Hz
G - 196 Hz
B - 246.9 Hz
E - 329.6 Hz
Since the the higher strings have a much lower amplitude signal than the lower strings, it can be tricky to get the frequency detection to work. Amanda's code has a variable called ampThreshold that is the minimum signal amplitude for the Arduino to calculate frequency. For the guitar tuner, the ampThreshold should be high enough that the Arduino calculates the frequency of the higher strings, but also low enough that it does not pick up too much noise from the lower strings. I found that an ampThreshold of 20 works. You have to strum the high strings a bit harder to get the Arduino to pick them up, but the frequency detection works well. You can experiment with other values to get it to work for you. Values ranging from 10 to 30 work okay. For more information on Amanda's algorithm for frequency detection, check out her Instructable: Arduino Frequency Detection.
Above is a schematic of the circuit you will need to do this.
I recommend building this circuit on a breadboard and testing it out using an oscilloscope before soldering it together. Your audio input should be the green wire of the audio jack. Connect the black wire of the jack to ground. Attach your scope probe to the output of the DC offset (where the circuit is attached to A0 on the Arduino). Turn the volume on your guitar all the way up and plug your guitar into the audio jack. Play every string and check on the oscilloscope to make sure your signal is centered around 2.5V and that the signal is close to but does not exceed 5V peak to peak.
Try running this modified version of Amanda's code for Arduino Frequency Detection to test out the Arduino's frequency calculation. The only thing I have changed from her code is I removed the clipping indicator LED and instead printed "clipping" in the serial monitor whenever the signal clips.
/* * Modified Arduino Frequency Detection * by Nicole Grimwood * * For more information please visit: * https://www.instructables.com/id/Arduino-Guitar-Tuner/ * * * Slightly edited version of: * Arduino Frequency Detection * created October 7, 2012 * by Amanda Ghassaei * * This code is in the public domain. */ //clipping indicator variables boolean clipping = 0; //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];//storage for timing of events int slope[10];//storage for slope of events unsigned int totalTimer;//used to calculate period 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 void setup(){ Serial.begin(9600); pinMode(13,OUTPUT);//led indicator pin 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 << ADPS2) | (1 << ADPS0); //set ADC clock with 32 prescaler- 16mHz/32=500kHz 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 } 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(); } } } 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 clipping = 1;//currently clipping Serial.println("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(){//clean out some variables index = 0;//reset index noMatch = 0;//reset match couner maxSlope = 0;//reset slope } void checkClipping(){//manage clipping indication if (clipping){//if currently clipping clipping = 0; } } void loop(){ checkClipping(); if (checkMaxAmp>ampThreshold){ frequency = 38462/float(period);//calculate frequency timer rate/period //print results Serial.print(frequency); Serial.println(" hz"); } delay(100); }
The serial monitor should print the frequency of the strings being played. The guitar's strings should have the following frequencies:
E - 82.4 Hz
A - 110 Hz
D - 146.8 Hz
G - 196 Hz
B - 246.9 Hz
E - 329.6 Hz
Since the the higher strings have a much lower amplitude signal than the lower strings, it can be tricky to get the frequency detection to work. Amanda's code has a variable called ampThreshold that is the minimum signal amplitude for the Arduino to calculate frequency. For the guitar tuner, the ampThreshold should be high enough that the Arduino calculates the frequency of the higher strings, but also low enough that it does not pick up too much noise from the lower strings. I found that an ampThreshold of 20 works. You have to strum the high strings a bit harder to get the Arduino to pick them up, but the frequency detection works well. You can experiment with other values to get it to work for you. Values ranging from 10 to 30 work okay. For more information on Amanda's algorithm for frequency detection, check out her Instructable: Arduino Frequency Detection.
STEP 7: Solder the Chip
Solder the TL082 to the grid-style PC board.
STEP 8: Solder the Amplifier and Offset
Solder the resistors for the amplifier and a wire for the output from the amplifier.
Solder the capacitors and resistors for the DC offset.
Solder wires to the DC offset that will connect to 5V, ground, and A0 on the Arduino.
Solder the capacitors and resistors for the DC offset.
Solder wires to the DC offset that will connect to 5V, ground, and A0 on the Arduino.
STEP 9: Solder Power and Input
Solder the red wire on the on/off switch to +VCC (pin 8) on the TL082 chip. Solder the black wire to ground.
Solder the black wire of the other battery snap to -VCC (pin 4) on the TL082 chip and solder the red wire to ground.
Solder the green wire of the audio jack to the positive input of the op amp on the TL082 (pin 3) and the black wire to ground.
Solder the red wire of the power plug to +VCC (pin 8) and the black wire to ground and insert the plug in the Arduino.
Plug the wires for 5V, Ground, and A0 from the DC Offset into the Arduino.
Solder the black wire of the other battery snap to -VCC (pin 4) on the TL082 chip and solder the red wire to ground.
Solder the green wire of the audio jack to the positive input of the op amp on the TL082 (pin 3) and the black wire to ground.
Solder the red wire of the power plug to +VCC (pin 8) and the black wire to ground and insert the plug in the Arduino.
Plug the wires for 5V, Ground, and A0 from the DC Offset into the Arduino.
STEP 10: Program
Load the following code into the Arduino.
This code contains the frequency detection and controls the LEDs that you will soon add to your tuner.
<pre>/* * Arduino Guitar Tuner * by Nicole Grimwood * * For more information please visit: * https://www.instructables.com/id/Arduino-Guitar-Tuner/ * * Based upon: * Arduino Frequency Detection * created October 7, 2012 * by Amanda Ghassaei * * This code is in the public domain. */ //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];//storage for timing of events int slope[10];//storage for slope of events unsigned int totalTimer;//used to calculate period 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 deciding 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 //variables for tuning int correctFrequency;//the correct frequency for the string being played void setup(){ Serial.begin(9600); //LED pins pinMode(7,OUTPUT); pinMode(6,OUTPUT); pinMode(5,OUTPUT); pinMode(4,OUTPUT); pinMode(3,OUTPUT); pinMode(2,OUTPUT); pinMode(A3,OUTPUT); pinMode(A4,OUTPUT); pinMode(A5,OUTPUT); pinMode(A1,OUTPUT); pinMode(A2,OUTPUT); pinMode(8,OUTPUT); pinMode(9,OUTPUT); //Beginning LED sequence digitalWrite(7,1); digitalWrite(6,1); digitalWrite(5,1); digitalWrite(4,1); digitalWrite(3,1); digitalWrite(2,1); digitalWrite(8,1); analogWrite(A1,255); delay(500); digitalWrite(9,1); analogWrite(A2,255); delay(500); digitalWrite(A5,255); analogWrite(A3,255); delay(500); analogWrite(A4,255); delay(500); cli();//disable 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 << ADPS2) | (1 << ADPS0); //set ADC clock with 32 prescaler- 16mHz/32=500kHz 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 } 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(); } } } 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(); } } } 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(){//clean out some variables index = 0;//reset index noMatch = 0;//reset match couner maxSlope = 0;//reset slope } //Turn off 5 out the 6 LEDs for the guitar strings void otherLEDsOff(int LED1, int LED2,int LED3,int LED4,int LED5){ digitalWrite(LED1,0); digitalWrite(LED2,0); digitalWrite(LED3,0); digitalWrite(LED4,0); digitalWrite(LED5,0); } //Determine the correct frequency and light up //the appropriate LED for the string being played void stringCheck(){ if(frequency>70&frequency<90){ otherLEDsOff(2,3,5,6,7); digitalWrite(2,1); correctFrequency = 82.4; } if(frequency>100&frequency<120){ otherLEDsOff(2,3,4,5,6); digitalWrite(3,1); correctFrequency = 110; } if(frequency>135&frequency<155){ otherLEDsOff(2,3,4,6,7); digitalWrite(4,1); correctFrequency = 146.8; } if(frequency>186&frequency<205){ otherLEDsOff(2,3,5,6,7); digitalWrite(5,1); correctFrequency = 196; } if(frequency>235&frequency<255){ otherLEDsOff(2,4,5,6,7); digitalWrite(6,1); correctFrequency = 246.9; } if(frequency>320&frequency<340){ otherLEDsOff(3,4,5,6,7); digitalWrite(7,1); correctFrequency = 329.6; } } //Compare the frequency input to the correct //frequency and light up the appropriate LEDS void frequencyCheck(){ if(frequency>correctFrequency+1){ analogWrite(A3,255); } if(frequency>correctFrequency+4){ analogWrite(A2,255); } if(frequency>correctFrequency+6){ analogWrite(A1,255); } if(frequency<correctFrequency-1){ analogWrite(A5,255); } if(frequency<correctFrequency-4){ digitalWrite(9,1); } if(frequency<correctFrequency-6){ digitalWrite(8,1); } if(frequency>correctFrequency-1&frequency<correctFrequency+1){ analogWrite(A4,255); } } void allLEDsOff(){ digitalWrite(2,0); digitalWrite(3,0); digitalWrite(4,0); digitalWrite(5,0); digitalWrite(6,0); digitalWrite(7,0); digitalWrite(8,0); digitalWrite(9,0); analogWrite(A1,0); analogWrite(A2,0); analogWrite(A3,0); analogWrite(A4,0); analogWrite(A5,0); } void loop(){ allLEDsOff(); if (checkMaxAmp>ampThreshold){ frequency = 38462/float(period);//calculate frequency timer rate/period } stringCheck(); frequencyCheck(); delay(100); }
STEP 11: Create the Front
For my guitar tuner, I chose to laser cut the front of it. I like the look of the white acrylic and the ability to etch the letters and symbols on the front. I have attached a template for the front of the guitar tuner. I used CorelDRAW to create it, but I have also attached it in EPS format.
If you do not have a laser cutter, you can use the normal lid for the enclosure and drill holes into it. Use a 13/64" drill bit and drill six holes for the LEDs indicating which of the six different strings is being tuned and seven holes for the LEDs indicating how sharp or flat the string is. Label the set of six holes with E, A, D, G, B, and E from left to right. Label the middle hole of the set of seven with a triangle pointed toward the hole. Label the rightmost hole with the musical symbol for sharp and the leftmost hole with the musical symbol for flat.
If you do not have a laser cutter, you can use the normal lid for the enclosure and drill holes into it. Use a 13/64" drill bit and drill six holes for the LEDs indicating which of the six different strings is being tuned and seven holes for the LEDs indicating how sharp or flat the string is. Label the set of six holes with E, A, D, G, B, and E from left to right. Label the middle hole of the set of seven with a triangle pointed toward the hole. Label the rightmost hole with the musical symbol for sharp and the leftmost hole with the musical symbol for flat.
STEP 12: LEDs
Solder LEDs to your matching PC board. Space the LEDs such that they will fit into the holes of your acrylic front piece. An easy way to do this is lay the front piece on top of your PC board and mark the spacings of the holes on your board using a pen. This way, you know exactly where to solder your LEDs.
Solder a 150 Ohm resistor to the anode of each LED and a wire from that resistor which will go to one of the pins on the Arduino.
I chose red wire for the LEDs indicating whether the string is in tune and green wire for the LEDs that show which string is being played.
Solder the cathodes of the LEDs to ground and solder a black wire to ground. This black wire will connect to the Arduino's ground.
Solder a 150 Ohm resistor to the anode of each LED and a wire from that resistor which will go to one of the pins on the Arduino.
I chose red wire for the LEDs indicating whether the string is in tune and green wire for the LEDs that show which string is being played.
Solder the cathodes of the LEDs to ground and solder a black wire to ground. This black wire will connect to the Arduino's ground.
STEP 13: Put It Together
Place the front cover of the tuner onto the PC board with the LEDs.
Connect the wires on the PC board to the Arduino. The following list indicates which LED should be connected to which pin.
leftmost red LED (most flat)- pin 8
next red LED to the right - pin 9
next red LED to the right - A5
green LED (in tune) - A4
first red LED to the right of the green LED - A3
next red LED to the right - A2
rightmost red LED (most sharp) - A1
Leftmost LED Labeled "E" - pin 2
LED Labeled "A" - pin 3
LED Labeled "D" - pin 4
LED Labeled "G" - pin 5
LED Labeled "B" - pin 6
Rightmost LED Labeled "E" - pin 7
There are also labels on the second image above to help.
The black wire on the PC board should be connected to ground on the Arduino.
Turn on the tuner and test it out in order to make sure you have your LEDs connected properly.
Connect the wires on the PC board to the Arduino. The following list indicates which LED should be connected to which pin.
leftmost red LED (most flat)- pin 8
next red LED to the right - pin 9
next red LED to the right - A5
green LED (in tune) - A4
first red LED to the right of the green LED - A3
next red LED to the right - A2
rightmost red LED (most sharp) - A1
Leftmost LED Labeled "E" - pin 2
LED Labeled "A" - pin 3
LED Labeled "D" - pin 4
LED Labeled "G" - pin 5
LED Labeled "B" - pin 6
Rightmost LED Labeled "E" - pin 7
There are also labels on the second image above to help.
The black wire on the PC board should be connected to ground on the Arduino.
Turn on the tuner and test it out in order to make sure you have your LEDs connected properly.
STEP 14: Close It Up
Gently put the front of the tuner onto the front of the enclosure making sure that none of the wires get disconnected.
Screw in the screws provided with the enclosure to fix the front in place.
Screw in the screws provided with the enclosure to fix the front in place.
STEP 15: Tune
Plug in your guitar and tune it!
118 Comments
Merlin04 7 years ago
I am unable to get the serial monitor to display any information. Is there any way to fix this? I need this for a science project.
Merlin04 7 years ago
I was able to get serial monitor output, but it is very different from the expected output. No matter how much I turn the gain dial, I always see "clipping". I also see "Inf hz". Why is this?
jersaucey 5 months ago
MaximilianoR16 6 years ago
Hello, I'm using: Serial.println(frequency); on loop program area with a Delay(100);, and it's shows the frequency on Serial monitor. try it.
UğurK30 4 years ago
jersaucey 5 months ago
Jeger 12 months ago
JanainaF 7 years ago
I'm trying to adapt a lcd screen to this project but I cant seem to figure the code out.
I have checked everything multiple times but wasn't able to find whats wrong and why isn't this working. Everythig seems to be working fine with the leds but when I try to use the lcd screen it shows nothing.
I have included the LiquidCrystal on the begining of the code and lcd.begin(16,2); in the setup, this was the other change I did in the code:
"void stringCheck(){
if(frequency>70&frequency<90){
lcd.print("E");
correctFrequency = 82.4;
}
if(frequency>100&frequency<120){
lcd.print("A");
correctFrequency = 110;
}
if(frequency>135&frequency<155){
lcd.print("D");
correctFrequency = 146.8;
}
if(frequency>186&frequency<205){
lcd.print("G");
correctFrequency = 196;
}
if(frequency>235&frequency<255){
lcd.print("B");
correctFrequency = 246.9;
}
if(frequency>320&frequency<340){
lcd.print("e");
correctFrequency = 329.6;
}
}
//Compare the frequency input to the correct
//frequency and light up the appropriate LEDS
void frequencyCheck(){
if(frequency>correctFrequency+1){
lcd.setCursor(0,1);
lcd.print(">");
}
if(frequency>correctFrequency+4){
lcd.setCursor(0,1);
lcd.print(">>");
}
if(frequency>correctFrequency+6){
lcd.setCursor(0,1);
lcd.print(">>>");
}
if(frequency<correctFrequency-1){
lcd.setCursor(0,1);
lcd.print("<");
}
if(frequency<correctFrequency-4){
lcd.setCursor(0,1);
lcd.print("<<");
}
if(frequency<correctFrequency-6){
lcd.setCursor(0,1);
lcd.print("<<<");
}
if(frequency>correctFrequency-1&frequency<correctFrequency+1){
lcd.setCursor(0,1);
lcd.print("OK!");
}
}
void loop(){
lcd.clear();
"
Thanks for the project! If someone could help me it would be awesome =)
jackseling 7 years ago
dude i had the same problem using LCD have you figure it out.. Could u send me the correct code
pope54 10 months ago
JanainaF 7 years ago
#include
//variaveis para armazenar dados
byte newData = 0;
byte prevData = 0;
unsigned int time = 0;//armazena o tempo e envia valores para o vetor time
int timer[10];//vetor que armazena o tempo dos eventos
int slope[10];//vetor que armazena a inclinacao dos eventos
unsigned int totalTimer;//usado para calcular o periodo
unsigned int period;//armazena o periodo
byte index = 0;//indice atual
float frequency;//frequencia
int maxSlope = 0;//usado para o calculo da inclinação máxima como trigger
int newSlope;//armazenamento de novas inclinacoes
//variáveis para comparacao
byte noMatch = 0;//conta quantos valores diferentes foram recebidos para resetar as variaveis
byte slopeTol = 3;//tolerancia da inclinacao (pode ser ajustada)
int timerTol = 10;//tolerancia de tempo (pode ser ajustada)
//variaveis para deteccao da amplitude
unsigned int ampTimer = 0;
byte maxAmp = 0;
byte checkMaxAmp;
byte ampThreshold = 30;//aumentar caso o ruido seja muito grande
//variaveis para o afinador
int correctFrequency;//frequencia correta da corda tocada
LiquidCrystal lcd(13, 11, 5, 4, 3, 2);
void setup(){
lcd.begin(16,2);
Serial.begin(9600);
lcd.print("Afinador");
lcd.setCursor(0,1);
lcd.print("<<<<<< oo >>>>>>");
delay(5000);
lcd.clear();
cli();//desabilita interrupcoes(time sensitive)
//da uma amostra do pino 0 com frequencia 38.5kHz
//limpa os registradores ADCSRA e ADCSRB
ADCSRA = 0;
ADCSRB = 0;
ADMUX |= (1 << REFS0); //tensao de referencia
ADMUX |= (1 << ADLAR); //alinhamento à esqueda do valor de ADC
// so eh possivel ler os maiores 8bits do registrador ADCH
ADCSRA |= (1 << ADPS2) | (1 << ADPS0); //clock do ADC com 32 escalas- 16mHz/32=500kHz
ADCSRA |= (1 << ADATE); //habilita auto trigger
ADCSRA |= (1 << ADIE); //habilita interrupcoes quando a medida foi completa
ADCSRA |= (1 << ADEN); //habilita ADC
ADCSRA |= (1 << ADSC); //habilita medidas ADC
sei();//habilita interrupcoes
}
ISR(ADC_vect) {//quando um valor novo de ADC está pronto
PORTB &= B11101111;//pino 12 em low
prevData = newData;//armazena dado anterior
newData = ADCH;//novo valor de A0
if (prevData < 127 && newData >=127){//se aumentando ao passar por 2.5v
newSlope = newData - prevData;//calcular inclinacao
if (abs(newSlope-maxSlope) //armazenar os dados e zerar o tempo
slope[index] = newSlope;
timer[index] = time;
time = 0;
if (index == 0){//resetar se a inclinacao eh nova
PORTB |= B00010000;//pino 12 no high
noMatch = 0;
index++;//aumenta o indice
}
else if (abs(timer[0]-timer[index]) //se o tempo e a inclinacao sao iguais aos valores iniciais
//somar os valores do tempo
totalTimer = 0;
for (byte i=0;i totalTimer+=timer[i];
}
period = totalTimer;//periodo
//reseta novo indice zero para comparacao
timer[0] = timer[index];
slope[0] = slope[index];
index = 1;
PORTB |= B00010000;//pino 12 high
noMatch = 0;
}
else{//cruza a linha de 2.5v mas nao deve ser armazenado(nao eh match)
index++;//aumenta o indice
if (index > 9){
reset();
}
}
}
else if (newSlope>maxSlope){//se a inclinacao eh muito maior que a inclinacao max
maxSlope = newSlope;
time = 0;//reseta o clock
noMatch = 0;
index = 0;//reseta indice
}
else{//inclinacao menor que o esperado
noMatch++;//aumenta o contador do noMatch
if (noMatch>9){
reset();
}
}
}
time++;//aumenta o timer em uma taxa de 38.5kHz
ampTimer++;//aumenta o timer da amplitude
if (abs(127-ADCH)>maxAmp){
maxAmp = abs(127-ADCH);
}
if (ampTimer==1000){
ampTimer = 0;
checkMaxAmp = maxAmp;
maxAmp = 0;
}
}
void reset(){//limpa algumas variaveis
index = 0;//reseta o indice
noMatch = 0;//reseta o contador de noMatch
maxSlope = 0;//reseta inclinacao
}
//Determina a frequência correta
void stringCheck(){
lcd.setCursor(0,0);
if(frequency>70&frequency<90){
lcd.print("Corda E . E (mi)");
correctFrequency = 82.4;
}
if(frequency>100&frequency<120){
lcd.print("Corda A . A (la)");
correctFrequency = 110;
}
if(frequency>135&frequency<155){
lcd.print("Corda D . D (re)");
correctFrequency = 146.8;
}
if(frequency>186&frequency<205){
lcd.print("Corda G . G (sol)");
correctFrequency = 196;
}
if(frequency>235&frequency<255){
lcd.print("Corda B . B (si)");
correctFrequency = 246.9;
}
if(frequency>320&frequency<340){
lcd.print("Corda e . e (mi)");
correctFrequency = 329.6;
}
}
//Compara a frequencia de entrada com a
//frequencia correta para determinar o ajuste
void frequencyCheck(){
if(frequency>correctFrequency+1){
lcd.setCursor(0,1);
lcd.print(" << ");
}
if(frequency>correctFrequency+6){
lcd.setCursor(0,1);
lcd.print("<<<<<< ");
}
if(frequency lcd.setCursor(0,1);
lcd.print(" >> ");
}
if(frequency lcd.setCursor(0,1);
lcd.print(" >>>>>>");
}
if(frequency>correctFrequency-1&frequency lcd.setCursor(0,1);
lcd.print(" oo ");
}
}
void loop(){
if (checkMaxAmp>ampThreshold){
frequency = 38462/float(period);
//calcula a frequencia taxa do timer/periodo
}
stringCheck();
frequencyCheck();
delay(100);
lcd.clear();
}
jackseling 7 years ago
sory for the late reply thought u never reply so u mean we have to use other lcd not the 12 pin lcd....lol so sad i have the 12 pin lcd
pope54 10 months ago
void allLEDsOff with this frequency=0.
jinda48473 11 months ago
adryrico1 2 years ago
El mismo circuito vale usando una sola pila de 9v? ¿Porque son necesarias las dos pilas?
mitt7575 11 months ago
KrzysiekW 1 year ago
mitt7575 11 months ago
arduino97 5 years ago
hairulamri123 4 years ago