hi,
I have written a code for a automatic guitar tuner and i have built an amplifying circuit as i have a lead which is connected to the arduino from the 6.35mm jack of the guitar. When i pluck the string i have written the code so that it should detect what string is being played and then it should calculate the frequency the string is at now and what frequency the string should be at in order to turn the tuning peg a certain way to tune it. Nevertheless i am having issues when i upload the code i cannot seem to get the servo to turn at all i have copied and pasted the code i have used below if anyone can look through it and suggest improvements it would be greatly appreciated.
#include //servo library
Servo Servo1; //declaration of servo object
int angleStill = 90; //stores servo position
int angle = 90; //stores servo position
int trim = 0; //trim adjustment to zero position
int servoPin = 8; //Arduino pin assigned to servo
int clockwisespeed = 120; //the speed to go in the clockwise direction
int countclockwisespeed = 60; //the speed to go in the counter clockwise direction
boolean clipping = 0; //clipping indicator variables
//data storage variables
byte newData = 0;
byte prevData = 0;
unsigned int time = 0;//keeps time and sends values to store in timer[] occasionally
int timer[10];//sstorage for timing of events
int slope[10];//storage fro 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
int minfreq; //it will be changed according to its string
int maxfreq; //it will be hanged according to to its string
int basefreq = 0; //define baseline noise to ignore any frequency less than this value
//int highstring;//says if you are tuning high string or not
//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
int notenum = 0; //set the guitar string number I want to tune
int notenumPrior = 0; //holds the previously selected guitar string
//-------------------------------------------------------------------------------------------------------------
//all Arduino programs must have a setup routine
//Starts Setup routine
void setup(){
Serial.begin(9600); //begins sampling the serial port for monitoring purposes
pinMode(13, OUTPUT); //clipping indicator
pinMode(12, OUTPUT); //wave period indicator
pinMode(11, OUTPUT); //freq too low
pinMode(10, OUTPUT); //freq spot on
pinMode(9, OUTPUT); //freq too high
//sets all three pitch indicator lights off
digitalWrite(11, LOW);
digitalWrite(10, LOW);
digitalWrite(9, LOW);
pinMode(7, INPUT);// different paths from dip switch indicating the notenum value (output)
pinMode(2, INPUT);
pinMode(3, INPUT);
pinMode(4, INPUT);
pinMode(5, INPUT);
pinMode(6, INPUT);
digitalWrite(7, HIGH);// making sure the input pins are set high, so when pressed they will be on low
digitalWrite(2, HIGH);
digitalWrite(3, HIGH);
digitalWrite(4, HIGH);
digitalWrite(5, HIGH);
digitalWrite(6, HIGH);
Servo1.attach(servoPin); //attaches servo on pin x to servo object
//ADC - Handle Analog to Digital Conversion of Guitar Signal
cli(); //disables 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
}
//Launch Continuous Interupt Service Routine (ISR) for Sampling Analog to Digital Conversion of Guitar Audio Input
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) //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]) //sum timer values
totalTimer = 0;
for (byte i=0;i totalTimer+=timer*;*
}
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
PORTB |= B00100000;//set pin 13 high- turn on clipping indicator led
clipping = 1;//currently clipping
}
time++;//increment timer at rate of 38.5kHz
}
//---------------------------------------------------------------------------------------------------
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;
}
}
//----------------------------------------------------------------------------------------------
//Start of Main Arduino Loop
void loop() // loop
{
//highstring = 0;
frequency = 38462/float(period); //calculate frequency timer rate/period
// added for debugging and visualizing data
Serial.print(frequency);
Serial.println(" hz");
Serial.println(" ");
Serial.println("string picked: ");
Serial.print(notenum);
notenum_val(); //call function to determine value of note/string we want to tune
freq_range_identify(); //set frequency threshold ranges for string previously selected
checkClipping(); //frequency determining and led indicator loop
set_indicator_lights(); //checks value of current frequency and lights correct indicator light. Then moves servo accordingly
//Serial.println(angle);
move_motor(); //move tuning servo motor
//delay(1000); //turn on to control debouncing
notenumPrior = notenum;
} //end of main loop
//-----------------------------------------------------------------------------------------------
//Determine String selected from rotary switch and voltage values on designated arduino pins
void notenum_val()
{
int val_1 = digitalRead(2); //read the value of rotary switch pins
int val_2 = digitalRead(3);
int val_3 = digitalRead(4);
int val_4 = digitalRead(5);
int val_5 = digitalRead(6);
int val_6 = digitalRead(7);
if (val_1 == LOW && val_2 == HIGH && val_3 == HIGH && val_4 == HIGH && val_5 == HIGH && val_6 == HIGH) //switch set on pressed, then notenum = 1
{
if (notenumPrior != 1)
{
delay(5000);
notenum = 1;
}
else
{
notenum = 1;
}
}
else if (val_1 == HIGH && val_2 == LOW && val_3 == HIGH && val_4 == HIGH && val_5 == HIGH && val_6 == HIGH) //Switch 3 pressed, noenum = 2
{
if (notenumPrior != 2 )
{
delay(5000);
notenum = 2;
}
else
{
notenum = 2;
}
}