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:
- 2:9c0a83c5ded5
- Parent:
- 1:4a82a5178506
- Child:
- 3:c672e782f19b
--- a/main.cpp Sun Apr 15 00:20:48 2012 +0000 +++ b/main.cpp Sun Apr 15 00:37:37 2012 +0000 @@ -1,320 +1,296 @@ -//#include "mbed.h" -//#include "Motor.h" -//#include "FrequencyFinder.h" -//#include "NewTextLCD.h" -//#include "PinDetect.h" -#include "strings.h" -#include <iostream> -#include <stdio.h> -#include <vector> - -using namespace std; -//*************************************************** -//***************Globals***************************** -//PinDetect string_but(p11); -//PinDetect pitch_but(p12); -//PinDetect start_but(p13); -//PinDetect mode_but(p14); - -//DigitalOut led1(LED1); -//DigitalOut led2(LED2); - -//TextLCD lcd(p21,p22,p23,p24,p25,p26); -//Motor motor(p26,p22,p21);//enable, direction, step -//FrequencyFinder guitar(p20);//input - -int selected_string; -//int selected_pitch; -bool current_mode; -bool start_tuning; -bool up, down; - -vector<strings> strings_array; - -//*************************************************** -//*****************constants************************* -const bool tuning_mode=false; -const bool winding_mode=true; - -//*************************************************** -//******************prototypes*********************** -void device_init(); - -void string_sel(); -void pitch_sel(); -void start(); -void stop(); -void mode(); -void do_nothing(); -void wind_up(); -void wind_down(); - -void button_init(); -void setup_buttons(); -void output_menu(); -void motor_calibration(); -bool check_threshold(float); -//************************************************* -//*********************main************************ -int main() { - // lcd.cls(); - // lcd.printf("Perfect\n Pitch"); - - // wait(.5); - - device_init(); - - int state=0,next_state=0; - float old_freq=0,new_freq=0; - float desired_freq; - strings *temp=&strings_array[0]; - while (1) { - - state=next_state; - - switch(state){ - //------------------------------------ - case 0://Stay here till the user selects the string and pitch - if(start_tuning==true){ - next_state=1; - } - else{ - next_state=0; - } - - break; - //---------------------------------------- - case 1://motor calibration state - motor_calibration(); - next_state=2; - break; - //----------------------------------------- - case 2://begin the actual tuning - temp=&strings_array[selected_string]; - desired_freq=temp->get_freq(); - - next_state=3; - break; - //----------------------------------------- - case 3: - //new_freq=frequency.find_frequency(); - if(check_threshold(new_freq)){ - if((desired_freq-.5)<new_freq && (desired_freq+.5)>new_freq){//We are within .5Hz of the desired frequency - //lcd.cls(); - //lcd. - printf("String %d\ntuned",selected_string); - //wait(.5); - - start_tuning=false; - next_state=0; - } - else if((desired_freq-.5)>new_freq){ - //motor(up,# of steps); - next_state=3; - } - else{ - //motor(down,# of steps); - next_state=3; - } - } - else{ - next_state=3; - } - - //TODO:Determine number of steps per frequency change - old_freq=new_freq; - break; - //----------------------------------------- - default: - break; - } - //wait_ms(5); - - if(start_tuning==false){//If the stop button is pressed, the state machine returns to user input - next_state=0; - } - } - - // return 0; -} - -//*************************************************** -//******************functions************************ -void output_menu() { - // lcd.cls(); - strings temp=strings_array[selected_string]; - /*lcd.*/printf("Select String: %d\nSelect Pitch: %s",selected_string,temp.get_note().c_str()); - fflush(stdout); - } - -//*************************************************** -void button_init(){ - // string_but.mode( PullDown ); - // string_but.setSampleFrequency(); - - // pitch_but.mode( PullDown ); - // pitch_but.setSampleFrequency(); - - // start_but.mode( PullDown ); - // start_but.setSampleFrequency(); - - // mode_but.mode( PullDown ); - // mode_but.setSampleFrequency(); -} - -//*************************************************** -void setup_buttons() { - if(current_mode==tuning_mode){ - // string_but.attach_asserted(&string_sel); - // pitch_but.attach_asserted(&pitch_sel); - // start_but.attach_asserted(&start); - // mode_but.attach_asserted(&mode); - } - else{ - // string_but.attach_asserted(&wind_up); - // pitch_but.attach_asserted(&wind_down); - // start_but.attach_asserted(&do_nothing); - // mode_but.attach_asserted(&mode); - } -} -//*************************************************** -void string_sel() { - selected_string++; - if (selected_string>6) - selected_string=1; - - output_menu(); -} -//*************************************************** -void pitch_sel() { - strings *temp=&strings_array[selected_string]; - temp->inc_index(); - - output_menu(); -} -//*************************************************** -void start() { - start_tuning=true; -} -//*************************************************** -void mode() { - if(current_mode==tuning_mode){ - current_mode=winding_mode; - //lcd.cls(); - /*lcd.*/printf("Winding Mode"); - //wait(1); - } - else{ - current_mode=tuning_mode; - //lcd.cls(); - /*lcd.*/printf("Tuning Mode"); - //wait(1); - } - setup_buttons(); -} -//*************************************************** -void stop() { - start_tuning=false; -} -//*************************************************** -void do_nothing(){ - return; -} -//*************************************************** -void wind_up(){ - //motor.motor_turn(1,10); -} -//*************************************************** -void wind_down(){ - //motor.motor_turn(0,10); -} -//*************************************************** -void device_init(){ - strings string1(1); - strings string2(2); - strings string3(3); - strings string4(4); - strings string5(5); - strings string6(6); - strings_array.push_back(string1); - strings_array.push_back(string2); - strings_array.push_back(string3); - strings_array.push_back(string4); - strings_array.push_back(string5); - strings_array.push_back(string6); - - selected_string=1; - current_mode=tuning_mode; - start_tuning=false; - up=true; - down=false; - - button_init(); - - output_menu(); -} -//*************************************************** -void motor_calibration(){ - //lcd.cls(); - //lcd. - printf("Calibrate Motor"); - - float freq=0, freq_up, freq_down; - // bool calibration_done=false; - bool done=false; - //lcd.cls(); - /*lcd.*/ - printf("Please pluck\nstring"); - - //motor.motor_turn(up,25)//TODO: Adjust the number of steps here - //On second thought, we don't need to tune up and down for this, we can find the current frequency - //and then turn the peg for two frequencies! - while(!done){ - //freq=frequency.find_frequency(); - - if(freq>500){ - printf("Please pluck\nstring again"); - //wait(.5); - //lcd.cls(); - } - else{ - freq_up=freq; - done=true; - } - } - //motor.motor_turn(down,25)//TODO: Adjust the number of steps here - done=false; - while(!done){ - //freq=frequency.find_frequency(); - - if(freq>500){ - printf("Please pluck\nstring again"); - //wait(.5); - //lcd.cls(); - } - else{ - freq_down=freq; - done=true; - } - } - - if(freq_up<freq_down){ - down=true; - up=false; - } - - //lcd.cls(); - //lcd. - printf("Calibration Done"); -} -//********************************************** -bool check_threshold(float freq){ - if(freq>500){ - //lcd.cls(); - //lcd. - printf("Pluck string \nagain"); - return false; - } - else - return true; -} +#include "mbed.h" +#include "Motor.h" +#include "FrequencyFinder.h" +#include "NewTextLCD.h" +#include "PinDetect.h" +#include "strings.h" +#include <iostream> +#include <stdio.h> +#include <vector> + +using namespace std; +//*************************************************** +//***************Globals***************************** +PinDetect string_but(p11); +PinDetect pitch_but(p12); +PinDetect start_but(p13); +PinDetect mode_but(p14); + +DigitalOut led1(LED1); +DigitalOut led2(LED2); + +TextLCD lcd(p23,p24,p25,p26,p27,p28); +Motor motor(p20,p21,p22);//enable, direction, step +FrequencyFinder guitar(p19);//input + +int selected_string; +bool current_mode; +bool start_tuning; +bool up, down; + +vector<strings> strings_array; + +//*************************************************** +//*****************constants************************* +const bool tuning_mode=false; +const bool winding_mode=true; + +//*************************************************** +//******************prototypes*********************** +void device_init(); + +void string_sel(); +void pitch_sel(); +void start(); +void stop(); +void mode(); +void do_nothing(); +void wind_up(); +void wind_down(); + +void button_init(); +void setup_buttons(); +void output_menu(); +void motor_calibration(); +bool check_threshold(float); +//************************************************* +//*********************main************************ +int main() { + lcd.cls(); + lcd.printf("Perfect\n Pitch"); + + wait(.5); + + device_init(); + + int state=0,next_state=0; + //float old_freq=0; + float new_freq=0; + float desired_freq=0; + strings *temp=&strings_array[0]; + while (1) { + + state=next_state; + + switch (state) { + //------------------------------------ + case 0://Stay here till the user selects the string and pitch + if (start_tuning==true) { + next_state=1; + } else { + next_state=0; + } + + break; + //---------------------------------------- + case 1://motor calibration state + motor_calibration(); + next_state=2; + break; + //----------------------------------------- + case 2://begin the actual tuning + temp=&strings_array[selected_string]; + desired_freq=temp->get_freq(); + + next_state=3; + break; + //----------------------------------------- + case 3: + new_freq=guitar.find_frequency(); + if (check_threshold(new_freq)) { + if ((desired_freq-.5)<new_freq && (desired_freq+.5)>new_freq) {//We are within .5Hz of the desired frequency + lcd.cls(); + lcd.printf("String %d\ntuned",selected_string); + wait(.5); + + start_tuning=false; + next_state=0; + } else if ((desired_freq-.5)>new_freq) { + //motor(up,# of steps); + next_state=3; + } else { + //motor(down,# of steps); + next_state=3; + } + } else { + next_state=3; + } + + //TODO:Determine number of steps per frequency change + //old_freq=new_freq; + break; + //----------------------------------------- + default: + break; + } + wait_ms(5); + + if (start_tuning==false) {//If the stop button is pressed, the state machine returns to user input + next_state=0; + } + } + + // return 0; +} + +//*************************************************** +//******************functions************************ +void output_menu() { + lcd.cls(); + strings temp=strings_array[selected_string]; + lcd.printf("Select String: %d\nSelect Pitch: %s",selected_string,temp.get_note().c_str()); +} + +//*************************************************** +void button_init() { + string_but.mode( PullDown ); + string_but.setSampleFrequency(); + + pitch_but.mode( PullDown ); + pitch_but.setSampleFrequency(); + + start_but.mode( PullDown ); + start_but.setSampleFrequency(); + + mode_but.mode( PullDown ); + mode_but.setSampleFrequency(); +} + +//*************************************************** +void setup_buttons() { + if (current_mode==tuning_mode) { + string_but.attach_asserted(&string_sel); + pitch_but.attach_asserted(&pitch_sel); + start_but.attach_asserted(&start); + mode_but.attach_asserted(&mode); + } else { + string_but.attach_asserted(&wind_up); + pitch_but.attach_asserted(&wind_down); + start_but.attach_asserted(&do_nothing); + mode_but.attach_asserted(&mode); + } +} +//*************************************************** +void string_sel() { + selected_string++; + if (selected_string>6) + selected_string=1; + + output_menu(); +} +//*************************************************** +void pitch_sel() { + strings *temp=&strings_array[selected_string]; + temp->inc_index(); + + output_menu(); +} +//*************************************************** +void start() { + start_tuning=true; +} +//*************************************************** +void mode() { + if (current_mode==tuning_mode) { + current_mode=winding_mode; + lcd.cls(); + lcd.printf("Winding Mode"); + wait(1); + } else { + current_mode=tuning_mode; + lcd.cls(); + lcd.printf("Tuning Mode"); + wait(1); + } + setup_buttons(); +} +//*************************************************** +void stop() { + start_tuning=false; +} +//*************************************************** +void do_nothing() { + return; +} +//*************************************************** +void wind_up() { + motor.motor_turn(1,10); +} +//*************************************************** +void wind_down() { + motor.motor_turn(0,10); +} +//*************************************************** +void device_init() { + strings string1(1); + strings string2(2); + strings string3(3); + strings string4(4); + strings string5(5); + strings string6(6); + strings_array.push_back(string1); + strings_array.push_back(string2); + strings_array.push_back(string3); + strings_array.push_back(string4); + strings_array.push_back(string5); + strings_array.push_back(string6); + + selected_string=1; + current_mode=tuning_mode; + start_tuning=false; + up=true; + down=false; + + button_init(); + + output_menu(); +} +//*************************************************** +void motor_calibration() { + lcd.cls(); + lcd.printf("Calibrate Motor"); + + float freq=0, freq_up=0, freq_down=0; + bool done=false; + lcd.cls(); + lcd.printf("Please pluck\nstring"); + + //motor.motor_turn(up,25)//TODO: Adjust the number of steps here + //On second thought, we don't need to tune up and down for this, we can find the current frequency + //and then turn the peg for the two frequencies! + while (!done) { + freq=guitar.find_frequency(); + + if (check_threshold(freq)) { + freq_up=freq; + done=true; + } + } + motor.motor_turn(down,25);//TODO: Adjust the number of steps here + done=false; + while (!done) { + freq=guitar.find_frequency(); + + if (check_threshold(freq)) { + freq_down=freq; + done=true; + } + } + + if (freq_up<freq_down) { + down=true; + up=false; + } + + lcd.cls(); + lcd.printf("Calibration Done"); +} +//********************************************** +bool check_threshold(float freq) { + if (freq>500) { + lcd.cls(); + lcd.printf("Pluck string \nagain"); + return false; + } else + return true; +}