A program to automatically tune a guitar. Written by Justin Reidhead and Steven Swenson
Dependencies: FFT FrequencyFinder Motor NewTextLCD PinDetect mbed strings
Diff: main.cpp
- Revision:
- 12:03c189de6e2e
- Parent:
- 11:bdad1acccdad
- Child:
- 13:948c7d19acb9
diff -r bdad1acccdad -r 03c189de6e2e main.cpp --- a/main.cpp Wed Apr 25 00:42:46 2012 +0000 +++ b/main.cpp Wed Apr 25 04:09:25 2012 +0000 @@ -66,6 +66,7 @@ bool check_threshold(float);//check to make sure the frequency is valid (frequency to check) void LED_initialize();//Initialization sequence for LEDs, called at start-up void set_LED(int led, int value);//sets or clears an LED: Blue=1(in tune), Red=2(flat), Green=3(sharp). Value=1(off), 0(on); +int get_steps(float desired, float current); //************************************************* //*********************main************************ int main() { @@ -79,9 +80,9 @@ int state=0,next_state=0; - //int num_steps=0; + int num_steps=0; //float old_freq=0; - //int found_frequency=0; + short current_direction=up; float new_freq=0; float desired_freq=0; strings *temp=&strings_array[0]; @@ -109,6 +110,7 @@ break; //----------------------------------------- case 2://begin the actual tuning + temp=&strings_array[selected_string]; desired_freq=temp->get_freq();//Get the desired frequency for the string selected //old_freq=desired_freq;//We have to initalize it to something... @@ -119,34 +121,40 @@ case 3://Do the dirty work of tuning new_freq=guitar.find_frequency();//Get the current frequency of the string - //if (new_freq>(desired_freq+50) || new_freq<(desired_freq-50)) {//If the new frequency is wildly out of whack - //new_freq=guitar.find_frequency();//Get the current frequency of the string, again - // break; - //} - //num_steps=-5*abs(new_freq-old_freq); - // old_freq=new_freq; + if (desired_freq*2.2>new_freq && desired_freq*1.8<new_freq) { + new_freq=new_freq/2; + } if (check_threshold(new_freq)) {//The check_threshold function makes sure the frequency is valid (less than 500 Hz) + + num_steps=get_steps(desired_freq, new_freq); + if ((desired_freq-.5)<new_freq && (desired_freq+.5)>new_freq) {//We are within .5Hz of the desired frequency - //if (found_frequency==0) { - // found_frequency++; - // next_state=3; - // break; - //} + new_freq=guitar.find_frequency(); + if ((desired_freq-.5)>new_freq || (desired_freq+.5)<new_freq) {//This checks the frequency again to make sure we are close + next_state=3; + break; + } + lcd.cls(); lcd.printf("String %d\ntuned",selected_string+1); set_LED(1,0);//blue on set_LED(2,1);//red off; set_LED(3,1);//green off - wait(.5); + wait(1); start_tuning=false; output_menu(); setup_buttons(); next_state=0; } else if ((desired_freq-.5)>new_freq) {//We are too low, and need to turn the string tigher + if (current_direction==down) { + num_steps+=18;//For deadband + current_direction=up; + } + lcd.cls(); lcd.printf("Tuning up"); @@ -156,12 +164,17 @@ //found_frequency=0; - wait(.5); + //wait(.5); - motor.motor_turn(up,10);//TODO:Adjust # of steps + motor.motor_turn(up,num_steps);//TODO:Adjust # of steps next_state=3; } else {//We are too high, and need to loosen the string + if (current_direction==up) { + num_steps+=18;//For deadband + current_direction=down; + } + lcd.cls(); lcd.printf("Tuning down"); set_LED(1,1);//blue off @@ -170,9 +183,9 @@ //found_frequency=0; - wait(.5); + //wait(.5); - motor.motor_turn(down,10); + motor.motor_turn(down,num_steps); next_state=3; } } else { @@ -224,19 +237,19 @@ } if (start_tuning) { - lcd.cls(); - - lcd.locate(9,0); - lcd.printf("%f",new_freq); - lcd.locate(9,1); - lcd.printf("%f",desired_freq); + if (check_threshold(new_freq)) { + lcd.cls(); + lcd.locate(9,0); + lcd.printf("%f",new_freq); + lcd.locate(9,1); + lcd.printf("%f",desired_freq); - lcd.locate(0,1); - lcd.printf("Desired"); - lcd.locate(0,0); - lcd.printf("Detected"); + lcd.locate(0,1); + lcd.printf("Desired"); + lcd.locate(0,0); + lcd.printf("Detected"); + } } - }//end while // return 0; @@ -254,7 +267,7 @@ lcd.printf("Select Pitch: "); lcd.printf("%s",temp->get_note()); //wait(.5); - + set_LED(1,0);//Turn blue LED on set_LED(2,1); set_LED(3,1); @@ -466,19 +479,49 @@ bool check_threshold(float freq) { strings *temp=&strings_array[selected_string]; float desired_freq=temp->get_freq();//Get the desired frequency for the string selected - - if (freq>(desired_freq+75) || freq<(desired_freq-75) || freq>500) {//new_freq>(desired_freq+50) || new_freq<(desired_freq-50) + + int hertz=0; + switch (selected_string) { + case 0: + hertz=85; + break; + + case 1: + hertz=66; + break; + + case 2: + hertz=53; + break; + + case 3: + hertz=42; + break; + + case 4: + hertz=29; + break; + + case 5: + hertz=22; + break; + + default: + break; + } + + if (freq>(desired_freq+hertz) || freq<(desired_freq-hertz) || freq>500) {//new_freq>(desired_freq+50) || new_freq<(desired_freq-50) lcd.cls(); lcd.printf("Pluck string %d\nagain",selected_string+1); - + set_LED(1,1); set_LED(2,1); set_LED(3,1);//Turn led off - + set_LED(2,0); set_LED(3,0);//Make the LED turn yellow - - wait(.5); + + //wait(.5); return false; } else return true; @@ -566,4 +609,78 @@ return; +} +//*********************************** +//********get_steps***************** +int get_steps(float desired, float current) { + + float difference=abs(desired-current); + + switch (selected_string) { + case 5: + if (difference>10) { + return 60; + } else if (difference>3) { + return 35; + } else if (difference>1) { + return 15; + } else { + return 10; + } + case 4: + if (difference>10) { + return 60; + } else if (difference>3) { + return 40; + } else if (difference>1) { + return 23; + } else { + return 10; + } + case 3: + if (difference>10) { + return 40; + } else if (difference>3) { + return 25; + } else if (difference>1) { + return 15; + } else { + return 10; + } + case 2: + if (difference>10) { + return 33; + } else if (difference>3) { + return 20; + } else if (difference>1) { + return 15; + } else { + return 10; + } + case 1: + if (difference>10) { + return 30; + } else if (difference>3) { + return 20; + } else if (difference>1) { + return 10; + } else { + return 7; + } + case 0: + if (difference>10) { + return 20; + } else if (difference>3) { + return 15; + } else if (difference>1) { + return 8; + } else { + return 4; + } + + + default: + return 0; + break; + }//end switch } \ No newline at end of file