A program to automatically tune a guitar. Written by Justin Reidhead and Steven Swenson

Dependencies:   FFT FrequencyFinder Motor NewTextLCD PinDetect mbed strings

main.cpp

Committer:
melangeaddict
Date:
2012-04-15
Revision:
1:4a82a5178506
Parent:
0:d8909ac31fbf
Child:
2:9c0a83c5ded5

File content as of revision 1:4a82a5178506:

//#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;
}